Merge branch 'main' into feat/app_pin

This commit is contained in:
gdlbo
2023-03-02 11:59:41 +03:00
committed by GitHub
92 changed files with 1627 additions and 1376 deletions
+2
View File
@@ -37,6 +37,8 @@ jobs:
sudo apt install zipalign
chmod +x scripts/apktool.jar
chmod +x scripts/apksigner.jar
rustup target add armv7-linux-androideabi
rustup target add aarch64-linux-android
- name: Build VTLite
run: |
+2
View File
@@ -31,3 +31,5 @@ smali/assets/version.properties
*.keystore
gradle.properties
scripts/build.sh
smali/lib/arm64-v8a/libnative_effects.so
smali/lib/armeabi-v7a/libnative_effects.so
+6 -2
View File
@@ -117,9 +117,13 @@
* Все необходимые скрипты/.jar файлы для компиляции APK, его подписывании и не только находятся в `/scripts`
### Необходимые зависимости
<a href="https://www.oracle.com/java/technologies/downloads/"><img src="https://i.imgur.com/z8ZN19a.png" align="center" width="20" height="23"/> **JDK**</a> >11 версии
<img src="https://i.imgur.com/z8ZN19a.png" align="center" width="20" height="23"/> [**JDK**](https://adoptium.net/temurin/releases/) >14 версии
<img src="https://www.rust-lang.org/logos/rust-logo-32x32.png" align="center" width="20" height="20"/> [**Rust**](https://www.rust-lang.org/learn/get-started) с Android ARM тулчейнами: `rustup target add aarch64-linux-android armv7-linux-androideabi`
<img src="https://developer.android.com/static/images/logos/android.svg" align="center" width="20" height="20"/> Android SDK и NDK (устанавливаются через
[sdkmanager](https://developer.android.com/studio/command-line/sdkmanager) или [Android Studio](https://developer.android.com/studio))
<a href="https://developer.android.com/studio"><img src="https://i.imgur.com/cPvvFDP.png" align="center" width="20" height="23"/> **Android Studio**</a>
### Linux/macOS/Windows
+23 -1
View File
@@ -7,6 +7,16 @@ import java.util.zip.ZipInputStream
plugins {
id 'com.android.application'
id 'net.nemerosa.versioning' version '2.15.1'
id 'org.mozilla.rust-android-gradle.rust-android'
}
cargo {
profile = 'release'
module = '../native-effects'
libname = 'native-effects'
targets = ["arm", "arm64"]
prebuiltToolchains = true
pythonCommand = "python3"
}
def smaliFolder = projectDir.toPath().resolve("../smali").normalize()
@@ -100,6 +110,7 @@ android {
targetCompatibility JavaVersion.VERSION_14
}
namespace 'ru.vtosters.lite'
ndkVersion '25.2.9519653'
}
dependencies {
@@ -112,6 +123,8 @@ dependencies {
task prepareDexForMerge(type: Copy) {
dependsOn('exportDex')
// Remove comment for native lib build
dependsOn('cargoBuild')
into smaliFolder.toString()
from(projectDir) {
include 'classes6.dex'
@@ -119,7 +132,16 @@ task prepareDexForMerge(type: Copy) {
}
from(projectDir) {
include 'version.properties'
into("assets")
into 'assets'
}
// Remove comment for native lib build
from('../native-effects/target/aarch64-linux-android/release'){
include 'libnative_effects.so'
into 'lib/arm64-v8a'
}
from('../native-effects/target/armv7-linux-androideabi/release'){
include 'libnative_effects.so'
into 'lib/armeabi-v7a'
}
doLast {
new File(projectDir, "classes6.dex").delete()
@@ -1,7 +1,6 @@
package com.vk.sharing.view;
import static b.h.z.f.roboto_medium;
import static ru.vtosters.lite.utils.Preferences.preferences;
import static ru.vtosters.lite.utils.ThemesUtils.getAccentColor;
import android.content.Context;
@@ -32,6 +31,7 @@ import com.vk.imageloader.view.VKMultiImageView;
import com.vk.navigation.NavigatorKeys;
import com.vtosters.lite.R;
import com.vtosters.lite.a0;
import ru.vtosters.lite.utils.Preferences;
import java.util.Arrays;
@@ -208,7 +208,7 @@ public class TargetImageView extends VKMultiImageView {
@Override // android.view.View
protected void onDraw(Canvas canvas) {
Canvas canvas2 = this.f21631f;
int pref = preferences.getInt("pic_rounding", 0);
int pref = Preferences.getPreferences().getInt("pic_rounding", 0);
if (canvas2 != null) {
canvas2.drawColor(0, PorterDuff.Mode.CLEAR);
@@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
public abstract class IMProcessor {
// By default it checks start and end tag.
@@ -67,20 +68,20 @@ public abstract class IMProcessor {
}
public void enableEncryptFor(int id) {
AndroidUtils.getDefaultPrefs().edit().putBoolean("VT_IMEncode_" + getPrefKey() + "_" + id, true).apply();
Preferences.getPreferences().edit().putBoolean("VT_IMEncode_" + getPrefKey() + "_" + id, true).apply();
}
public void disableEncryptFor(int id) {
AndroidUtils.getDefaultPrefs().edit().putBoolean("VT_IMEncode_" + getPrefKey() + "_" + id, false).apply();
Preferences.getPreferences().edit().putBoolean("VT_IMEncode_" + getPrefKey() + "_" + id, false).apply();
}
public void setEncryptionKeyFor(int id, @Nullable String key) {
if (key == null || key.isEmpty()) key = "VTAesDefault";
AndroidUtils.getDefaultPrefs().edit().putString("VT_IMEncodeKey_" + getPrefKey() + "_" + id, key).apply();
Preferences.getPreferences().edit().putString("VT_IMEncodeKey_" + getPrefKey() + "_" + id, key).apply();
}
@Nullable
public String getEncryptionKeyFor(int id) {
return AndroidUtils.getDefaultPrefs().getString("VT_IMEncodeKey_" + getPrefKey() + "_" + id, null);
return Preferences.getPreferences().getString("VT_IMEncodeKey_" + getPrefKey() + "_" + id, null);
}
}
@@ -18,6 +18,7 @@ import javax.crypto.spec.SecretKeySpec;
import ru.vtosters.lite.encryption.base.IMProcessor;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
public class VTostersAESProcessor extends IMProcessor {
private final static String CIPHER_INSTANCE = "AES/CBC/PKCS7Padding";
@@ -114,7 +115,7 @@ public class VTostersAESProcessor extends IMProcessor {
@Nullable
@Override
public String getEncryptionKeyFor(int id) {
return AndroidUtils.getDefaultPrefs().getString("VT_IMEncodeKey_" + getPrefKey() + "_" + id, "VTAesDefault");
return Preferences.getPreferences().getString("VT_IMEncodeKey_" + getPrefKey() + "_" + id, "VTAesDefault");
}
public static class Triple<F, S, T> {
@@ -22,6 +22,7 @@ import java.util.Collections;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.NewsFeedFiltersUtils;
import ru.vtosters.lite.utils.Preferences;
public class AdBlockHook {
public static Boolean discoverAdBlock(JSONObject jsonObject) {
@@ -351,7 +352,7 @@ public class AdBlockHook {
return true;
}
var whitelist = AndroidUtils.getDefaultPrefs().getStringSet(
var whitelist = Preferences.getPreferences().getStringSet(
"whitelisted_filters_groups",
Collections.emptySet()
);
@@ -366,7 +367,7 @@ public class AdBlockHook {
id = String.valueOf(list.optInt("source_id"));
}
var whitelist = AndroidUtils.getDefaultPrefs().getStringSet(
var whitelist = Preferences.getPreferences().getStringSet(
"whitelisted_ad_groups",
Collections.emptySet()
);
@@ -377,7 +378,7 @@ public class AdBlockHook {
public static Boolean isWhitelistedAdStories(JSONObject list) {
var id = String.valueOf(list.optInt("owner_id"));
var whitelist = AndroidUtils.getDefaultPrefs().getStringSet(
var whitelist = Preferences.getPreferences().getStringSet(
"whitelisted_stories_ad",
Collections.emptySet()
);
@@ -1,6 +1,6 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.Preferences.getString;
import static ru.vtosters.lite.utils.AndroidUtils.getStringDate;
import android.annotation.SuppressLint;
@@ -15,11 +15,11 @@ import ru.vtosters.lite.utils.AndroidUtils;
public class DateHook {
public static boolean fulltime() {
return getPrefsValue("dateformat").equals("noyear") || getPrefsValue("dateformat").equals("full") || getPrefsValue("dateformat").equals("noseconds");
return getString("dateformat").equals("noyear") || getString("dateformat").equals("full") || getString("dateformat").equals("noseconds");
}
public static String getDateFormat() {
return switch (getPrefsValue("dateformat")) {
return switch (getString("dateformat")) {
case "noyear" -> AndroidUtils.getString(R.string.fulltime2);
case "full" -> AndroidUtils.getString(R.string.fulltime);
default -> AndroidUtils.getString(R.string.fulltime3);
@@ -45,7 +45,7 @@ public class DateHook {
}
public static String getLocale() {
String string = getPrefsValue("lang_value");
String string = getString("lang_value");
if (string.equals("system")) {
return Locale.getDefault().getLanguage();
@@ -108,10 +108,8 @@ public class DockBarInjector {
private static void removeAllChildren(ViewGroup view) {
for (int i = 0; i < view.getChildCount(); i++) {
if (view instanceof ViewGroup) {
removeAllChildren((ViewGroup) view.getChildAt(i));
view.removeAllViews();
}
removeAllChildren((ViewGroup) view.getChildAt(i));
view.removeAllViews();
}
}
@@ -247,8 +245,8 @@ public class DockBarInjector {
}
try {
JSONArray jSONArray = new JSONArray();
for (int i = 0; i < arrayList.size(); i++) {
jSONArray.put(new JSONObject().put("name", arrayList.get(i)));
for (String s : arrayList) {
jSONArray.put(new JSONObject().put("name", s));
}
for (int i2 = 0; i2 < arr.length(); i2++) {
jSONArray.put(arr.getJSONObject(i2));
@@ -1,7 +1,7 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.ui.components.FragAnimationKit.setAnimations;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.Preferences.getString;
import androidx.fragment.app.FragmentTransaction;
@@ -9,7 +9,7 @@ public class FragAnimationHook {
public static boolean animateOpen(FragmentTransaction transaction) {
setAnimations(transaction);
return getPrefsValue("anim_rtrn_type").equals("noanim") || getPrefsValue("anim_rtrn_type").isEmpty();
return getString("anim_rtrn_type").equals("noanim") || getString("anim_rtrn_type").isEmpty();
}
public static void animateClose(FragmentTransaction transaction) {
@@ -1,37 +1,22 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.foaf.FoafBase.getBypassedOnlineInfo;
import static ru.vtosters.lite.hooks.OnlineFormatterHook.onlineHookProfiles;
import static ru.vtosters.lite.proxy.ProxyUtils.getStatic;
import static ru.vtosters.lite.utils.AndroidUtils.getDefaultPrefs;
import static ru.vtosters.lite.utils.Preferences.dev;
import static ru.vtosters.lite.utils.Preferences.friendsblock;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Preferences.hasVerification;
import static ru.vtosters.lite.utils.VTVerifications.isDeveloper;
import static ru.vtosters.lite.utils.VTVerifications.isPrometheus;
import static ru.vtosters.lite.utils.VTVerifications.isVerified;
import android.text.TextUtils;
import android.util.Log;
import com.vk.core.util.LangUtils;
import com.vtosters.lite.R;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
import java.io.IOException;
import java.text.ParseException;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Random;
import okhttp3.OkHttpClient;
import ru.vtosters.lite.di.singleton.VtOkHttpClient;
import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils;
import static ru.vtosters.lite.foaf.FoafBase.getBypassedOnlineInfo;
import static ru.vtosters.lite.hooks.OnlineFormatterHook.onlineHookProfiles;
import static ru.vtosters.lite.utils.Preferences.dev;
import static ru.vtosters.lite.utils.Preferences.friendsblock;
public class JsonInjectors {
public static JSONObject menu(JSONObject orig) throws JSONException {
@@ -47,7 +32,7 @@ public class JsonInjectors {
}
public static JSONObject superapp(JSONObject json) throws JSONException {
var superApps = AndroidUtils.getPreferences().getString("superapp_items",
var superApps = Preferences.getPreferences().getString("superapp_items",
"menu,miniapps,vkpay_slim,greeting,promo,holiday,weather,sport,games,informer,food,event,music,vk_run").split(",");
if (superApps.length == 0) return json;
@@ -154,8 +139,8 @@ public class JsonInjectors {
}
public static JSONArray newsfeedlist(JSONArray items) throws JSONException {
var selectedItems = getDefaultPrefs().getString("news_feed_selected_items", "");
var filtersSet = getDefaultPrefs().getStringSet("news_feed_items_set", null);
var selectedItems = Preferences.getPreferences().getString("news_feed_selected_items", "");
var filtersSet = Preferences.getPreferences().getStringSet("news_feed_items_set", null);
var mutableFiltersSet = new LinkedHashSet<String>();
if (filtersSet != null)
mutableFiltersSet.addAll(filtersSet);
@@ -182,7 +167,7 @@ public class JsonInjectors {
.put("is_unavailable", hide);
if (dev()) Log.d("NewsfeedListInj", "Unlocked " + id + " in newsfeed list");
}
getDefaultPrefs().edit().putStringSet("news_feed_items_set", mutableFiltersSet)
Preferences.getPreferences().edit().putStringSet("news_feed_items_set", mutableFiltersSet)
.apply();
return items;
@@ -9,29 +9,28 @@ import static ru.vtosters.lite.utils.ThemesUtils.setNeededTheme;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import com.guardanis.applock.AppLock;
import com.guardanis.applock.activities.UnlockActivity;
import b.h.g.k.VKProgressDialog;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vtosters.lite.R;
import ru.vtosters.lite.concurrent.VTExecutors;
import ru.vtosters.lite.downloaders.notifications.NotificationChannels;
import ru.vtosters.lite.ssfs.UsersList;
import ru.vtosters.lite.themes.ThemesManager;
import ru.vtosters.lite.ui.dialogs.DisableBattery;
import ru.vtosters.lite.ui.dialogs.InstallGMS;
import ru.vtosters.lite.ui.dialogs.OTADialog;
import ru.vtosters.lite.ui.dialogs.Start;
import ru.vtosters.lite.utils.DeletedMessagesHandler;
import ru.vtosters.lite.utils.*;
public class MainActivityInjector {
public static void inject(Activity activity) {
setNeededTheme(activity);
sendRequest();
UsersList.getUsersList();
if (checkupdates()) OTADialog.checkUpdates(activity);
VTExecutors.getIoScheduler().a(DeletedMessagesHandler::reloadMessagesList); // ioScheduler
Start.alert(activity);
InstallGMS.alert(activity);
DisableBattery.alert(activity);
VTExecutors.getSlowTasksScheduler().a(() -> {
getInstance().autoCleaningCache();
@@ -47,6 +46,45 @@ public class MainActivityInjector {
activity.startActivity(intent);
}
if(Preferences.isNewBuild() && !ThemesUtils.isMonetTheme() && ThemesManager.canApplyCustomAccent()) {
Preferences.updateBuildNumber();
updateBinsAndTmpArchive(activity);
}
VTExecutors.getIoScheduler().a(DeletedMessagesHandler::reloadMessagesList); // ioScheduler
if(activity.getIntent().getAction() != null && Intent.ACTION_APPLICATION_PREFERENCES.equals(activity.getIntent().getAction())) {
NavigatorUtils.switchToSettings(activity);
return;
}
Start.alert(activity);
InstallGMS.alert(activity);
DisableBattery.alert(activity);
// VKIDProtection.alert(activity);
}
private static void updateBinsAndTmpArchive(Activity activity) {
final VKProgressDialog dialog = new VKProgressDialog(activity);
dialog.setMessage("Применение акцента");
dialog.show();
VTExecutors.getIoExecutor().execute(() -> {
try {
ThemesManager.generateModApk(ThemesUtils.getReservedAccent());
activity.runOnUiThread(LifecycleUtils::restartApplication);
} catch(Throwable e) {
e.printStackTrace();
activity.runOnUiThread(() -> {
dialog.cancel();
new VkAlertDialog.Builder(activity)
.setTitle("Ошикба")
.setMessage("Ошибка при применении акцента:\n" + e)
.setPositiveButton(R.string.ok, null)
.show();
});
}
});
}
}
@@ -1,9 +1,8 @@
package ru.vtosters.lite.hooks;
import static java.lang.Long.MAX_VALUE;
import static ru.vtosters.lite.utils.AndroidUtils.getDefaultPrefs;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.Preferences.getString;
import static ru.vtosters.lite.utils.Preferences.ads;
import static ru.vtosters.lite.utils.Preferences.authorsrecomm;
import static ru.vtosters.lite.utils.Preferences.friendsrecomm;
@@ -23,13 +22,14 @@ import java.util.LinkedHashSet;
import java.util.List;
import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.Preferences;
public class NewsfeedHook {
public static long getUpdateNewsfeed(boolean refresh_timeout) {
if (vkme()) {
return MAX_VALUE;
}
return switch (getPrefsValue("newsupdate")) {
return switch (getString("newsupdate")) {
case "no_update" -> MAX_VALUE;
case "imd_update" -> 10000L;
default ->
@@ -67,20 +67,20 @@ public class NewsfeedHook {
}
public static boolean isWhitelistedFilter(ExtendedCommunityProfile eup) {
return getDefaultPrefs().getStringSet(
return Preferences.getPreferences().getStringSet(
"whitelisted_filters_groups", Collections.emptySet()
).contains(String.valueOf(AccountManagerUtils.getUserID(eup)));
}
public static boolean isWhitelistedAd(ExtendedCommunityProfile eup) {
return getDefaultPrefs().getStringSet(
return Preferences.getPreferences().getStringSet(
"whitelisted_ad_groups",
Collections.emptySet()
).contains(String.valueOf(AccountManagerUtils.getUserID(eup)));
}
public static boolean isWhitelistedAdStories(ExtendedCommunityProfile eup) {
return getDefaultPrefs().getStringSet(
return Preferences.getPreferences().getStringSet(
"whitelisted_stories_ad",
Collections.emptySet()
).contains(String.valueOf(AccountManagerUtils.getUserID(eup)));
@@ -89,7 +89,7 @@ public class NewsfeedHook {
public static void setWhitelistedFilter(ExtendedCommunityProfile eup, boolean needWhitelist) {
var id = String.valueOf(AccountManagerUtils.getUserID(eup));
var mutableAdsSet = new LinkedHashSet<>(getDefaultPrefs().getStringSet(
var mutableAdsSet = new LinkedHashSet<>(Preferences.getPreferences().getStringSet(
"whitelisted_filters_groups",
Collections.emptySet())
);
@@ -99,13 +99,13 @@ public class NewsfeedHook {
mutableAdsSet.remove(id);
}
getDefaultPrefs().edit().putStringSet("whitelisted_filters_groups", mutableAdsSet).apply();
Preferences.getPreferences().edit().putStringSet("whitelisted_filters_groups", mutableAdsSet).apply();
}
public static void setWhitelistedAd(ExtendedCommunityProfile eup, boolean needWhitelist) {
var id = String.valueOf(AccountManagerUtils.getUserID(eup));
var mutableAdsSet = new LinkedHashSet<>(getDefaultPrefs().getStringSet(
var mutableAdsSet = new LinkedHashSet<>(Preferences.getPreferences().getStringSet(
"whitelisted_ad_groups",
Collections.emptySet()));
@@ -115,13 +115,13 @@ public class NewsfeedHook {
mutableAdsSet.remove(id);
}
getDefaultPrefs().edit().putStringSet("whitelisted_ad_groups", mutableAdsSet).apply();
Preferences.getPreferences().edit().putStringSet("whitelisted_ad_groups", mutableAdsSet).apply();
}
public static void setWhitelistedAdStories(ExtendedCommunityProfile eup, boolean needWhitelist) {
var id = String.valueOf(AccountManagerUtils.getUserID(eup));
var mutableAdsSet = new LinkedHashSet<>(getDefaultPrefs().getStringSet(
var mutableAdsSet = new LinkedHashSet<>(Preferences.getPreferences().getStringSet(
"whitelisted_stories_ad",
Collections.emptySet()));
@@ -131,7 +131,7 @@ public class NewsfeedHook {
mutableAdsSet.remove(id);
}
getDefaultPrefs().edit().putStringSet("whitelisted_stories_ad", mutableAdsSet).apply();
Preferences.getPreferences().edit().putStringSet("whitelisted_stories_ad", mutableAdsSet).apply();
}
public static void adsParams(HashSet<String> hashSet) {
@@ -1,6 +1,5 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
import android.annotation.SuppressLint;
import android.content.ClipData;
@@ -12,9 +11,7 @@ import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.vk.core.dialogs.actionspopup.ActionsPopup;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vk.core.ui.themes.VKThemeHelper;
@@ -25,23 +22,18 @@ import com.vk.dto.common.ImageSize;
import com.vtosters.lite.R;
import com.vtosters.lite.attachments.DocumentAttachment;
import com.vtosters.lite.attachments.PhotoAttachment;
import okhttp3.*;
import org.json.JSONException;
import org.json.JSONObject;
import ru.vtosters.lite.di.singleton.VtOkHttpClient;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.LifecycleUtils;
import ru.vtosters.lite.utils.Preferences;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import ru.vtosters.lite.di.singleton.VtOkHttpClient;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.LifecycleUtils;
public class PhotoViewer {
static OkHttpClient client = VtOkHttpClient.getInstance();
@@ -203,7 +195,7 @@ public class PhotoViewer {
}
private static int selectedEngine() {
return getPreferences().getInt("search_engine", 0);
return Preferences.getPreferences().getInt("search_engine", 0);
}
private static void searchPhoto(int i, String url) {
@@ -1,20 +1,12 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.Preferences.preferences;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.*;
import com.facebook.drawee.generic.RoundingParams;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
public class PicRoundingHook {
private static final int pref = preferences.getInt("pic_rounding", 0);
private static final int pref = Preferences.getPreferences().getInt("pic_rounding", 0);
public static RoundingParams inject() {
if (pref > 0) {
@@ -1,30 +1,23 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.proxy.ProxyUtils.isRandomProxyEnabled;
import static ru.vtosters.lite.proxy.ProxyUtils.isVikaProxyEnabled;
import static ru.vtosters.lite.proxy.ProxyUtils.isZaboronaEnabled;
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.LifecycleUtils.restartApplication;
import static ru.vtosters.lite.utils.ThemesUtils.getTextAttr;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.util.TypedValue;
import android.view.View;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import androidx.appcompat.view.ContextThemeWrapper;
import com.vk.auth.ui.VkAuthTextView;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vk.navigation.Navigator;
import com.vtosters.lite.R;
import ru.vtosters.lite.ui.fragments.ProxySettingsFragment;
import ru.vtosters.lite.utils.NavigatorUtils;
import ru.vtosters.lite.utils.Preferences;
import static ru.vtosters.lite.proxy.ProxyUtils.*;
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
import static ru.vtosters.lite.utils.LifecycleUtils.restartApplication;
import static ru.vtosters.lite.utils.ThemesUtils.getTextAttr;
public class ProxyHook {
public static void hookAuth(View v) {
@@ -77,16 +70,16 @@ public class ProxyHook {
.setView(rg)
.setPositiveButton(ctx.getString(R.string.vtl_confirm), ((dialog, which) -> { // Применить
if (rgZaborona.isChecked()) {
edit().putString("proxy", "zaborona").commit();
Preferences.getPreferences().edit().putString("proxy", "zaborona").commit();
restartApplication();
} else if (rgRandomProxy.isChecked()) {
edit().putString("proxy", "randomproxy").commit();
Preferences.getPreferences().edit().putString("proxy", "randomproxy").commit();
restartApplication();
} else if (rgVika.isChecked()) {
edit().putString("proxy", "vika").commit();
Preferences.getPreferences().edit().putString("proxy", "vika").commit();
restartApplication();
} else {
edit().putString("proxy", "noproxy").commit();
Preferences.getPreferences().edit().putString("proxy", "noproxy").commit();
restartApplication();
}
}))
@@ -1,7 +1,7 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.ui.components.DockBarEditorManager.getInstance;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.Preferences.getString;
import static ru.vtosters.lite.utils.Preferences.milkshake;
import static ru.vtosters.lite.utils.Preferences.superapp;
import static ru.vtosters.lite.utils.Preferences.useNewSettings;
@@ -35,7 +35,7 @@ public class StartFragmentHook {
if (vkme()) {
return DialogsFragment.class;
}
return switch (getPrefsValue("start_values")) {
return switch (getString("start_values")) {
case "newsfeed" -> milkshake() ? HomeFragment.class : NewsfeedFragment.class;
case "messenger" -> DialogsFragment.class;
case "groups" -> milkshake() ? CommunitiesCatalogFragment.class : GroupsFragment1.class;
@@ -1,20 +1,6 @@
package ru.vtosters.lite.hooks;
import static android.util.Base64.encodeToString;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.ThemesUtils.getAccentColor;
import static ru.vtosters.lite.utils.ThemesUtils.getBackgroundContent;
import static ru.vtosters.lite.utils.ThemesUtils.getBackgroundPage;
import static ru.vtosters.lite.utils.ThemesUtils.getColorFromAttr;
import static ru.vtosters.lite.utils.ThemesUtils.getHeaderBackground;
import static ru.vtosters.lite.utils.ThemesUtils.getHeaderText;
import static ru.vtosters.lite.utils.ThemesUtils.getTextAttr;
import static ru.vtosters.lite.utils.ThemesUtils.hex;
import android.webkit.WebView;
import com.vk.articles.preload.WebCachePreloader;
import com.vtosters.lite.R;
import com.vtosters.lite.data.ThemeTracker;
@@ -27,6 +13,11 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import static android.util.Base64.encodeToString;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.ThemesUtils.*;
public class VKUIHook {
public static boolean isLoaded = false;
private static String loadedCSS = "";
@@ -180,7 +180,7 @@ public class LastFMScrobbler {
var name = session.getString("name");
var key = session.getString("key");
AndroidUtils.edit()
Preferences.getPreferences().edit()
.putString("username", name)
.putString("sessionKey", key)
.putBoolean("lastfm_enabled", true)
@@ -190,7 +190,7 @@ public class LastFMScrobbler {
}
public static void logout() {
AndroidUtils.edit()
Preferences.getPreferences().edit()
.remove("username")
.remove("sessionKey")
.putBoolean("lastfm_enabled", false)
@@ -208,14 +208,14 @@ public class LastFMScrobbler {
}
public static boolean isScrobblingEnabled() {
return AndroidUtils.getPreferences().getBoolean("lastfm_enabled", false);
return Preferences.getPreferences().getBoolean("lastfm_enabled", false);
}
public static String getUserName() {
return AndroidUtils.getDefaultPrefs().getString("username", null);
return Preferences.getPreferences().getString("username", null);
}
private static String getSessionKey() {
return AndroidUtils.getDefaultPrefs().getString("sessionKey", null);
return Preferences.getPreferences().getString("sessionKey", null);
}
}
@@ -14,6 +14,7 @@ import ru.vtosters.lite.di.singleton.VtOkHttpClient;
import ru.vtosters.lite.music.cache.CacheDatabaseDelegate;
import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
import java.io.IOException;
@@ -93,7 +94,7 @@ public class CatalogJsonInjector {
var title = item.optString("title");
var id = item.optString("id");
var url = item.optString("url");
var value = AndroidUtils.getPrefsValue("musicdefcatalog");
var value = Preferences.getString("musicdefcatalog");
Log.d("VKMusic", "title: " + title + " id: " + id + " url: " + url + " value: " + value);
@@ -5,7 +5,7 @@ import static ru.vtosters.lite.proxy.api.VikaMobile.getApiHost;
import static ru.vtosters.lite.proxy.api.VikaMobile.getOauthHost;
import static ru.vtosters.lite.proxy.api.VikaMobile.getStaticHost;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import android.annotation.SuppressLint;
import android.content.Context;
@@ -21,10 +21,11 @@ import ru.vtosters.lite.proxy.http.CustomHttp;
import ru.vtosters.lite.proxy.https.CustomHttps;
import ru.vtosters.lite.proxy.socks.CustomSocks;
import ru.vtosters.lite.proxy.socks.Zaborona;
import ru.vtosters.lite.utils.Preferences;
public class ProxyUtils {
public static String getApi() {
var proxyapi = getPrefsValue("proxyapi");
var proxyapi = Preferences.getString("proxyapi");
if (isVikaProxyEnabled()) {
proxyapi = getApiHost();
@@ -38,7 +39,7 @@ public class ProxyUtils {
}
public static String getOauth() {
var oauth = getPrefsValue("proxyoauth");
var oauth = Preferences.getString("proxyoauth");
if (isVikaProxyEnabled()) {
oauth = getOauthHost();
@@ -52,7 +53,7 @@ public class ProxyUtils {
}
public static String getStatic() {
var staticapi = getPrefsValue("proxystatic");
var staticapi = Preferences.getString("proxystatic");
if (isVikaProxyEnabled()) {
staticapi = getStaticHost();
@@ -70,19 +71,19 @@ public class ProxyUtils {
}
public static Boolean isZaboronaEnabled() {
return getPrefsValue("proxy").equals("zaborona");
return Preferences.getString("proxy").equals("zaborona");
}
public static Boolean isRandomProxyEnabled() {
return getPrefsValue("proxy").equals("randomproxy");
return Preferences.getString("proxy").equals("randomproxy");
}
public static Boolean isApiProxyEnabled() {
return getPrefsValue("proxy").equals("apiproxy");
return Preferences.getString("proxy").equals("apiproxy");
}
public static Boolean isVikaProxyEnabled() {
return getPrefsValue("proxy").equals("vika");
return Preferences.getString("proxy").equals("vika");
}
public static void forceProxyApplying() {
@@ -134,7 +135,7 @@ public class ProxyUtils {
public static void setProxy() throws IOException {
if (!isAnyProxyEnabled()) return;
switch (getPrefsValue("proxy")) {
switch (Preferences.getString("proxy")) {
case "zaborona" -> Zaborona.loadProxy();
case "randomproxy" -> RandomProxy.loadProxy();
case "socks" -> CustomSocks.loadProxy();
@@ -1,20 +1,18 @@
package ru.vtosters.lite.proxy;
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
import static ru.vtosters.lite.proxy.ProxyUtils.resetProxy;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.Preferences.preferences;
import java.io.IOException;
import ru.vtosters.lite.proxy.socks.Hookzof;
import ru.vtosters.lite.proxy.socks.Jetkai;
import ru.vtosters.lite.proxy.socks.Roosterkid;
import ru.vtosters.lite.proxy.socks.TheSpeedX;
import ru.vtosters.lite.utils.Preferences;
import java.io.IOException;
import static ru.vtosters.lite.proxy.ProxyUtils.resetProxy;
public class RandomProxy {
public static String type = preferences.getString("random_type", "none");
public static String host = preferences.getString("random_host", "");
public static String type = Preferences.getPreferences().getString("random_type", "none");
public static String host = Preferences.getPreferences().getString("random_host", "");
public static boolean showProxyResult = false;
public static void loadProxy() throws IOException {
@@ -40,13 +38,13 @@ public class RandomProxy {
}
public static void setupNewProxy() throws IOException {
edit().putString("random_type", "none").putString("random_host", "").commit();
Preferences.getPreferences().edit().putString("random_type", "none").putString("random_host", "").commit();
resetProxy();
showProxyResult = true;
getProxy();
edit().putString("proxy", "randomproxy").commit();
Preferences.getPreferences().edit().putString("proxy", "randomproxy").commit();
}
public static boolean getProxy() throws IOException {
@@ -2,7 +2,7 @@ package ru.vtosters.lite.proxy.api;
import static ru.vtosters.lite.proxy.ProxyUtils.isAnyProxyEnabled;
import static ru.vtosters.lite.proxy.ProxyUtils.isVikaProxyEnabled;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.Preferences.getString;
import android.util.Log;
@@ -12,9 +12,9 @@ public class ApiProxy {
var oauth = "oauth.vk.com";
var vkstatic = "static.vk.com";
var proxyapi = getPrefsValue("proxyapi");
var proxyoauth = getPrefsValue("proxyoauth");
var proxystatic = getPrefsValue("proxystatic");
var proxyapi = getString("proxyapi");
var proxyoauth = getString("proxyoauth");
var proxystatic = getString("proxystatic");
if (isVikaProxyEnabled()) {
proxyapi = VikaMobile.getApiHost();
@@ -47,7 +47,7 @@ public class ApiProxy {
}
public static String staticFix(String str) {
var string = getPrefsValue("proxystatic");
var string = getString("proxystatic");
if (isVikaProxyEnabled()) {
string = VikaMobile.getStaticHost();
@@ -61,7 +61,7 @@ public class ApiProxy {
}
public static String getAwayPhpCom() {
var proxyapi = getPrefsValue("proxyapi");
var proxyapi = getString("proxyapi");
if (isVikaProxyEnabled()) {
proxyapi = VikaMobile.getApiHost();
@@ -1,7 +1,7 @@
package ru.vtosters.lite.proxy.http;
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.Preferences.getString;
public class CustomHttp {
public static void loadProxy() {
@@ -13,22 +13,22 @@ public class CustomHttp {
}
private static String proxyHostHTTP() {
var string = getPrefsValue("proxyHostHTTP");
var string = getString("proxyHostHTTP");
return string.isEmpty() ? "192.168.0.1" : string;
}
private static String proxyPortHTTP() {
var string = getPrefsValue("proxyPortHTTP");
var string = getString("proxyPortHTTP");
return string.isEmpty() ? "8888" : string;
}
private static String proxyUserHTTP() {
var string = getPrefsValue("proxyUserHTTP");
var string = getString("proxyUserHTTP");
return string.isEmpty() ? "" : string;
}
private static String proxyPassHTTP() {
var string = getPrefsValue("proxyPassHTTP");
var string = getString("proxyPassHTTP");
return string.isEmpty() ? "" : string;
}
}
@@ -3,7 +3,6 @@ package ru.vtosters.lite.proxy.http;
import static ru.vtosters.lite.proxy.GithubList.getProxy;
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
import static ru.vtosters.lite.proxy.ProxyUtils.hasProxy;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import android.util.Log;
@@ -14,6 +13,7 @@ import java.util.ArrayList;
import ru.vtosters.lite.proxy.RandomProxy;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
public class Jetkai {
private static final String TAG = "Jetkai_Http";
@@ -41,7 +41,7 @@ public class Jetkai {
RandomProxy.showProxyResult = false;
}
edit().putString("random_type", "http").putString("random_host", proxy).commit();
Preferences.getPreferences().edit().putString("random_type", "http").putString("random_host", proxy).commit();
System.setProperty("http.proxyHost", proxy.split(":")[0]);
System.setProperty("http.proxyPort", proxy.split(":")[1]);
@@ -3,7 +3,6 @@ package ru.vtosters.lite.proxy.http;
import static ru.vtosters.lite.proxy.GithubList.getProxy;
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
import static ru.vtosters.lite.proxy.ProxyUtils.hasProxy;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import android.util.Log;
@@ -14,6 +13,7 @@ import java.util.ArrayList;
import ru.vtosters.lite.proxy.RandomProxy;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
public class TheSpeedX {
private static final String TAG = "TheSpeedX_Http";
@@ -40,7 +40,7 @@ public class TheSpeedX {
RandomProxy.showProxyResult = false;
}
edit().putString("random_type", "http").putString("random_host", proxy).commit();
Preferences.getPreferences().edit().putString("random_type", "http").putString("random_host", proxy).commit();
System.setProperty("http.proxyHost", proxy.split(":")[0]);
System.setProperty("http.proxyPort", proxy.split(":")[1]);
@@ -1,7 +1,7 @@
package ru.vtosters.lite.proxy.https;
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.Preferences.getString;
public class CustomHttps {
public static void loadProxy() {
@@ -13,22 +13,22 @@ public class CustomHttps {
}
private static String proxyHostHTTPS() {
var string = getPrefsValue("proxyHostHTTPS");
var string = getString("proxyHostHTTPS");
return string.isEmpty() ? "192.168.0.1" : string;
}
private static String proxyPortHTTPS() {
var string = getPrefsValue("proxyPortHTTPS");
var string = getString("proxyPortHTTPS");
return string.isEmpty() ? "8888" : string;
}
private static String proxyUserHTTPS() {
var string = getPrefsValue("proxyUserHTTPS");
var string = getString("proxyUserHTTPS");
return string.isEmpty() ? "" : string;
}
private static String proxyPassHTTPS() {
String string = getPrefsValue("proxyPassHTTPS");
String string = getString("proxyPassHTTPS");
return string.isEmpty() ? "" : string;
}
}
@@ -3,7 +3,6 @@ package ru.vtosters.lite.proxy.https;
import static ru.vtosters.lite.proxy.GithubList.getProxy;
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
import static ru.vtosters.lite.proxy.ProxyUtils.hasProxy;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import android.util.Log;
@@ -14,6 +13,7 @@ import java.util.ArrayList;
import ru.vtosters.lite.proxy.RandomProxy;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
public class Jetkai {
private static final String TAG = "Jetkai_Https";
@@ -40,7 +40,7 @@ public class Jetkai {
RandomProxy.showProxyResult = false;
}
edit().putString("random_type", "https").putString("random_host", proxy).commit();
Preferences.getPreferences().edit().putString("random_type", "https").putString("random_host", proxy).commit();
System.setProperty("https.proxyHost", proxy.split(":")[0]);
System.setProperty("https.proxyPort", proxy.split(":")[1]);
@@ -3,7 +3,6 @@ package ru.vtosters.lite.proxy.https;
import static ru.vtosters.lite.proxy.GithubList.getProxy;
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
import static ru.vtosters.lite.proxy.ProxyUtils.hasProxy;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import android.util.Log;
@@ -14,6 +13,7 @@ import java.util.ArrayList;
import ru.vtosters.lite.proxy.RandomProxy;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
public class Roosterkid {
private static final String TAG = "Roosterkid_Https";
@@ -40,7 +40,7 @@ public class Roosterkid {
RandomProxy.showProxyResult = false;
}
edit().putString("random_type", "https").putString("random_host", proxy).commit();
Preferences.getPreferences().edit().putString("random_type", "https").putString("random_host", proxy).commit();
System.setProperty("https.proxyHost", proxy.split(":")[0]);
System.setProperty("https.proxyPort", proxy.split(":")[1]);
@@ -1,7 +1,7 @@
package ru.vtosters.lite.proxy.socks;
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.Preferences.getString;
public class CustomSocks {
public static void loadProxy() {
@@ -11,12 +11,12 @@ public class CustomSocks {
}
private static String proxyHostSocks() {
var string = getPrefsValue("proxyHostSocks");
var string = getString("proxyHostSocks");
return string.isEmpty() ? "192.168.0.1" : string;
}
private static String proxyPortSocks() {
var string = getPrefsValue("proxyPortSocks");
var string = getString("proxyPortSocks");
return string.isEmpty() ? "8888" : string;
}
}
@@ -3,7 +3,6 @@ package ru.vtosters.lite.proxy.socks;
import static ru.vtosters.lite.proxy.GithubList.getProxy;
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
import static ru.vtosters.lite.proxy.ProxyUtils.hasProxy;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import android.util.Log;
@@ -14,6 +13,7 @@ import java.util.ArrayList;
import ru.vtosters.lite.proxy.RandomProxy;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
public class Hookzof {
private static final String TAG = "Hookzof_Socks";
@@ -40,7 +40,7 @@ public class Hookzof {
RandomProxy.showProxyResult = false;
}
edit().putString("random_type", "socks").putString("random_host", proxy).commit();
Preferences.getPreferences().edit().putString("random_type", "socks").putString("random_host", proxy).commit();
System.setProperty("socksProxyHost", proxy.split(":")[0]);
System.setProperty("socksProxyPort", proxy.split(":")[1]);
@@ -3,7 +3,6 @@ package ru.vtosters.lite.proxy.socks;
import static ru.vtosters.lite.proxy.GithubList.getProxy;
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
import static ru.vtosters.lite.proxy.ProxyUtils.hasProxy;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import android.util.Log;
@@ -14,6 +13,7 @@ import java.util.ArrayList;
import ru.vtosters.lite.proxy.RandomProxy;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
public class Jetkai {
private static final String TAG = "Jetkai_Socks";
@@ -40,7 +40,7 @@ public class Jetkai {
RandomProxy.showProxyResult = false;
}
edit().putString("random_type", "socks").putString("random_host", proxy).commit();
Preferences.getPreferences().edit().putString("random_type", "socks").putString("random_host", proxy).commit();
System.setProperty("socksProxyHost", proxy.split(":")[0]);
System.setProperty("socksProxyPort", proxy.split(":")[1]);
@@ -3,7 +3,6 @@ package ru.vtosters.lite.proxy.socks;
import static ru.vtosters.lite.proxy.GithubList.getProxy;
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
import static ru.vtosters.lite.proxy.ProxyUtils.hasProxy;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import android.util.Log;
@@ -14,6 +13,7 @@ import java.util.ArrayList;
import ru.vtosters.lite.proxy.RandomProxy;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
public class Roosterkid {
private static final String TAG = "Roosterkid_Socks";
@@ -40,7 +40,7 @@ public class Roosterkid {
RandomProxy.showProxyResult = false;
}
edit().putString("random_type", "socks").putString("random_host", proxy).commit();
Preferences.getPreferences().edit().putString("random_type", "socks").putString("random_host", proxy).commit();
System.setProperty("socksProxyHost", proxy.split(":")[0]);
System.setProperty("socksProxyPort", proxy.split(":")[1]);
@@ -3,7 +3,6 @@ package ru.vtosters.lite.proxy.socks;
import static ru.vtosters.lite.proxy.GithubList.getProxy;
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
import static ru.vtosters.lite.proxy.ProxyUtils.hasProxy;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import android.util.Log;
@@ -14,6 +13,7 @@ import java.util.ArrayList;
import ru.vtosters.lite.proxy.RandomProxy;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
public class TheSpeedX {
private static final String TAG = "TheSpeedX_Socks";
@@ -40,7 +40,7 @@ public class TheSpeedX {
RandomProxy.showProxyResult = false;
}
edit().putString("random_type", "socks").putString("random_host", proxy).commit();
Preferences.getPreferences().edit().putString("random_type", "socks").putString("random_host", proxy).commit();
System.setProperty("socksProxyHost", proxy.split(":")[0]);
System.setProperty("socksProxyPort", proxy.split(":")[1]);
@@ -75,7 +75,7 @@ public class ImBanner {
.setMessage(AndroidUtils.getString("custom_links_warning"))
.setCancelable(false)
.setPositiveButton(R.string.continue_, (dialogInterface, i) -> {
Preferences.preferences.edit().putBoolean("linkalert", true).commit();
Preferences.getPreferences().edit().putBoolean("linkalert", true).commit();
})
.setNeutralButton(R.string.cancel, (dialogInterface, i) -> {
dialogInterface.cancel();
@@ -3,7 +3,10 @@ package ru.vtosters.lite.ssfs;
import com.vk.core.network.Network;
import ru.vtosters.lite.hooks.DateHook;
import ru.vtosters.lite.proxy.ProxyUtils;
import ru.vtosters.lite.utils.*;
import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.Base64Utils;
import ru.vtosters.lite.utils.Preferences;
import ru.vtosters.lite.utils.ThemesUtils;
public class Utils {
public static String getVKUILink() {
@@ -20,7 +23,7 @@ public class Utils {
}
public static String getDomain() {
String string = AndroidUtils.getPrefsValue("ssfscustom");
String string = Preferences.getString("ssfscustom");
if (!string.isEmpty()) return string;
@@ -2,10 +2,12 @@ package ru.vtosters.lite.themes;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import androidx.annotation.IdRes;
import com.vtosters.lite.R;
import ru.vtosters.lite.utils.Preferences;
import ru.vtosters.lite.utils.ThemesUtils;
@@ -161,12 +163,13 @@ public class ThemesCore {
}
public static boolean hasThemedAttr(Context context, int attrID) {
// try {
// Log.d(TAG, "Requesting color by attr " + context.getResources().getResourceName(attrID));
// } catch (Exception e) {
// }
if (ThemesUtils.isCustomAccentEnabled()) {
if (Preferences.dev()) {
try {
Log.d(TAG, "Requesting color by attr " + context.getResources().getResourceName(attrID));
} catch (Exception ignored) {}
}
if (isCachedAccents()) {
if (ThemesUtils.isDarkTheme()) {
return (themedColors.get(attrID) != 0 && ACCENT_THEME_ONLY_DARK.get(attrID, true) && (
@@ -2,18 +2,18 @@ package ru.vtosters.lite.themes;
import android.app.Application;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import com.google.devrel.gmscore.tools.apk.arsc.BinaryResourceFile;
import com.vtosters.lite.R;
import ru.vtosters.lite.themes.loaders.ResourcesLoader;
import ru.vtosters.lite.themes.utils.ArscEditor;
import ru.vtosters.lite.utils.IOUtils;
import ru.vtosters.lite.utils.Preferences;
import ru.vtosters.lite.utils.ThemesUtils;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.*;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
@@ -95,144 +95,126 @@ public class ThemesManager {
R.color.darker_blue,
R.color.header_blue_opacity40
};
private final static String[] NAMES = {
"resources.arsc",
"res",
"assets"
// modify it if "doNotCompress" in apktool.yml has been edited
private final static String[] DO_NOT_COMPRESS = {
".png",
".jpg",
".mp3",
"res/raw/keep_cronet_api.xml"
};
private static String baseApkPath;
private static boolean validated = false;
// Directories
private static File mainDir;
private static File binDir;
private static File palettesDir;
private static File colorSchemesDir;
// Files
// Temp archive with resources.arsc and res.zip content for loading resources
private static File resTmpZipFile = null;
// Archive with assets folder content for loading resources
private static File assetsZipFile = null;
// Archive with res folder content
private static File resZipFile = null;
// Resources table file
private static File resourcesArscFile = null;
// Modified archive with resources.arsc, other resources and assets
private static File modApk;
public static void init(Application app) {
try {
Log.d("ThemesManager", "init paths");
initPaths(app);
validateModApk();
if (hasTmpArchive() && !ThemesUtils.isMonetTheme()) {
if (!Preferences.isNewBuild() && !ThemesUtils.isMonetTheme() && canApplyCustomAccent()) {
ResourcesLoader.init(app);
ResourcesLoader.load(app, resTmpZipFile.getAbsolutePath(), assetsZipFile.getAbsolutePath(), false);
ResourcesLoader.load(app, modApk.getAbsolutePath(), false);
}
} catch (Exception e) {
Log.e("ThemesManager", String.valueOf(e));
Log.e("ThemesManager", e+"");
}
}
// validate modded apk before loading
private static void validateModApk()
throws IOException {
final var apk = new ZipFile(modApk);
apk.close();
validated = true;
}
private static void initPaths(Context context) {
baseApkPath = context.getApplicationInfo().publicSourceDir;
mainDir = new File(context.getFilesDir(), "VTLThemes");
if (!mainDir.exists()) mainDir.mkdir();
binDir = new File(mainDir, "bin");
if (!binDir.exists()) mainDir.mkdir();
colorSchemesDir = new File(mainDir, "color_schemes");
if (!colorSchemesDir.exists()) colorSchemesDir.mkdir();
palettesDir = new File(mainDir, "palettes");
if (!palettesDir.exists()) palettesDir.mkdir();
assetsZipFile = new File(binDir, "assets.zip");
resZipFile = new File(binDir, "res.zip");
resourcesArscFile = new File(binDir, "resources.arsc");
resTmpZipFile = new File(binDir, "res.tmp.zip");
modApk = new File(mainDir, "mod.apk");
}
public static void generateBins(Context context)
throws IOException {
try (final var apk = new ZipFile(context.getApplicationInfo().sourceDir)) {
for (var filename : NAMES) {
final var bin = new File(binDir, filename);
if (!bin.exists())
if (filename.contains(".")) extractFile(apk, filename, bin);
else extractAndCompressDirectory(apk, filename, new File(binDir, filename + ".zip"));
}
}
public static boolean canApplyCustomAccent() {
return validated && modApk.exists() && ThemesUtils.getReservedAccent() != Color.TRANSPARENT;
}
private static void extractFile(ZipFile apk, String name, File out)
throws IOException {
final var is = apk.getInputStream(apk.getEntry(name));
if (!out.exists()) out.getParentFile().mkdirs();
IOUtils.copy(is, out);
}
public static void generateModApk(int accentColor)
throws Throwable {
try(
final var apk = new ZipFile(baseApkPath)
) {
final var arscEntry = apk.getEntry("resources.arsc");
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");
private static void extractAndCompressDirectory(ZipFile apk, String dirName, File out)
throws IOException {
final var zos = new ZipOutputStream(new FileOutputStream(out));
try (zos) {
final var entries = apk.entries();
while (entries.hasMoreElements()) {
final var entry = entries.nextElement();
if (!entry.getName().startsWith(dirName + "/")) continue;
try(
final var zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(modApk)))
) {
final var arscBuff = arsc.toByteArray();
final var newArscEntry = new ZipEntry("resources.arsc");
zos.putNextEntry(new ZipEntry(entry.getName()));
final var crc = new CRC32();
crc.update(arscBuff);
final var zis = apk.getInputStream(entry);
IOUtils.copy(zis, zos);
newArscEntry.setSize(arscBuff.length);
newArscEntry.setMethod(ZipEntry.STORED);
newArscEntry.setCrc(crc.getValue());
zis.close();
zos.putNextEntry(newArscEntry);
zos.write(arscBuff);
zos.closeEntry();
final var entries = apk.entries();
while(entries.hasMoreElements()) {
final var entry = entries.nextElement();
final var name = entry.getName();
if(!name.startsWith("res/") && !name.startsWith("assets/") || name.equals("resources.arsc")) continue;
var doNotCompress = false;
for(var suffix : DO_NOT_COMPRESS) {
if(name.endsWith(suffix)) {
doNotCompress = true;
break;
}
}
final var entryBis = new BufferedInputStream(apk.getInputStream(entry));
final var newEntry = new ZipEntry(name);
if(doNotCompress) {
newEntry.setMethod(ZipEntry.STORED);
newEntry.setSize(entry.getSize());
newEntry.setCrc(entry.getCrc());
} else newEntry.setMethod(ZipEntry.DEFLATED);
zos.putNextEntry(newEntry);
IOUtils.copy(entryBis, zos);
entryBis.close();
zos.closeEntry();
}
}
}
}
public static boolean hasBins() {
return assetsZipFile.exists() && resZipFile.exists() && resourcesArscFile.exists();
}
public static boolean hasTmpArchive() {
return resTmpZipFile.exists();
}
public static void generateTempResArchive(int accentColor)
throws IOException {
final var resZip = new ZipFile(resZipFile);
final var zos = new ZipOutputStream(new FileOutputStream(resTmpZipFile));
try (zos) {
final var entries = resZip.entries();
while (entries.hasMoreElements()) {
final var entry = entries.nextElement();
final var is = resZip.getInputStream(entry);
zos.putNextEntry(new ZipEntry(entry.getName()));
IOUtils.copy(is, zos);
is.close();
zos.closeEntry();
}
final var arsc = new BinaryResourceFile(IOUtils.readFully(resourcesArscFile));
if (!ArscEditor.changeColors(arsc, ACCENT_COLORS, accentColor)) {
resZip.close();
resTmpZipFile.delete();
throw new IOException("Error while generating res.tmp.res");
}
zos.putNextEntry(new ZipEntry("resources.arsc"));
IOUtils.copy(new ByteArrayInputStream(arsc.toByteArray()), zos);
}
}
public static void deleteBins() {
assetsZipFile.delete();
resZipFile.delete();
resourcesArscFile.delete();
}
public static void deleteTmpArchive() {
resTmpZipFile.delete();
public static void deleteModification() {
modApk.delete();
}
}
@@ -108,7 +108,7 @@ public class ResourcesLoader {
}
}
public static void load(Context context, String resPath, String assetsPath, boolean reinject)
public static void load(Context context, String resPath, boolean reinject)
throws Exception {
final ApplicationInfo appInfo = context.getApplicationInfo();
@@ -136,8 +136,7 @@ public class ResourcesLoader {
sAssetManager = AssetManager.class.newInstance();
// Create a new AssetManager instance and point it to the resources installed under
if (AssetManagerHelper.addAssetPath(sAssetManager, resPath) == 0
|| AssetManagerHelper.addAssetPath(sAssetManager, assetsPath) == 0)
if (AssetManagerHelper.addAssetPath(sAssetManager, resPath) == 0)
throw new IllegalStateException("Could not create new AssetManager");
// Add SharedLibraries to AssetManager for resolve system resources not found issue
@@ -192,10 +191,10 @@ public class ResourcesLoader {
}
}
installResourceInsuranceHacks(context, resPath, assetsPath);
installResourceInsuranceHacks(context, resPath);
}
private static void installResourceInsuranceHacks(Context context, String patchedResApkPath, String patchedAssetsApkPath) {
private static void installResourceInsuranceHacks(Context context, String patchedResApkPath) {
try {
final Object activityThread = ReflectionUtils.getActivityThread(context, null);
final Field mHField = ReflectionUtils.findField(activityThread, "mH");
@@ -204,7 +203,7 @@ public class ResourcesLoader {
final Handler.Callback originCallback = (Handler.Callback) mCallbackField.get(mH);
if (!(originCallback instanceof ResourceInsuranceHandlerCallback)) {
final ResourceInsuranceHandlerCallback hackCallback = new ResourceInsuranceHandlerCallback(
context, patchedResApkPath, patchedAssetsApkPath, originCallback, mH.getClass());
context, patchedResApkPath, originCallback, mH.getClass());
mCallbackField.set(mH, hackCallback);
} else {
Log.w("ResourcesLoader", "installResourceInsuranceHacks: already installed, skip rest logic.");
@@ -274,7 +273,6 @@ public class ResourcesLoader {
private final Context mContext;
private final String mPatchResApkPath;
private final String mPatchedAssetsApkPath;
private final Handler.Callback mOriginalCallback;
private final int LAUNCH_ACTIVITY;
@@ -284,11 +282,10 @@ public class ResourcesLoader {
private Method mGetCallbacksMethod = null;
private boolean mSkipInterceptExecuteTransaction = false;
ResourceInsuranceHandlerCallback(Context context, String patchResApkPath, String patchedAssetsApkPath, Handler.Callback original, Class<?> hClazz) {
ResourceInsuranceHandlerCallback(Context context, String patchResApkPath, Handler.Callback original, Class<?> hClazz) {
Context appContext = context.getApplicationContext();
mContext = (appContext != null ? appContext : context);
mPatchResApkPath = patchResApkPath;
mPatchedAssetsApkPath = patchedAssetsApkPath;
mOriginalCallback = original;
LAUNCH_ACTIVITY = fetchMessageId(hClazz, "LAUNCH_ACTIVITY", 100);
RELAUNCH_ACTIVITY = fetchMessageId(hClazz, "RELAUNCH_ACTIVITY", 126);
@@ -365,7 +362,7 @@ public class ResourcesLoader {
}
if (shouldReInjectPatchedResources) {
try {
load(mContext, mPatchResApkPath, mPatchedAssetsApkPath, true);
load(mContext, mPatchResApkPath, true);
} catch (Throwable thr) {
thr.printStackTrace();
}
@@ -19,8 +19,8 @@ public class ArscEditor {
final var id = BinaryResourceIdentifier.create(packageChunk.getId(), typeSpecChunk.getId(), entry.getKey());
for (int i = 0; i < colorIds.length; ++i) {
if (colorIds[i] != id.resId()) continue;
for (int colorId : colorIds) {
if (colorId != id.resId()) continue;
final var value = entry.getValue();
value.updateValue(new BinaryResourceValue(8, value.value().type(), color /*colors[i]*/));
@@ -1,6 +1,6 @@
package ru.vtosters.lite.translators;
import static ru.vtosters.lite.utils.Preferences.preferences;
import static ru.vtosters.lite.utils.Preferences.getPreferences;
import androidx.annotation.NonNull;
import androidx.collection.LruCache;
@@ -8,6 +8,7 @@ import androidx.collection.LruCache;
import java.util.Locale;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
public abstract class BaseTranslator {
@@ -22,7 +23,7 @@ public abstract class BaseTranslator {
};
public static String getToLanguage() {
var lang = preferences.getString("lang_target", "system");
var lang = getPreferences().getString("lang_target", "system");
var systemLang = Locale.getDefault().getLanguage();
if (lang.isEmpty() || lang.equals(systemLang) || lang.equals("system"))
@@ -32,7 +33,7 @@ public abstract class BaseTranslator {
}
public static BaseTranslator getInstance() {
return switch (AndroidUtils.getPreferences().getInt("translator", 0)) {
return switch (Preferences.getPreferences().getInt("translator", 0)) {
case YANDEX -> YandexTranslator.getInstance();
case GOOGLE -> GoogleTranslator.getInstance();
case DEEPL -> DeepLTranslator.getInstance();
@@ -26,6 +26,7 @@ import com.vtosters.lite.general.fragments.GamesFragment;
import com.vtosters.lite.general.fragments.PhotosFragment;
import ru.vtosters.lite.ui.items.DockBarTab;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
import java.io.File;
import java.util.ArrayList;
@@ -33,7 +34,6 @@ import java.util.Arrays;
import java.util.List;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
import static ru.vtosters.lite.utils.Preferences.*;
public class DockBarEditorManager {
@@ -110,7 +110,7 @@ public class DockBarEditorManager {
}
public void reset() {
AndroidUtils.getPreferences()
Preferences.getPreferences()
.edit()
.putString("dockbar_tabs", "tab_news,tab_superapps,tab_messages,tab_friends,tab_profile")
.commit();
@@ -1,13 +1,11 @@
package ru.vtosters.lite.ui.components;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import android.content.res.Resources;
import androidx.fragment.app.FragmentTransaction;
import com.vtosters.lite.R;
import static ru.vtosters.lite.utils.Preferences.getString;
public class FragAnimationKit {
// Q
@@ -33,8 +31,8 @@ public class FragAnimationKit {
private static final int SSTactCloseExit = resources.getIdentifier("task_close_exit", "anim", "android");
public static void setAnimations(FragmentTransaction transaction) {
if (transaction != null && !getPrefsValue("anim_rtrn_type").equals("noanim")) {
switch (getPrefsValue("anim_rtrn_type")) {
if (transaction != null && !getString("anim_rtrn_type").equals("noanim")) {
switch (getString("anim_rtrn_type")) {
case "q" -> transaction.setCustomAnimations(
actOpenEnter,
actOpenExit,
@@ -2,11 +2,11 @@ package ru.vtosters.lite.ui.components;
import static ru.vtosters.lite.ui.vkui.VBListBuilder.VBListItem;
import static ru.vtosters.lite.ui.vkui.VBListBuilder.buildListOf;
import static ru.vtosters.lite.utils.AndroidUtils.getDefaultPrefs;
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
import android.app.Activity;
import com.vk.core.preference.Preference;
import com.vtosters.lite.R;
import java.util.ArrayList;
@@ -14,12 +14,13 @@ import java.util.Collections;
import ru.vtosters.lite.ui.vkui.VBottomSheetBuilder;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
public class NewsfeedListManager {
public static void callEditorPopup(Activity activity) {
var selectedItems = getDefaultPrefs().getString("news_feed_selected_items", "");
var filtersSet = getDefaultPrefs().getStringSet("news_feed_items_set", Collections.emptySet());
var selectedItems = Preferences.getString("news_feed_selected_items");
var filtersSet = Preferences.getPreferences().getStringSet("news_feed_items_set", Collections.emptySet());
var list = new ArrayList<VBListItem>(filtersSet.size());
if (filtersSet.isEmpty()) {
@@ -44,7 +45,8 @@ public class NewsfeedListManager {
for (VBListItem item : list)
if (item.checked)
newSelectedItems += item.id + ",";
getDefaultPrefs().edit()
Preferences.getPreferences()
.edit()
.putString("news_feed_selected_items", newSelectedItems)
.apply();
sendToast(activity.getString(R.string.newsfeed_list_update_feed_to_work));
@@ -54,7 +56,8 @@ public class NewsfeedListManager {
}
public static void resetHideItems() {
getDefaultPrefs().edit()
Preferences.getPreferences()
.edit()
.remove("news_feed_selected_items")
.remove("news_feed_items_set")
.apply();
@@ -4,14 +4,13 @@ import android.os.Build;
import com.vtosters.lite.R;
import ru.vtosters.lite.ui.items.SuperAppItem;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
public class SuperAppEditorManager {
private static SuperAppEditorManager sInstance;
@@ -29,7 +28,7 @@ public class SuperAppEditorManager {
}
private void init() {
var tmp = getPreferences().getString("superapp_items", "menu,miniapps,vkpay_slim,greeting,promo,holiday,weather,sport,games,informer,food,event,music,vk_run");
var tmp = Preferences.getPreferences().getString("superapp_items", "menu,miniapps,vkpay_slim,greeting,promo,holiday,weather,sport,games,informer,food,event,music,vk_run");
var selectedTags = !tmp.isEmpty() ? tmp.split(",") : new String[0];
parseSelectedItems(selectedTags);
}
@@ -49,7 +48,7 @@ public class SuperAppEditorManager {
public void save() {
if (mSelectedItems.size() > 0)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
getPreferences().edit().putString("superapp_items", mSelectedItems.stream()
Preferences.getPreferences().edit().putString("superapp_items", mSelectedItems.stream()
.map(item -> item.type)
.collect(Collectors.joining(",")))
.commit();
@@ -59,14 +58,14 @@ public class SuperAppEditorManager {
sb.append(item.type);
sb.append(",");
}
getPreferences().edit().putString("superapp_items", sb.toString()).commit();
Preferences.getPreferences().edit().putString("superapp_items", sb.toString()).commit();
}
else
reset();
}
public void reset() {
AndroidUtils.getPreferences()
Preferences.getPreferences()
.edit()
.putString("superapp_items", "menu,miniapps,vkpay_slim,greeting,promo,holiday,informer,event,weather,sport,games,food,music,vk_run")
.commit();
@@ -1,5 +1,6 @@
package ru.vtosters.lite.ui.dialogs;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@@ -7,12 +8,9 @@ import android.net.Uri;
import android.os.Build;
import android.os.PowerManager;
import android.provider.Settings;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vtosters.lite.R;
import ru.vtosters.lite.deviceinfo.OEMDetector;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
public class DisableBattery {
@@ -27,13 +25,14 @@ public class DisableBattery {
.setMessage(R.string.batteryissuesumm)
.setCancelable(false)
.setPositiveButton(R.string.batteryissuebtn1, (dialogInterface, i) -> {
@SuppressLint("BatteryLife")
var intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.setData(Uri.parse("package:" + packName));
activity.startActivity(intent);
})
.setNeutralButton(R.string.batteryissuebtn2,
(dialogInterface, i) -> AndroidUtils.edit().putBoolean("showDoze", false).apply()
(dialogInterface, i) -> Preferences.getPreferences().edit().putBoolean("showDoze", false).apply()
)
.show();
}
@@ -1,18 +1,14 @@
package ru.vtosters.lite.ui.dialogs;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.GmsUtils.isGmsInstalled;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import android.app.Activity;
import android.content.Intent;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vk.navigation.Navigator;
import com.vtosters.lite.R;
import ru.vtosters.lite.ui.fragments.InstallGMSFragment;
import ru.vtosters.lite.utils.NavigatorUtils;
import ru.vtosters.lite.utils.Preferences;
import static ru.vtosters.lite.utils.GmsUtils.isGmsInstalled;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
public class InstallGMS {
public static void alert(final Activity activity) {
@@ -22,10 +18,10 @@ public class InstallGMS {
.setMessage(activity.getString(R.string.gmsissuesumm))
.setCancelable(false)
.setPositiveButton(activity.getString(R.string.gmsissuebtn1), (
dialogInterface, i) -> edit().putBoolean("showAlertGms", false).apply()
dialogInterface, i) -> Preferences.getPreferences().edit().putBoolean("showAlertGms", false).apply()
)
.setNeutralButton(activity.getString(R.string.gmsissuebtn2), (dialogInterface, i) -> {
edit().putBoolean("showAlertGms", false).apply();
Preferences.getPreferences().edit().putBoolean("showAlertGms", false).apply();
NavigatorUtils.switchFragment(activity, InstallGMSFragment.class);
})
.show();
@@ -1,18 +1,15 @@
package ru.vtosters.lite.ui.dialogs;
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
import static ru.vtosters.lite.utils.LifecycleUtils.restartApplicationWithTimer;
import android.content.Context;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vtosters.lite.R;
import ru.vtosters.lite.utils.LayoutUtils;
import ru.vtosters.lite.utils.Preferences;
import static ru.vtosters.lite.utils.AndroidUtils.*;
import static ru.vtosters.lite.utils.LifecycleUtils.restartApplicationWithTimer;
public class RoundingSeekbarDialog {
public static void dialog(Context context) {
@@ -20,7 +17,7 @@ public class RoundingSeekbarDialog {
SeekBar seek = new SeekBar(context);
seek.setMax(10);
seek.setKeyProgressIncrement(0);
seek.setProgress(getPreferences().getInt("pic_rounding", 0));
seek.setProgress(Preferences.getPreferences().getInt("pic_rounding", 0));
seek.setPadding(dp2px(16f), dp2px(16f), dp2px(16f), dp2px(16f));
mContainer.addView(seek, LayoutUtils.createLinear(-1, -2));
@@ -32,7 +29,7 @@ public class RoundingSeekbarDialog {
.setNegativeButton(context.getString(R.string.cancel), null)
.setView(mContainer)
.setPositiveButton(context.getString(R.string.vtl_confirm), (dialog, which) -> {
edit().putInt("pic_rounding", seek.getProgress()).commit();
Preferences.getPreferences().edit().putInt("pic_rounding", seek.getProgress()).commit();
restartApplicationWithTimer();
})
.show();
@@ -1,7 +1,6 @@
package ru.vtosters.lite.ui.dialogs;
import static android.content.ContentValues.TAG;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.NetworkUtils.isNetworkIsSlow;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Preferences.hasVerification;
@@ -24,6 +23,7 @@ import okhttp3.Request;
import okhttp3.Response;
import ru.vtosters.lite.di.singleton.VtOkHttpClient;
import ru.vtosters.lite.utils.LifecycleUtils;
import ru.vtosters.lite.utils.Preferences;
public class ServerDialog {
private static final OkHttpClient client = VtOkHttpClient.getInstance();
@@ -101,9 +101,9 @@ public class ServerDialog {
.setMessage(message)
.setCancelable(cancelable)
.setPositiveButton(positiveButton,
(dialogInterface, i) -> edit().putBoolean(key, false).apply())
(dialogInterface, i) -> Preferences.getPreferences().edit().putBoolean(key, false).apply())
.setNeutralButton(neutralButton, (dialogInterface, i) -> {
edit().putBoolean(key, false).apply();
Preferences.getPreferences().edit().putBoolean(key, false).apply();
var intent = new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse(link));
activity.startActivity(intent);
@@ -8,8 +8,8 @@ import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vtosters.lite.R;
import ru.vtosters.lite.deviceinfo.OEMDetector;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
public class Start {
@@ -23,11 +23,11 @@ public class Start {
.setMessage(getWelcome())
.setCancelable(false)
.setPositiveButton(R.string.startbtn2,
(dialogInterface, i) -> edit().putBoolean("showAlert", false).apply()
(dialogInterface, i) -> Preferences.getPreferences().edit().putBoolean("showAlert", false).apply()
)
.setNeutralButton(R.string.startbtn1,
(dialogInterface, i) -> {
edit().putBoolean("showAlert", false).apply();
Preferences.getPreferences().edit().putBoolean("showAlert", false).apply();
activity.startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://t.me/vtosters")));
}
)
@@ -1,17 +1,14 @@
package ru.vtosters.lite.ui.dialogs;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.ThemesUtils.isDarkTheme;
import android.app.Activity;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vk.core.ui.themes.VKThemeHelper;
import com.vtosters.lite.R;
import ru.vtosters.lite.hooks.VKUIHook;
import ru.vtosters.lite.utils.Preferences;
import static ru.vtosters.lite.utils.ThemesUtils.isDarkTheme;
public class ThemeChanging {
public static void changeTheme(Activity activity, float[] f) {
if (Preferences.systemtheme()) {
@@ -20,7 +17,7 @@ public class ThemeChanging {
.setMessage(R.string.system_theme_warning)
.setCancelable(false)
.setPositiveButton(R.string.proxy_disable, (dialogInterface, i) -> { // Отключить
edit().putString("currsystemtheme", !isDarkTheme() ? "dark" : "light").commit();
Preferences.getPreferences().edit().putString("currsystemtheme", !isDarkTheme() ? "dark" : "light").commit();
VKThemeHelper.b(activity, f);
VKUIHook.clearWebCache();
})
@@ -28,7 +25,7 @@ public class ThemeChanging {
.show();
} else {
VKThemeHelper.b(activity, f);
edit().putString("currsystemtheme", isDarkTheme() ? "dark" : "light").commit();
Preferences.getPreferences().edit().putString("currsystemtheme", isDarkTheme() ? "dark" : "light").commit();
VKUIHook.clearWebCache();
}
}
@@ -32,7 +32,7 @@ public class Translate {
var translation = translator.getTranslation(text);
MAIN_EXECUTOR.execute(() -> showDialog(context, translation));
} catch (Exception e) {
Log.e("Translate", e + "");
Log.e("Translate", String.valueOf(e));
}
});
}
@@ -1,20 +1,16 @@
package ru.vtosters.lite.ui.dialogs;
import android.app.Activity;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vtosters.lite.R;
import ru.vtosters.lite.ui.fragments.VKUIwrapper;
import ru.vtosters.lite.utils.NavigatorUtils;
import ru.vtosters.lite.utils.Preferences;
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
import static ru.vtosters.lite.proxy.ProxyUtils.isAnyProxyEnabled;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import android.app.Activity;
import android.content.Intent;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vk.navigation.Navigator;
import com.vtosters.lite.R;
import ru.vtosters.lite.ui.fragments.VKUIwrapper;
import ru.vtosters.lite.utils.NavigatorUtils;
public class VKIDProtection {
public static void alert(final Activity activity) {
if (!getBoolValue("showAlertVkId", true)) return;
@@ -23,9 +19,9 @@ public class VKIDProtection {
.setMessage(R.string.vkidsumm)
.setCancelable(false)
.setPositiveButton(R.string.startbtn2,
(dialogInterface, i) -> edit().putBoolean("showAlertVkId", false).apply())
(dialogInterface, i) -> Preferences.getPreferences().edit().putBoolean("showAlertVkId", false).apply())
.setNeutralButton(R.string.vkiddisable, (dialogInterface, i) -> {
edit().putBoolean("showAlertVkId", false).apply();
Preferences.getPreferences().edit().putBoolean("showAlertVkId", false).apply();
VKUIwrapper.setLink(
isAnyProxyEnabled()
? "https://id.vk.com/account"
@@ -12,8 +12,8 @@ import ru.vtosters.lite.utils.LayoutUtils;
public class VTColorPickerBottomSheetDialog extends ModalBottomSheetWrapper<VTColorPickerBottomSheetDialog> {
private Activity mActivity;
private LinearLayout mContainer;
private final Activity mActivity;
private final LinearLayout mContainer;
public VTColorPickerBottomSheetDialog(Activity activity) {
super(activity);
@@ -43,6 +43,9 @@ public abstract class BaseToolbarFragment extends FragmentImpl {
public void setNavigationIconEnabled(boolean enabled) {
if (enabled) {
ViewUtils.a(mToolbar, R.drawable.ic_back_outline_28);
mToolbar.setNavigationOnClickListener(v -> {
ToolbarHelper.b(this);
});
} else {
ToolbarHelper.a(this, mToolbar);
}
@@ -43,9 +43,9 @@ public class FeedFragment extends MaterialPreferenceToolbarFragment {
return true;
});
findPreference("spamfilters").setSummary(count(getPrefsValue("spamfilters")));
findPreference("sourcenamefilter").setSummary(count(getPrefsValue("sourcenamefilter")));
findPreference("linkfilter").setSummary(count(getPrefsValue("linkfilter")));
findPreference("spamfilters").setSummary(count(Preferences.getString("spamfilters")));
findPreference("sourcenamefilter").setSummary(count(Preferences.getString("sourcenamefilter")));
findPreference("linkfilter").setSummary(count(Preferences.getString("linkfilter")));
findPreference("spamfilters").setOnPreferenceClickListener(preference -> {
NewsFeedFiltersUtils.setupFilters();
@@ -86,7 +86,7 @@ public class FeedFragment extends MaterialPreferenceToolbarFragment {
return true;
});
var str = getDefaultPrefs().getString("news_feed_selected_items", "");
var str = Preferences.getPreferences().getString("news_feed_selected_items", "");
findPreference("newsfeedlistmanager").setSummary(
String.format(requireContext().getString(R.string.feed_hidden), (!TextUtils.isEmpty(str) ? str.split(",").length : 0))
);
@@ -96,7 +96,7 @@ public class FeedFragment extends MaterialPreferenceToolbarFragment {
return true;
});
findPreference("feedcache").setVisible(!getPrefsValue("newsupdate").equals("no_update"));
findPreference("feedcache").setVisible(!Preferences.getString("newsupdate").equals("no_update"));
}
private String count(String text) {
@@ -116,7 +116,7 @@ public class FeedFragment extends MaterialPreferenceToolbarFragment {
.setMessage(requireContext().getString(R.string.delete_elements_confirm))
.setCancelable(false)
.setPositiveButton(requireContext().getString(R.string.yes), (dialogInterface, i) -> {
edit().remove(key).apply();
Preferences.getPreferences().edit().remove(key).apply();
sendToast(requireContext().getString(R.string.elements_deleted_success));
NewsFeedFiltersUtils.setupFilters();
})
@@ -126,7 +126,7 @@ public class FeedFragment extends MaterialPreferenceToolbarFragment {
}
private String countSet(String key) {
var set = getDefaultPrefs().getStringSet(key, null);
var set = Preferences.getPreferences().getStringSet(key, null);
StringBuilder str = new StringBuilder();
if (set != null) {
for (var s : set) {
@@ -23,8 +23,8 @@ import ru.vtosters.lite.utils.ThemesUtils;
public class IconsFragment extends MaterialPreferenceToolbarFragment {
@SuppressLint("SetTextI18n")
public static void callSelectDialog(Context ctx, String appicon) {
var defname = Preferences.preferences.getString("appname", "vt");
var deficon = Preferences.preferences.getString("selectedicon", "vt");
var defname = Preferences.getPreferences().getString("appname", "vt");
var deficon = Preferences.getPreferences().getString("selectedicon", "vt");
RadioGroup rg = new RadioGroup(ctx);
@@ -60,18 +60,18 @@ public class IconsFragment extends MaterialPreferenceToolbarFragment {
.setView(rg)
.setPositiveButton(R.string.vtl_confirm, ((dialog, which) -> {
if (rgDefault.isChecked()) {
AndroidUtils.edit().putString("appname", "vt").commit();
AndroidUtils.edit().putString("selectedicon", appicon).commit();
Preferences.getPreferences().edit().putString("appname", "vt").commit();
Preferences.getPreferences().edit().putString("selectedicon", appicon).commit();
IconManager.switchComponent(appicon, "vt");
} else if (rgVK.isChecked()) {
AndroidUtils.edit().putString("appname", "standard").commit();
AndroidUtils.edit().putString("selectedicon", appicon).commit();
Preferences.getPreferences().edit().putString("appname", "standard").commit();
Preferences.getPreferences().edit().putString("selectedicon", appicon).commit();
IconManager.switchComponent(appicon, "standard");
} else if (rgVKontakte.isChecked()) {
AndroidUtils.edit().putString("appname", "vkontakte").commit();
AndroidUtils.edit().putString("selectedicon", appicon).commit();
Preferences.getPreferences().edit().putString("appname", "vkontakte").commit();
Preferences.getPreferences().edit().putString("selectedicon", appicon).commit();
IconManager.switchComponent(appicon, "vkontakte");
}
@@ -11,7 +11,7 @@ import ru.vtosters.lite.utils.NavigatorUtils;
import ru.vtosters.lite.utils.Preferences;
import ru.vtosters.lite.utils.ThemesUtils;
import static ru.vtosters.lite.utils.AndroidUtils.*;
import static ru.vtosters.lite.utils.AndroidUtils.isTablet;
import static ru.vtosters.lite.utils.LifecycleUtils.restartApplicationWithTimer;
public class InterfaceFragment extends MaterialPreferenceToolbarFragment {
@@ -45,7 +45,7 @@ public class InterfaceFragment extends MaterialPreferenceToolbarFragment {
});
findPreference("dateformat").setOnPreferenceChangeListener((preference, o) -> {
edit().putString("dateformat", o.toString()).commit();
Preferences.getPreferences().edit().putString("dateformat", o.toString()).commit();
restartApplicationWithTimer();
return true;
});
@@ -78,10 +78,10 @@ public class InterfaceFragment extends MaterialPreferenceToolbarFragment {
findPreference("anim_rtrn_type").setVisible(false);
}
if (getPreferences().getInt("pic_rounding", 0) == 0) {
if (Preferences.getPreferences().getInt("pic_rounding", 0) == 0) {
findPreference("customrounding").setSummary(requireContext().getString(R.string.disabled));
} else {
findPreference("customrounding").setSummary(String.format(requireContext().getString(R.string.rounding_size), getPreferences().getInt("pic_rounding", 0)));
findPreference("customrounding").setSummary(String.format(requireContext().getString(R.string.rounding_size), Preferences.getPreferences().getInt("pic_rounding", 0)));
}
}
@@ -25,6 +25,7 @@ import ru.vtosters.lite.music.LastFMScrobbler;
import ru.vtosters.lite.music.cache.CacheDatabaseDelegate;
import ru.vtosters.lite.ui.adapters.ImagineArrayAdapter;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
import ru.vtosters.lite.utils.ThemesUtils;
import java.io.IOException;
@@ -152,11 +153,11 @@ public class MediaFragment extends MaterialPreferenceToolbarFragment {
);
var adapter = new ImagineArrayAdapter(requireContext(), items);
adapter.setSelected(getPreferences().getInt("search_engine", 0));
adapter.setSelected(Preferences.getPreferences().getInt("search_engine", 0));
new VkAlertDialog.Builder(getActivity())
.setAdapter(adapter, (dialog, which) -> {
getPreferences().edit().putInt("search_engine", which).apply();
Preferences.getPreferences().edit().putInt("search_engine", which).apply();
dialog.cancel();
})
.show();
@@ -7,10 +7,10 @@ import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vtosters.lite.R;
import com.vtosters.lite.general.fragments.MaterialPreferenceToolbarFragment;
import ru.vtosters.lite.ui.adapters.ImagineArrayAdapter;
import ru.vtosters.lite.utils.Preferences;
import java.util.Arrays;
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
import static ru.vtosters.lite.utils.AndroidUtils.isTablet;
import static ru.vtosters.lite.utils.LifecycleUtils.restartApplicationWithTimer;
import static ru.vtosters.lite.utils.Preferences.autoalltranslate;
@@ -47,11 +47,11 @@ public class MessagesFragment extends MaterialPreferenceToolbarFragment {
);
var adapter = new ImagineArrayAdapter(requireContext(), items);
adapter.setSelected(getPreferences().getInt("translator", 0));
adapter.setSelected(Preferences.getPreferences().getInt("translator", 0));
new VkAlertDialog.Builder(getActivity())
.setAdapter(adapter, (dialog, which) -> {
getPreferences().edit().putInt("translator", which).apply();
Preferences.getPreferences().edit().putInt("translator", which).apply();
dialog.cancel();
})
.show();
@@ -81,7 +81,7 @@ public class OtherFragment extends MaterialPreferenceToolbarFragment {
if (requestCode == VK_ADMIN_TOKEN_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
String token = data.getStringExtra("token");
AndroidUtils.getPreferences().edit().putString("vk_admin_token", token).apply();
Preferences.getPreferences().edit().putString("vk_admin_token", token).apply();
Toast.makeText(getContext(), requireContext().getString(R.string.token_saved), LENGTH_SHORT).show();
}
}
@@ -161,7 +161,7 @@ public class OtherFragment extends MaterialPreferenceToolbarFragment {
return true;
});
var pref = getDefaultPrefs().getString("autoclearcache", "Default");
var pref = Preferences.getPreferences().getString("autoclearcache", "Default");
switch (pref) {
case "Default" ->
findPreference("autoclearcache").setSummary(requireContext().getString(R.string.cache_disabled));
@@ -222,7 +222,7 @@ public class OtherFragment extends MaterialPreferenceToolbarFragment {
});
var vkAdminTokenPref = findPreference("vk_admin_token");
vkAdminTokenPref.setVisible(AndroidUtils.getDefaultPrefs().getBoolean("new_music_downloading_way", false));
vkAdminTokenPref.setVisible(Preferences.getPreferences().getBoolean("new_music_downloading_way", false));
if (vkAdminTokenPref.isVisible()) {
vkAdminTokenPref.setOnPreferenceClickListener(preference -> {
startActivityForResult(new Intent(getContext(), VKAdminTokenActivity.class), VK_ADMIN_TOKEN_REQUEST_CODE);
@@ -236,7 +236,7 @@ public class OtherFragment extends MaterialPreferenceToolbarFragment {
private void cacheAutoCleanDialog() {
String[] cacheText = {null, "100 MB", "500 MB", "1 GB", "2 GB", "5 GB"};
var val = getDefaultPrefs().getInt("autoclearcache_size", 0);
var val = Preferences.getPreferences().getInt("autoclearcache_size", 0);
RadioGroup rg = new RadioGroup(getContext());
rg.setPadding(dp2px(18f), dp2px(12f), dp2px(18f), 0);
@@ -263,7 +263,7 @@ public class OtherFragment extends MaterialPreferenceToolbarFragment {
.setPositiveButton(requireContext().getString(R.string.save), (dialog, which) -> {
var sizes = new String[]{"Default", "100mb", "500mb", "1gb", "2gb", "5gb"};
var id = rg.getCheckedRadioButtonId();
getDefaultPrefs().edit()
Preferences.getPreferences().edit()
.putInt("autoclearcache_size", id)
.putString("autoclearcache", sizes[id])
.apply();
@@ -1,6 +1,7 @@
package ru.vtosters.lite.ui.fragments;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
@@ -19,22 +20,15 @@ import ru.vtosters.lite.ui.views.rarepebble.ColorPickerView;
import ru.vtosters.lite.ui.wallpapers.WallpaperMenuFragment;
import ru.vtosters.lite.utils.*;
import java.io.IOException;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.ThemesUtils.recolorDrawable;
public class ThemesFragment extends MaterialPreferenceToolbarFragment {
private VKProgressDialog mProgressDialog;
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
mProgressDialog = new VKProgressDialog(requireContext());
mProgressDialog.setCancelable(false);
addPreferencesFromResource(R.xml.preferences_themes);
initPreferences();
}
@@ -57,20 +51,12 @@ public class ThemesFragment extends MaterialPreferenceToolbarFragment {
});
var invalidateThemeCache = findPreference("invalidate_theme_cache");
invalidateThemeCache.setOnPreferenceClickListener(preference -> {
mProgressDialog.setMessage("Инвалидация кэша...");
mProgressDialog.show();
VTExecutors.getIoExecutor().execute(() -> {
ThemesManager.deleteBins();
try {
ThemesManager.generateBins(requireContext());
requireActivity().runOnUiThread(this::restart);
} catch(IOException e) {
requireActivity().runOnUiThread(() -> showErrorDialog("Ошибка при инвалидации кэша"));
}
if(ThemesUtils.getReservedAccent() != Color.TRANSPARENT)
invalidateThemeCache.setOnPreferenceClickListener(preference -> {
setAccentColor(ThemesUtils.getReservedAccent());
return true;
});
return true;
});
else invalidateThemeCache.setVisible(false);
var navBarPreference = findPreference("navbar");
navBarPreference.setOnPreferenceClickListener(preference -> {
@@ -172,8 +158,9 @@ public class ThemesFragment extends MaterialPreferenceToolbarFragment {
}
})
.setNegativeButton(R.string.reset, (dialog, which) -> {
ThemesManager.deleteTmpArchive();
LifecycleUtils.restartApplicationWithTimer();
ThemesManager.deleteModification();
ThemesUtils.reserveAccentColor(Color.TRANSPARENT, false);
restart();
})
.setPositiveButton(R.string.cancel, null)
.show();
@@ -218,47 +205,29 @@ public class ThemesFragment extends MaterialPreferenceToolbarFragment {
}
void setAccentColor(int color) {
String message;
Runnable task;
if(!ThemesManager.hasBins()) {
message = "Генерация файлов...";
task = () -> {
try {
ThemesManager.generateBins(requireContext());
requireActivity().runOnUiThread(() -> setAccentColor(color));
} catch(IOException e) {
Log.e("ThemesFragment", e+"");
ThemesManager.deleteBins();
requireActivity().runOnUiThread(() -> showErrorDialog("Ошибка при генерации файлов"));
}
};
} else {
message = "Применение акцента...";
task = () -> {
try {
ThemesManager.generateTempResArchive(color);
requireActivity().runOnUiThread(this::restart);
} catch(IOException e) {
Log.e("ThemesFragment", e+"");
ThemesManager.deleteTmpArchive();
requireActivity().runOnUiThread(() -> showErrorDialog("Ошибка при применении акцента"));
}
};
}
final VKProgressDialog dialog = new VKProgressDialog(requireContext());
dialog.setCancelable(false);
dialog.setMessage("Применение акцента...");
dialog.show();
mProgressDialog.setMessage(message);
mProgressDialog.show();
VTExecutors.getIoExecutor().execute(task);
}
void showErrorDialog(String msg) {
mProgressDialog.dismiss();
new VkAlertDialog.Builder(requireContext())
.setTitle("Ошибка")
.setMessage(msg)
.setPositiveButton("OK", null)
.show();
VTExecutors.getIoExecutor().execute(() -> {
try {
ThemesUtils.reserveAccentColor(color, true);
ThemesManager.generateModApk(color);
requireActivity().runOnUiThread(this::restart);
} catch(Throwable e) {
Log.e("ThemesFragment", e+"");
ThemesManager.deleteModification();
requireActivity().runOnUiThread(() -> {
dialog.dismiss();
new VkAlertDialog.Builder(requireContext())
.setTitle("Ошибка")
.setMessage("Ошибка при применении акцента:\n" + e)
.setPositiveButton("OK", null)
.show();
});
}
});
}
void restart() {
@@ -30,6 +30,9 @@ import ru.vtosters.lite.ui.dialogs.OTADialog;
import ru.vtosters.lite.ui.fragments.tgstickers.StickersFragment;
import ru.vtosters.lite.utils.*;
import static ru.vtosters.lite.utils.Preferences.VERSIONNAME;
import static ru.vtosters.lite.utils.Preferences.isValidSignature;
public class VTSettings extends MaterialPreferenceToolbarFragment implements TelegramStickersService.StickersEventsListener {
public static String getValAsString(@StringRes int strRes, Boolean value) {
@@ -52,7 +55,7 @@ public class VTSettings extends MaterialPreferenceToolbarFragment implements Tel
}
public static String getProxysumm() {
var type = AndroidUtils.getPrefsValue("proxy");
var type = Preferences.getString("proxy");
if(type.equals("noproxy") || type.isEmpty())
type = AndroidUtils.getString(R.string.vtlsettdisabled);
@@ -63,7 +66,7 @@ public class VTSettings extends MaterialPreferenceToolbarFragment implements Tel
public static String getThemesumm() {
String[] themeTypeName = AndroidUtils.getArray("theme_type_name");
return AndroidUtils.getString("current_theme") + ": " + switch (AndroidUtils.getPrefsValue("currsystemtheme")) {
return AndroidUtils.getString("current_theme") + ": " + switch (Preferences.getString("currsystemtheme")) {
case "system" -> themeTypeName[0];
case "dark" -> themeTypeName[1];
case "light" -> themeTypeName[2];
@@ -115,47 +118,49 @@ public class VTSettings extends MaterialPreferenceToolbarFragment implements Tel
AndroidUtils.checkLinksVerified(this.requireActivity());
var accountSwitcher = PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"account_switcher",
AccountManagerUtils.getUsername(),
requireContext().getString(R.string.vtllogout),
requireContext().getDrawable(R.drawable.ic_user_circle_outline_28),
preference -> {
try {
VKAuth.a("logout", false);
} catch(Exception ignored) {
}
if (AccountManagerUtils.isLogin()) {
var accountSwitcher = PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"account_switcher",
AccountManagerUtils.getUsername(),
requireContext().getString(R.string.vtllogout),
requireContext().getDrawable(R.drawable.ic_user_circle_outline_28),
preference -> {
try {
VKAuth.a("logout", false);
} catch(Exception ignored) {
}
var intent = new Intent(requireContext(), MainActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
requireContext().startActivity(intent);
var intent = new Intent(requireContext(), MainActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
requireContext().startActivity(intent);
return false;
return false;
});
VTExecutors.getIoScheduler().a(() -> {
var icon = ImageUtils.getDrawableFromUrl(AccountManagerUtils.getUserPhoto(), 0, true, true);
if(icon == null) return;
requireActivity().runOnUiThread(() -> {
accountSwitcher.setIcon(icon);
});
VTExecutors.getIoScheduler().a(() -> {
var icon = ImageUtils.getDrawableFromUrl(AccountManagerUtils.getUserPhoto(), 0, true, true);
if(icon == null) return;
requireActivity().runOnUiThread(() -> {
accountSwitcher.setIcon(icon);
});
});
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"",
requireContext().getString(R.string.vtssfs),
getSSFSsumm(),
R.drawable.ic_link_circle_outline_28,
preference -> {
VKUIwrapper.setLink(Utils.getVKUILink());
NavigatorUtils.switchFragment(requireContext(), VKUIwrapper.class);
return false;
}
);
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"",
requireContext().getString(R.string.vtssfs),
getSSFSsumm(),
R.drawable.ic_link_circle_outline_28,
preference -> {
VKUIwrapper.setLink(Utils.getVKUILink());
NavigatorUtils.switchFragment(requireContext(), VKUIwrapper.class);
return false;
}
);
}
PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), R.string.appearance_theme_use_system);
@@ -175,7 +180,7 @@ public class VTSettings extends MaterialPreferenceToolbarFragment implements Tel
var theme = value.equals("dark") ? ThemesUtils.getDarkTheme() : ThemesUtils.getLightTheme();
ThemesUtils.applyTheme(theme);
}
AndroidUtils.edit().putString("currsystemtheme", value).commit();
Preferences.getPreferences().edit().putString("currsystemtheme", value).commit();
SystemThemeChangerHook.onThemeChanged(getResources().getConfiguration());
return true;
});
@@ -235,7 +240,7 @@ public class VTSettings extends MaterialPreferenceToolbarFragment implements Tel
R.drawable.ic_globe_outline_28,
true,
(preference, o) -> {
AndroidUtils.edit().putBoolean("ssl", (boolean) o).commit();
Preferences.getPreferences().edit().putBoolean("ssl", (boolean) o).commit();
return true;
}
);
@@ -250,65 +255,67 @@ public class VTSettings extends MaterialPreferenceToolbarFragment implements Tel
true,
(preference, o) -> {
boolean value = (boolean) o;
AndroidUtils.edit().putBoolean("autoupdates", value).commit();
Preferences.getPreferences().edit().putBoolean("autoupdates", value).commit();
return true;
}
);
}
}
PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), R.string.vtsettaccount);
if (AccountManagerUtils.isLogin()) {
PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), R.string.vtsettaccount);
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"",
requireContext().getString(R.string.vkconnect),
"",
R.drawable.ic_user_circle_outline_28,
preference -> {
VKUIwrapper.officalLinks("account");
NavigatorUtils.switchFragment(requireContext(), VKUIwrapper.class);
return false;
}
);
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"",
requireContext().getString(R.string.privacy_settings),
"",
R.drawable.ic_privacy_outline_28,
preference -> {
NavigatorUtils.switchFragment(requireContext(), PrivacyFragment.class);
return false;
}
);
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"",
requireContext().getString(R.string.sett_account),
"",
R.drawable.ic_user_outline_28,
preference -> {
NavigatorUtils.switchFragment(requireContext(), SettingsAccountFragment.class);
return false;
}
);
if(AccountManagerUtils.isVKTester()) {
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"",
requireContext().getString(R.string.bugs),
requireContext().getString(R.string.vkconnect),
"",
R.drawable.ic_bug_outline_28,
R.drawable.ic_user_circle_outline_28,
preference -> {
VKUIwrapper.officalLinks("bugs");
VKUIwrapper.officalLinks("account");
NavigatorUtils.switchFragment(requireContext(), VKUIwrapper.class);
return false;
}
);
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"",
requireContext().getString(R.string.privacy_settings),
"",
R.drawable.ic_privacy_outline_28,
preference -> {
NavigatorUtils.switchFragment(requireContext(), PrivacyFragment.class);
return false;
}
);
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"",
requireContext().getString(R.string.sett_account),
"",
R.drawable.ic_user_outline_28,
preference -> {
NavigatorUtils.switchFragment(requireContext(), SettingsAccountFragment.class);
return false;
}
);
if(AccountManagerUtils.isVKTester()) {
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"",
requireContext().getString(R.string.bugs),
"",
R.drawable.ic_bug_outline_28,
preference -> {
VKUIwrapper.officalLinks("bugs");
NavigatorUtils.switchFragment(requireContext(), VKUIwrapper.class);
return false;
}
);
}
}
PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), requireContext().getString(R.string.vtlvksettings));
@@ -504,7 +511,7 @@ public class VTSettings extends MaterialPreferenceToolbarFragment implements Tel
getPreferenceScreen(),
"",
requireContext().getString(R.string.menu_about),
"Commit: " + About.getBuildNumber(),
(isValidSignature() ? VERSIONNAME : "Dev") + " | " + About.getBuildNumber(),
R.drawable.ic_about_outline_28,
preference -> {
NavigatorUtils.switchFragment(requireContext(), AboutAppFragment.class);
@@ -3,6 +3,8 @@ package ru.vtosters.lite.ui.wallpapers;
import android.graphics.Bitmap;
import android.graphics.Color;
import java.util.Arrays;
public class ConvolutionMatrix {
public static final int SIZE = 3;
@@ -83,17 +85,13 @@ public class ConvolutionMatrix {
public void setAll(double value) {
for (int x = 0; x < SIZE; ++x) {
for (int y = 0; y < SIZE; ++y) {
Matrix[x][y] = value;
}
Arrays.fill(Matrix[x], value);
}
}
public void applyConfig(double[][] config) {
for (int x = 0; x < SIZE; ++x) {
for (int y = 0; y < SIZE; ++y) {
Matrix[x][y] = config[x][y];
}
System.arraycopy(config[x], 0, Matrix[x], 0, SIZE);
}
}
}
@@ -0,0 +1,245 @@
package ru.vtosters.lite.ui.wallpapers;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.vtosters.lite.R;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
import java.nio.ByteBuffer;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
enum ImageEffects {
Blur(true,
AndroidUtils.getArray(R.array.filter_types),
new String[]{"disabled", "low", "med", "high"},
getGlobalContext().getString(R.string.filter_blur)
) {
@Override
public void applyEffect(ByteBuffer bitmap, int height, int width) {
int radius;
switch (Preferences.getPreferences().getString(ImageEffects.Blur.toString(), "disabled")) {
case "low":
radius = 8;
break;
case "med":
radius = 14;
break;
case "high":
radius = 20;
break;
default:
return;
}
NativeEffects.gaussian(bitmap, height, width, radius);
}
@Override
public String getSummary() {
switch (Preferences.getPreferences().getString(ImageEffects.Blur.toString(), "disabled")) {
case "low":
return AndroidUtils.getString(R.string.wallpapers_low);
case "med":
return AndroidUtils.getString(R.string.wallpapers_med);
case "high":
return AndroidUtils.getString(R.string.wallpapers_high);
default:
return AndroidUtils.getString(R.string.wallpapers_disabled);
}
}
},
Dim(true,
AndroidUtils.getArray(R.array.filter_dim_types),
new String[]{"disabled", "dim_black", "dim_white"},
getGlobalContext().getString(R.string.filter_dim)) {
@Override
public void applyEffect(ByteBuffer bitmap, int height, int width) {
var delta = 0;
switch (Preferences.getPreferences().getString(ImageEffects.Dim.toString(), "disabled")) {
case "dim_black":
delta = -50; break;
case "dim_white":
delta = 50; break;
default:
return;
}
NativeEffects.dim(bitmap, height, width, delta);
}
@Override
public String getSummary() {
switch (Preferences.getPreferences().getString(ImageEffects.Dim.toString(), "disabled")) {
case "dim_black":
return AndroidUtils.getString(R.string.wallpapers_dim_black);
case "dim_white":
return AndroidUtils.getString(R.string.wallpapers_dim_white);
default:
return AndroidUtils.getString(R.string.wallpapers_disabled);
}
}
},
Mosaic(true,
AndroidUtils.getArray(R.array.filter_types),
new String[]{"disabled", "low", "med", "high"},
getGlobalContext().getString(R.string.filter_mosaic)) {
@Override
public void applyEffect(ByteBuffer bitmap, int height, int width) {
var scale = 0;
switch (Preferences.getPreferences().getString(ImageEffects.Mosaic.toString(), "disabled")) {
case "high":
scale = 50; break;
case "med":
scale = 25; break;
case "low":
scale = 10; break;
default:
return;
}
NativeEffects.mosaic(bitmap, height, width, scale);
}
@Override
public String getSummary() {
switch (Preferences.getPreferences().getString(ImageEffects.Mosaic.toString(), "disabled")) {
case "low":
return AndroidUtils.getString(R.string.wallpapers_low);
case "med":
return AndroidUtils.getString(R.string.wallpapers_med);
case "high":
return AndroidUtils.getString(R.string.wallpapers_high);
default:
return AndroidUtils.getString(R.string.wallpapers_disabled);
}
}
},
Monochrome(false, null, null,
getGlobalContext().getString(R.string.filter_monochrome)) {
@Override
public void applyEffect(ByteBuffer bitmap, int height, int width) {
if (isApplied()) {
NativeEffects.monochrome(bitmap);
}
}
},
Invert(false, null, null,
getGlobalContext().getString(R.string.filter_invert_colors)) {
@Override
public void applyEffect(ByteBuffer bitmap, int height, int width) {
if (isApplied()) {
NativeEffects.invert(bitmap);
}
}
},
Sepia(false, null, null,
getGlobalContext().getString(R.string.filter_sepia)) {
@Override
public void applyEffect(ByteBuffer bitmap, int height, int width) {
if (isApplied()) {
NativeEffects.sepia(bitmap);
}
}
},
Emboss(false, null, null,
getGlobalContext().getString(R.string.filter_emboss)) {
@Override
public String getSummary() {
return getGlobalContext().getString(R.string.filter_maybe_lag);
}
@Override
public void applyEffect(ByteBuffer bitmap, int height, int width) {
if (isApplied()) {
NativeEffects.emboss(bitmap, height, width);
}
}
},
Engrave(false, null, null,
getGlobalContext().getString(R.string.filter_engrave)) {
@Override
public String getSummary() {
return getGlobalContext().getString(R.string.filter_maybe_lag);
}
@Override
public void applyEffect(ByteBuffer bitmap, int height, int width) {
if (isApplied()) {
NativeEffects.engrave(bitmap, height, width);
}
}
},
Flea(false, null, null,
getGlobalContext().getString(R.string.filter_flea)) {
@Override
public void applyEffect(ByteBuffer bitmap, int height, int width) {
if (isApplied()) {
NativeEffects.flea(bitmap);
}
}
},
Snow(false, null, null,
getGlobalContext().getString(R.string.filter_snow)) {
@Override
public void applyEffect(ByteBuffer bitmap, int height, int width) {
if (isApplied()){
NativeEffects.snow(bitmap);
}
}
};
private final boolean free;
private final String title;
@Nullable
private final String[] entryValues;
@Nullable
private final String[] entries;
ImageEffects(boolean free, @Nullable String[] entries, @Nullable String[] entryValues, String title) {
this.free = free;
this.entries = entries;
this.entryValues = entryValues;
this.title = title;
}
public String getTitle() {
return title;
}
public Boolean isSwitch() {
return entryValues == null || entryValues.length == 0;
}
public Boolean isList() {
return entryValues != null && entryValues.length > 0;
}
public boolean isFree() {
return free;
}
@Nullable
public String[] getEntries() {
return entries;
}
@Nullable
public String[] getEntryValues() {
return entryValues;
}
public String getSummary() {
return "";
}
public abstract void applyEffect(ByteBuffer bitmap, int height, int width);
protected boolean isApplied() {
return Preferences.getPreferences().getBoolean(this.toString(), false);
}
@NonNull
@Override
public String toString() {
return "msg_" + super.toString();
}
}
@@ -1,351 +1,37 @@
package ru.vtosters.lite.ui.wallpapers;
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
import static ru.vtosters.lite.utils.AndroidUtils.getResources;
import static ru.vtosters.lite.utils.Preferences.hasVerification;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LightingColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;
import com.vk.medianative.MediaNative;
import java.util.Random;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class ImageFilters {
public static final int COLOR_MAX = 0xFF;
public static Drawable getFilteredDrawable(Drawable orig) {
if (orig == null) return null;
if (!(orig instanceof BitmapDrawable)) return orig;
if (!getPreferences().getString("msg_blur_radius", "disabled").equals("disabled")) {
orig = getBlurredWallpaper(orig, getRadius());
Bitmap bitmap = ((BitmapDrawable) orig).getBitmap();
if (bitmap.getConfig() != Bitmap.Config.ARGB_8888) {
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
}
if (!getPreferences().getString("msg_dim", "off").equals("off")) {
orig = getDimmed(orig);
var directBuff = ByteBuffer.allocateDirect(bitmap.getByteCount());
directBuff.order(ByteOrder.nativeOrder());
bitmap.copyPixelsToBuffer(directBuff);
// FIXME: preserve order of filters
// e.g. user turned invert first then mosaic then monochrome
// invocation here happens regardless of that order
for (var type : ImageEffects.values()) {
type.applyEffect(directBuff, bitmap.getHeight(), bitmap.getWidth());
}
if (!getPreferences().getString("msg_mosaic", "disabled").equals("disabled")) {
orig = getMosaic(orig);
}
if (!hasVerification()) {
return orig;
}
if (getPreferences().getBoolean("msg_monochrome", false)) {
orig = getMonochrome(orig);
}
Bitmap bm;
if (orig != null) {
bm = ((BitmapDrawable) orig).getBitmap();
} else {
return null;
}
Bitmap instance = bm.copy(Bitmap.Config.ARGB_8888, true);
if (getPreferences().getBoolean("msg_invert", false)) {
instance = applyInvertEffect(instance);
}
if (getPreferences().getBoolean("msg_sepia", false)) {
instance = applySepiaEffect(instance);
}
if (getPreferences().getBoolean("msg_emboss", false)) {
instance = applyEmbossEffect(instance);
}
if (getPreferences().getBoolean("msg_engrave", false)) {
instance = applyEngraveEffect(instance);
}
if (getPreferences().getBoolean("msg_flea", false)) {
instance = applyFleaEffect(instance);
}
if (getPreferences().getBoolean("msg_snow", false)) {
instance = applySnowEffect(instance);
}
return new BitmapDrawable(getResources(), instance);
}
private static int getRadius() {
String radius = getPreferences().getString("msg_blur_radius", "disabled");
return switch (radius) {
case "low" -> 8;
case "med" -> 14;
default -> 20;
};
}
public static Drawable getBlurredWallpaper(Drawable orig, int radius) {
try {
if (orig == null) return null;
if (!(orig instanceof BitmapDrawable)) return orig; // we need only BitmapDrawable
Bitmap bm = ((BitmapDrawable) orig).getBitmap();
Bitmap instance = bm.copy(Bitmap.Config.ARGB_8888, true);
MediaNative.blurBitmap(instance, radius);
return new BitmapDrawable(getResources(), instance);
} catch (Exception e) {
e.printStackTrace();
return orig;
}
}
public static Drawable getMosaic(Drawable orig) {
int scale = 100;
if (orig == null) return null;
if (!(orig instanceof BitmapDrawable)) return orig;
Bitmap bm = ((BitmapDrawable) orig).getBitmap();
Bitmap instance = bm.copy(Bitmap.Config.ARGB_8888, true);
String radius = getPreferences().getString("msg_mosaic", "disabled");
switch (radius) {
case "high" -> scale = 25;
case "med" -> scale = 50;
case "low" -> scale = 75;
}
Bitmap temp = Bitmap.createScaledBitmap(instance, scale, scale, false);
Bitmap mosaicBitmap = Bitmap.createScaledBitmap(temp, instance.getWidth(), instance.getHeight(), false);
return new BitmapDrawable(getResources(), mosaicBitmap);
}
public static Drawable getDimmed(Drawable orig) {
if (orig == null) return null;
if (!(orig instanceof BitmapDrawable)) return orig;
Bitmap bm = ((BitmapDrawable) orig).getBitmap();
Bitmap instance = bm.copy(Bitmap.Config.ARGB_8888, true);
String radius = getPreferences().getString("msg_dim", "disabled");
switch (radius) {
case "dim_black":
darken(instance);
case "dim_white":
lighten(instance);
}
return new BitmapDrawable(getResources(), instance);
}
public static Drawable getMonochrome(Drawable orig) {
if (orig == null) return null;
if (!(orig instanceof BitmapDrawable)) return orig;
Bitmap bm = ((BitmapDrawable) orig).getBitmap();
Bitmap instance = bm.copy(Bitmap.Config.ARGB_8888, true);
Bitmap bwBitmap = Bitmap.createBitmap(instance.getWidth(), instance.getHeight(), Bitmap.Config.RGB_565);
float[] hsv = new float[3];
for (int col = 0; col < instance.getWidth(); col++) {
for (int row = 0; row < instance.getHeight(); row++) {
Color.colorToHSV(instance.getPixel(col, row), hsv);
if (hsv[2] > 0.5f) {
bwBitmap.setPixel(col, row, 0xffffffff);
} else {
bwBitmap.setPixel(col, row, 0xff000000);
}
}
}
return new BitmapDrawable(getResources(), bwBitmap);
}
private static void darken(Bitmap bm) {
try {
Canvas canvas = new Canvas(bm);
Paint p = new Paint(Color.RED);
ColorFilter filter = new LightingColorFilter(0xFF7F7F7F, 0x00000000); // darken
p.setColorFilter(filter);
canvas.drawBitmap(bm, new Matrix(), p);
} catch (Exception e) {
Log.d("WallpaperD", e.getMessage());
}
}
private static void lighten(Bitmap bm) {
try {
Canvas canvas = new Canvas(bm);
Paint p = new Paint(Color.RED);
ColorFilter filter = new LightingColorFilter(0xFFFFFFFF, 0x00222222); // lighten
p.setColorFilter(filter);
canvas.drawBitmap(bm, new Matrix(), p);
} catch (Exception e) {
Log.d("WallpaperL", e.getMessage());
}
}
public static Bitmap applyInvertEffect(Bitmap src) {
// create new bitmap with the same settings as source bitmap
Bitmap bmOut = Bitmap.createBitmap(src.getWidth(), src.getHeight(), src.getConfig());
// color info
int A, R, G, B;
int pixelColor;
// image size
int height = src.getHeight();
int width = src.getWidth();
// scan through every pixel
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// get one pixel
pixelColor = src.getPixel(x, y);
// saving alpha channel
A = Color.alpha(pixelColor);
// inverting byte for each R/G/B channel
R = 255 - Color.red(pixelColor);
G = 255 - Color.green(pixelColor);
B = 255 - Color.blue(pixelColor);
// set newly-inverted pixel to output image
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}
// return final bitmap
return bmOut;
}
public static Bitmap applySepiaEffect(Bitmap src) {
// image size
int width = src.getWidth();
int height = src.getHeight();
// create output bitmap
Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
// constant grayscale
final double GS_RED = 0.3;
final double GS_GREEN = 0.59;
final double GS_BLUE = 0.11;
// color information
int A, R, G, B;
int pixel;
// scan through all pixels
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
// get pixel color
pixel = src.getPixel(x, y);
// get color on each channel
A = Color.alpha(pixel);
R = Color.red(pixel);
G = Color.green(pixel);
B = Color.blue(pixel);
// apply grayscale sample
B = (int) (GS_RED * R + GS_GREEN * G + GS_BLUE * B);
// apply intensity level for sepia tone
R = G = B = (int) (B * 0.9);
// set new pixel color to output bitmap
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}
// return final image
return bmOut;
}
public static Bitmap applyEmbossEffect(Bitmap src) {
double[][] EmbossConfig = new double[][]{
{-1, 0, -1},
{0, 4, 0},
{-1, 0, -1}
};
ConvolutionMatrix convMatrix = new ConvolutionMatrix(3);
convMatrix.applyConfig(EmbossConfig);
convMatrix.Factor = 1;
convMatrix.Offset = 127;
return ConvolutionMatrix.computeConvolution3x3(src, convMatrix);
}
public static Bitmap applyEngraveEffect(Bitmap src) {
ConvolutionMatrix convMatrix = new ConvolutionMatrix(3);
convMatrix.setAll(0);
convMatrix.Matrix[0][0] = -2;
convMatrix.Matrix[1][1] = 2;
convMatrix.Factor = 1;
convMatrix.Offset = 95;
return ConvolutionMatrix.computeConvolution3x3(src, convMatrix);
}
public static Bitmap applyFleaEffect(Bitmap source) {
// get image size
int width = source.getWidth();
int height = source.getHeight();
int[] pixels = new int[width * height];
// get pixel array from source
source.getPixels(pixels, 0, width, 0, 0, width, height);
// a random object
Random random = new Random();
int index;
// iteration through pixels
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
// get current index in 2D-matrix
index = y * width + x;
// get random color
int randColor = Color.rgb(random.nextInt(COLOR_MAX),
random.nextInt(COLOR_MAX), random.nextInt(COLOR_MAX));
// OR
pixels[index] |= randColor;
}
}
// output bitmap
Bitmap bmOut = Bitmap.createBitmap(width, height, source.getConfig());
bmOut.setPixels(pixels, 0, width, 0, 0, width, height);
return bmOut;
}
public static Bitmap applySnowEffect(Bitmap source) {
// get image size
int width = source.getWidth();
int height = source.getHeight();
int[] pixels = new int[width * height];
// get pixel array from source
source.getPixels(pixels, 0, width, 0, 0, width, height);
// random object
Random random = new Random();
int R, G, B, index, thresHold;
// iteration through pixels
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
// get current index in 2D-matrix
index = y * width + x;
// get color
R = Color.red(pixels[index]);
G = Color.green(pixels[index]);
B = Color.blue(pixels[index]);
// generate threshold
thresHold = random.nextInt(COLOR_MAX);
if (R > thresHold && G > thresHold && B > thresHold) {
pixels[index] = Color.rgb(COLOR_MAX, COLOR_MAX, COLOR_MAX);
}
}
}
// output bitmap
Bitmap bmOut = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
bmOut.setPixels(pixels, 0, width, 0, 0, width, height);
return bmOut;
directBuff.flip();
bitmap.copyPixelsFromBuffer(directBuff);
return new BitmapDrawable(getResources(), bitmap);
}
}
@@ -0,0 +1,22 @@
package ru.vtosters.lite.ui.wallpapers;
import java.nio.ByteBuffer;
public class NativeEffects {
static {
System.loadLibrary("native_effects");
}
public static native String monochrome(ByteBuffer input);
public static native String invert(ByteBuffer input);
public static native String sepia(ByteBuffer input);
public static native String emboss(ByteBuffer input, int height, int width);
public static native String engrave(ByteBuffer input, int height, int width);
public static native String flea(ByteBuffer input);
public static native String snow(ByteBuffer input);
// FIXME: slow when comparing with MediaNative.blurBitmap
public static native String gaussian(ByteBuffer input, int height, int width, float radius);
public static native String dim(ByteBuffer input, int height, int width, int delta);
public static native String mosaic(ByteBuffer input, int height, int width, int scale);
}
@@ -7,20 +7,19 @@ import android.net.Uri;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.preference.ListPreference;
import com.vtosters.lite.R;
import com.vtosters.lite.general.fragments.MaterialPreferenceToolbarFragment;
import com.vtosters.lite.im.ImEngineProvider;
import ru.vtosters.lite.ui.PreferenceFragmentUtils;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.Preferences;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import static ru.vtosters.lite.ui.wallpapers.WallpapersHooks.*;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Preferences.hasVerification;
@@ -29,7 +28,6 @@ public class WallpaperMenuFragment extends MaterialPreferenceToolbarFragment {
private WallpaperPreferences mWPPreviewPref;
public static void copyStream(InputStream copyFrom, OutputStream copyTo) throws IOException {
byte[] buffer = new byte[1024];
int length;
while ((length = copyFrom.read(buffer)) > 0) {
@@ -47,146 +45,117 @@ public class WallpaperMenuFragment extends MaterialPreferenceToolbarFragment {
addPreferencesFromResource(R.xml.empty);
PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), requireContext().getString(R.string.vkim_settings_appearance_chat_preview_title));
PreferenceFragmentUtils.addPreferenceCategory(
getPreferenceScreen(),
requireContext().getString(R.string.vkim_settings_appearance_chat_preview_title)
);
mWPPreviewPref = new WallpaperPreferences(getContext());
mWPPreviewPref.setIcon(null);
mWPPreviewPref.setIconSpaceReserved(false);
getPreferenceScreen().addPreference(mWPPreviewPref);
PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "wp_set", requireContext().getString(R.string.wallpaper_select), requireContext().getString(R.string.wallpaper_from_gallery), R.drawable.ic_picture_outline_28, preference -> {
startActivityForResult(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI), 1488);
removeStickCache();
return true;
});
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"wp_set",
requireContext().getString(R.string.wallpaper_select),
requireContext().getString(R.string.wallpaper_from_gallery),
R.drawable.ic_picture_outline_28,
preference -> {
startActivityForResult(
new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI
),
1488
);
removeStickCache();
return true;
});
PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "wp_clear", requireContext().getString(R.string.wallpaper_remove), "", R.drawable.ic_delete_outline_28, preference -> {
removeWallpaper();
requestUpdateWallpaper();
mWPPreviewPref.redraw();
removeStickCache();
return true;
});
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"wp_clear",
requireContext().getString(R.string.wallpaper_remove),
"",
R.drawable.ic_delete_outline_28,
preference -> {
removeWallpaper();
requestUpdateWallpaper();
mWPPreviewPref.redraw();
removeStickCache();
return true;
});
PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), requireContext().getString(R.string.vtlfilters));
if (!hasVerification() && !getBoolValue("dialogrecomm", false)) {
PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", requireContext().getString(R.string.filters_warning), requireContext().getString(R.string.icons_warning_info), 0, preference -> {
requireContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://vtosters.app/donate/")));
return false;
});
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"",
requireContext().getString(R.string.filters_warning),
requireContext().getString(R.string.icons_warning_info),
0,
preference -> {
requireContext().startActivity(
new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse("https://vtosters.app/donate/"))
);
return false;
});
}
PreferenceFragmentUtils.addListPreference(getPreferenceScreen(), "msg_blur_radius", "disabled", requireContext().getString(R.string.filter_blur), AndroidUtils.getArray(R.array.filter_types), new String[]{
"disabled", "low", "med", "high"
});
Arrays.stream(ImageEffects.values())
.filter(imageEffects -> imageEffects.isFree() || hasVerification())
.forEach(it -> {
if (it.isList()) {
var pref = PreferenceFragmentUtils.addListPreference(
getPreferenceScreen(),
it.toString(),
"disabled",
it.getTitle(),
it.getEntries(),
it.getEntryValues()
);
pref.setSummary(it.getSummary());
pref.setOnPreferenceChangeListener((preference, o) -> {
Preferences.getPreferences().edit().putString(it.toString(), (String) o).apply();
preference.setSummary(it.getSummary());
requestUpdateWallpaper();
mWPPreviewPref.redraw();
return true;
});
} else if (it.isSwitch()) {
PreferenceFragmentUtils.addMaterialSwitchPreference(
getPreferenceScreen(),
it.toString(),
it.getTitle(),
it.getSummary(),
0,
false,
(preference, o) -> {
Preferences.getPreferences().edit().putBoolean(it.toString(), (Boolean) o).apply();
requestUpdateWallpaper();
mWPPreviewPref.redraw();
return true;
});
}
});
PreferenceFragmentUtils.addListPreference(getPreferenceScreen(), "msg_dim", "off", requireContext().getString(R.string.filter_dim), AndroidUtils.getArray(R.array.filter_dim_types), new String[]{
"off", "dim_black", "dim_white"
});
PreferenceFragmentUtils.addListPreference(getPreferenceScreen(), "msg_mosaic", "disabled", requireContext().getString(R.string.filter_mosaic), AndroidUtils.getArray(R.array.filter_types), new String[]{
"disabled", "low", "med", "high"
});
if (hasVerification()) {
PreferenceFragmentUtils.addMaterialSwitchPreference(getPreferenceScreen(), "msg_monochrome", requireContext().getString(R.string.filter_monochrome), "", 0, false, (preference, o) -> {
boolean value = (boolean) o;
edit().putBoolean("msg_monochrome", value).commit();
requestUpdateWallpaper();
mWPPreviewPref.redraw();
return true;
});
PreferenceFragmentUtils.addMaterialSwitchPreference(getPreferenceScreen(), "msg_invert", requireContext().getString(R.string.filter_invert_colors), "", 0, false, (preference, o) -> {
boolean value = (boolean) o;
edit().putBoolean("msg_invert", value).commit();
requestUpdateWallpaper();
mWPPreviewPref.redraw();
return true;
});
PreferenceFragmentUtils.addMaterialSwitchPreference(getPreferenceScreen(), "msg_sepia", requireContext().getString(R.string.filter_sepia), "", 0, false, (preference, o) -> {
boolean value = (boolean) o;
edit().putBoolean("msg_sepia", value).commit();
requestUpdateWallpaper();
mWPPreviewPref.redraw();
return true;
});
PreferenceFragmentUtils.addMaterialSwitchPreference(getPreferenceScreen(), "msg_emboss", requireContext().getString(R.string.filter_emboss), requireContext().getString(R.string.filter_maybe_lag), 0, false, (preference, o) -> {
boolean value = (boolean) o;
edit().putBoolean("msg_emboss", value).commit();
requestUpdateWallpaper();
mWPPreviewPref.redraw();
return true;
});
PreferenceFragmentUtils.addMaterialSwitchPreference(getPreferenceScreen(), "msg_engrave", requireContext().getString(R.string.filter_engrave), requireContext().getString(R.string.filter_maybe_lag), 0, false, (preference, o) -> {
boolean value = (boolean) o;
edit().putBoolean("msg_engrave", value).commit();
requestUpdateWallpaper();
mWPPreviewPref.redraw();
return true;
});
PreferenceFragmentUtils.addMaterialSwitchPreference(getPreferenceScreen(), "msg_flea", requireContext().getString(R.string.filter_flea), "", 0, false, (preference, o) -> {
boolean value = (boolean) o;
edit().putBoolean("msg_flea", value).commit();
requestUpdateWallpaper();
mWPPreviewPref.redraw();
return true;
});
PreferenceFragmentUtils.addMaterialSwitchPreference(getPreferenceScreen(), "msg_snow", requireContext().getString(R.string.filter_flea), "", 0, false, (preference, o) -> {
boolean value = (boolean) o;
edit().putBoolean("msg_snow", value).commit();
requestUpdateWallpaper();
mWPPreviewPref.redraw();
return true;
});
}
PreferenceFragmentUtils.addMaterialSwitchPreference(getPreferenceScreen(), "compresswp", requireContext().getString(R.string.compress_wallpaper_title), requireContext().getString(R.string.compress_wallpaper_summ), 0, true, (preference, o) -> {
boolean value = (boolean) o;
edit().putBoolean("compresswp", value).commit();
requestUpdateWallpaper();
mWPPreviewPref.redraw();
return true;
});
ListPreference blur = (ListPreference) findPreference("msg_blur_radius");
ListPreference dim = (ListPreference) findPreference("msg_dim");
ListPreference mosaic = (ListPreference) findPreference("msg_mosaic");
blur.setSummary(getRadiusSummary());
dim.setSummary(getDimmingSummary());
mosaic.setSummary(getMosaicSummary());
blur.setOnPreferenceChangeListener((preference, o) -> {
edit().putString("msg_blur_radius", (String) o).apply();
preference.setSummary(getRadiusSummary());
requestUpdateWallpaper();
mWPPreviewPref.redraw();
return true;
});
dim.setOnPreferenceChangeListener((preference, o) -> {
edit().putString("msg_dim", (String) o).apply();
preference.setSummary(getDimmingSummary());
requestUpdateWallpaper();
mWPPreviewPref.redraw();
return true;
});
mosaic.setOnPreferenceChangeListener((preference, o) -> {
edit().putString("msg_mosaic", (String) o).apply();
preference.setSummary(getMosaicSummary());
requestUpdateWallpaper();
mWPPreviewPref.redraw();
return true;
});
PreferenceFragmentUtils.addMaterialSwitchPreference(
getPreferenceScreen(),
"compresswp",
requireContext().getString(R.string.compress_wallpaper_title),
requireContext().getString(R.string.compress_wallpaper_summ),
0,
true,
(preference, o) -> {
boolean value = (boolean) o;
Preferences.getPreferences().edit().putBoolean("compresswp", value).commit();
requestUpdateWallpaper();
mWPPreviewPref.redraw();
return true;
});
}
@Override
@@ -1,7 +1,6 @@
package ru.vtosters.lite.ui.wallpapers;
import static ru.vtosters.lite.ui.wallpapers.WallpapersHooks.getFilteredFile;
import static ru.vtosters.lite.ui.wallpapers.WallpapersHooks.getWallpaperFile;
import static ru.vtosters.lite.ui.wallpapers.WallpapersHooks.*;
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
import android.annotation.SuppressLint;
@@ -59,12 +58,8 @@ public class WallpaperPreferences extends Preference {
}
private void requestBg() {
final Drawable drawable = getFilteredFile();
if (drawable != null && getWallpaperFile() != null)
mChatBackground.setImageDrawable(drawable);
else
mChatBackground.setImageDrawable(null);
final Drawable drawable = getWallpaper();
mChatBackground.setImageDrawable(drawable);
}
@SuppressLint("NotifyDataSetChanged")
@@ -1,78 +1,97 @@
package ru.vtosters.lite.ui.wallpapers;
import static com.vk.im.engine.h.im_bg_chat;
import static ru.vtosters.lite.ui.wallpapers.ImageFilters.getFilteredDrawable;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.ImageView;
import com.vtosters.lite.R;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.ThemesUtils;
import vigo.sdk.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.util.function.Supplier;
import static com.vk.im.engine.h.im_bg_chat;
import static ru.vtosters.lite.ui.wallpapers.ImageFilters.getFilteredDrawable;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
public class WallpapersHooks {
private static final boolean compress = getBoolValue("compresswp", true);
private static File mWallpaperFile;
// TODO: force compress by default not asking user about that?
private static final Supplier<Boolean> compress = () -> getBoolValue("compresswp", true);
private static final File originalWp = new File(getGlobalContext().getFilesDir(), "wallpaper.jpeg");
private static final File compressedWp = new File(getGlobalContext().getFilesDir(), "compressedwp.jpeg");
// TODO: cache to file?
private static Drawable mWallpaper;
private static boolean mUpdateWallpaperRequested = true;
private static boolean mUpdateWallpaperFileRequested = true;
public static File getWallpaperFile() {
if (mWallpaperFile == null) {
mWallpaperFile = new File(getGlobalContext().getFilesDir(), "wallpaper.webp");
// TODO: respect blur, when there is blur/mosaic effect applied these two can be even less, just HD (1280x720) for e.g.
private static final int MAX_WP_WIDTH = 1080;
private static final int MAX_WP_HEIGHT = 1920;
public static void setBg(View view) {
if (hasWallpapers()) {
((ImageView) view).setImageDrawable(getWallpaper()); // set picture to background
} else {
view.setBackgroundColor(ThemesUtils.getColorFromAttr(im_bg_chat)); // set default bg color
}
return mWallpaperFile;
}
public static Drawable getFilteredFile() {
File file = null;
File wp = mWallpaperFile;
String temp = getGlobalContext().getFilesDir() + File.separator + "filteredwp.webp";
if (wp != null && mUpdateWallpaperFileRequested) {
try {
file = new File(temp);
file.createNewFile();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
((BitmapDrawable) getFilteredDrawable(Drawable.createFromPath(wp.getAbsolutePath()))).getBitmap().compress(Bitmap.CompressFormat.WEBP, (compress ? 80 : 95), bos);
byte[] bitmapdata = bos.toByteArray();
FileOutputStream fos = new FileOutputStream(file);
fos.write(bitmapdata);
fos.flush();
fos.close();
} catch (Exception e) {
Log.d("Wallpapers", e.getMessage());
}
mUpdateWallpaperFileRequested = false;
}
try {
return Drawable.createFromPath(temp);
} catch (Exception e) {
if (file != null) {
return Drawable.createFromPath(file.getAbsolutePath());
} else {
public static Drawable getWallpaper() {
if (mWallpaper == null || mUpdateWallpaperRequested) {
if (!originalWp.exists()) {
return null;
}
Drawable drawable;
if (compress.get()) {
if (!compressedWp.exists() && !prepareCompressed()) {
return null;
}
drawable = Drawable.createFromPath(compressedWp.getAbsolutePath());
} else {
drawable = Drawable.createFromPath(originalWp.getAbsolutePath());
}
if (drawable == null) {
return null;
}
mWallpaper = getFilteredDrawable(drawable);
mUpdateWallpaperRequested = false;
}
return mWallpaper;
}
private static boolean prepareCompressed() {
// TODO remove this check? with "compress" enabled it should be fine
if (!eligibleWallpaperFile(originalWp)) {
return false;
}
try (var f = new FileOutputStream(compressedWp)) {
var bitmap = BitmapFactory.decodeFile(originalWp.getAbsolutePath());
if (bitmap.getHeight() > MAX_WP_HEIGHT || bitmap.getWidth() > MAX_WP_WIDTH) {
bitmap = resize(bitmap, MAX_WP_WIDTH, MAX_WP_HEIGHT);
}
var drawable = new BitmapDrawable(null, bitmap);
// TODO: remove duplication without changes when provided image already fits required params
drawable.getBitmap().compress(Bitmap.CompressFormat.WEBP, 90, f);
} catch (Exception e) {
Log.d("Wallpapers", e.getMessage());
return false;
}
return true;
}
public static File getWallpaperFile() {
return originalWp;
}
private static Boolean eligibleWallpaperFile(File file) {
@@ -85,94 +104,40 @@ public class WallpapersHooks {
}
}
public static void setBg(View view) {
if (hasWallpapers()) {
((ImageView) view).setImageDrawable(getFilteredFile()); // set picture to background
} else {
view.setBackgroundColor(ThemesUtils.getColorFromAttr(im_bg_chat)); // set default bg color
}
}
public static String getWallpaperUrl() {
var file = getWallpaperFile();
if (file.exists() && eligibleWallpaperFile(file)) {
return file.getAbsolutePath();
}
return "default";
}
public static boolean hasWallpapers() {
return getWallpaper() != null;
}
public static Drawable getWallpaper() {
if (mWallpaper == null || mUpdateWallpaperRequested) {
String url = getWallpaperUrl();
if (url.equals("default") || url.isEmpty()) {
return null;
}
Drawable drawable = Drawable.createFromPath(getWallpaperUrl());
if (drawable == null) {
return null;
}
mWallpaper = drawable;
mWallpaper = getFilteredDrawable(mWallpaper);
mUpdateWallpaperRequested = false;
}
return mWallpaper;
}
public static void requestUpdateWallpaper() {
mUpdateWallpaperRequested = true;
mUpdateWallpaperFileRequested = true;
}
public static String getRadiusSummary() {
String radius = getPreferences().getString("msg_blur_radius", "disabled");
return switch (radius) {
case "low" -> AndroidUtils.getString(R.string.wallpapers_low);
case "med" -> AndroidUtils.getString(R.string.wallpapers_med);
case "high" -> AndroidUtils.getString(R.string.wallpapers_high);
default -> AndroidUtils.getString(R.string.wallpapers_disabled);
};
}
public static String getDimmingSummary() {
String radius = getPreferences().getString("msg_dim", "disabled");
return switch (radius) {
case "dim_black" -> AndroidUtils.getString(R.string.wallpapers_dim_black);
case "dim_white" -> AndroidUtils.getString(R.string.wallpapers_dim_white);
default -> AndroidUtils.getString(R.string.wallpapers_disabled);
};
}
public static String getMosaicSummary() {
String radius = getPreferences().getString("msg_mosaic", "disabled");
return switch (radius) {
case "low" -> AndroidUtils.getString(R.string.wallpapers_low);
case "med" -> AndroidUtils.getString(R.string.wallpapers_med);
case "high" -> AndroidUtils.getString(R.string.wallpapers_high);
default -> AndroidUtils.getString(R.string.wallpapers_disabled);
};
}
public static void removeWallpaper() {
try {
new File(getGlobalContext().getFilesDir(), "wallpaper.webp").delete();
new File(getGlobalContext().getFilesDir(), "filteredwp.webp").delete();
mWallpaperFile = null;
mWallpaper = null;
originalWp.delete();
compressedWp.delete();
} catch (Exception e) {
Log.d("Wallpapers", e.getMessage());
}
}
private static Bitmap resize(Bitmap image, int maxWidth, int maxHeight) {
if (maxHeight > 0 && maxWidth > 0) {
int width = image.getWidth();
int height = image.getHeight();
float ratioBitmap = (float) width / (float) height;
float ratioMax = (float) maxWidth / (float) maxHeight;
int finalWidth = maxWidth;
int finalHeight = maxHeight;
if (ratioMax > ratioBitmap) {
finalWidth = (int) ((float) maxHeight * ratioBitmap);
} else {
finalHeight = (int) ((float) maxWidth / ratioBitmap);
}
image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true);
}
return image;
}
}
@@ -1,21 +1,17 @@
package ru.vtosters.lite.utils;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.AndroidUtils.getApplicationName;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
import static ru.vtosters.lite.utils.Preferences.VERSIONNAME;
import static ru.vtosters.lite.utils.Preferences.devmenu;
import static ru.vtosters.lite.utils.Preferences.isValidSignature;
import android.content.Context;
import android.content.res.AssetManager;
import android.text.TextUtils;
import android.view.View;
import com.vtosters.lite.R;
import java.io.IOException;
import java.util.Scanner;
import static ru.vtosters.lite.utils.AndroidUtils.*;
import static ru.vtosters.lite.utils.Preferences.*;
public class About {
public static String getBuildNumber() {
return getBuild(getGlobalContext(), "version.properties");
@@ -26,7 +22,7 @@ public class About {
if (devmenu()) {
sendToast(AndroidUtils.getString(R.string.debug_menu_already_activated));
} else {
edit().putBoolean("devmenu", true).apply();
Preferences.getPreferences().edit().putBoolean("devmenu", true).apply();
sendToast(AndroidUtils.getString(R.string.debug_menu_activated));
}
return true;
@@ -38,16 +34,14 @@ public class About {
}
public static String getBuild(Context context, String name) {
try (
Scanner scanner = new Scanner(context.getAssets().open(name))
) {
while (scanner.hasNextLine()) {
String line = scanner.findInLine("VERSION_BUILD=.+");
if (line != null)
return line.replace("VERSION_BUILD=", "");
return "0000000";
try {
final var scanner = new Scanner(context.getAssets().open(name, AssetManager.ACCESS_BUFFER));
while(scanner.hasNextLine()) {
final var line = scanner.findInLine("VERSION_BUILD=.+");
if(!TextUtils.isEmpty(line))
return line.substring(14);
}
} catch (IOException e) {
} catch(IOException e) {
e.printStackTrace();
}
return "0000000";
@@ -53,6 +53,10 @@ public class AccountManagerUtils {
return userProfile.b;
} // UserId Profile via userProfile
public static boolean isLogin() {
return VKAccountManager.d().b1();
}
public static int getUserID(ExtendedUserProfile extendedUserProfile) {
return getUserID(fromEup(extendedUserProfile));
} // UserId Profile via extendedUserProfile
@@ -32,28 +32,10 @@ import static ru.vtosters.lite.utils.Preferences.getBoolValue;
public class AndroidUtils {
public static SharedPreferences getDefaultPrefs() {
if (Preferences.preferences == null)
Preferences.preferences = PreferenceManager.getDefaultSharedPreferences(getGlobalContext());
return Preferences.preferences;
}
public static SharedPreferences getPreferences() {
return PreferenceManager.getDefaultSharedPreferences(getGlobalContext());
}
public static boolean isTablet() {
return Screen.l(getGlobalContext());
}
public static String getPrefsValue(String pref) {
return getPreferences().getString(pref, "");
} // Get pref value as string
public static SharedPreferences.Editor edit() {
return PreferenceManager.getDefaultSharedPreferences(getGlobalContext()).edit();
} // Edit SharedPreferences
@NonNull
public static Context getGlobalContext() {
try {
@@ -176,7 +158,7 @@ public class AndroidUtils {
.setMessage(AndroidUtils.getString("app_open_by_default_settings"))
.setCancelable(false)
.setPositiveButton(com.vtosters.lite.R.string.social_graph_skip,
(dialogInterface, i) -> edit().putBoolean("showUnverifDialog", false).apply()
(dialogInterface, i) -> Preferences.getPreferences().edit().putBoolean("showUnverifDialog", false).apply()
)
.setNeutralButton(com.vtosters.lite.R.string.open_settings,
(dialogInterface, i) -> {
@@ -1,7 +1,7 @@
package ru.vtosters.lite.utils;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.Preferences.getString;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import android.annotation.SuppressLint;
@@ -73,7 +73,7 @@ public class DeletedMessagesHandler {
}
private static String getPrefixUndelete() {
var prefs = getPrefsValue("undeletemsg_prefix_value");
var prefs = getString("undeletemsg_prefix_value");
if (prefs.isEmpty()) {
return "\uD83D\uDDD1 ";
@@ -17,7 +17,7 @@ import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class IOUtils {
public static final int BUFFER_SIZE = 0x800;
public static final int BUFFER_SIZE = 8192;
public static byte[] decodeStream(InputStream encIs, String keyURL)
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IOException {
@@ -112,7 +112,7 @@ public class IOUtils {
public static void deleteRecursive(File f, boolean selfDeletion) {
if (f.isDirectory()) {
var fs = f.listFiles();
if (fs != null && fs.length > 0)
if (fs != null)
for (var child : fs)
deleteRecursive(child, true);
}
@@ -58,7 +58,7 @@ public class ImageUtils {
final int width = bitmap.getWidth();
final int height = bitmap.getHeight();
final Bitmap outputBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
int pref = Preferences.preferences.getInt("pic_rounding", 0);
int pref = Preferences.getPreferences().getInt("pic_rounding", 0);
final Canvas canvas = new Canvas(outputBitmap);
final Path path = new Path();
@@ -4,6 +4,7 @@ import android.content.Context;
import android.content.Intent;
import com.vk.core.fragments.FragmentImpl;
import com.vk.navigation.Navigator;
import ru.vtosters.lite.ui.fragments.VTSettings;
public class NavigatorUtils {
@@ -13,4 +14,14 @@ public class NavigatorUtils {
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
/**
* switch to settings for {@link Intent.ACTION_APPLICATION_PREFERENCES}*/
public static void switchToSettings(Context context) {
var intent = new Navigator(VTSettings.class)
.b(context)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intent);
}
}
@@ -1,7 +1,7 @@
package ru.vtosters.lite.utils;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.Preferences.getString;
import static ru.vtosters.lite.utils.Preferences.ads;
import static ru.vtosters.lite.utils.Preferences.adsgroup;
import static ru.vtosters.lite.utils.Preferences.authorsrecomm;
@@ -41,17 +41,17 @@ public class NewsFeedFiltersUtils {
getFilter("shitposting", "IDontWantToReadIt.txt", mFilters);
getFilter("cringecopyright", "CopyrightAds.txt", mFiltersLinks);
var customFilters = getPrefsValue("spamfilters");
var customFilters = getString("spamfilters");
if (!customFilters.isEmpty()) {
mFilters.addAll(Arrays.asList(customFilters.toLowerCase().split(", ")));
}
var sourceNameFilter = getPrefsValue("sourcenamefilter");
var sourceNameFilter = getString("sourcenamefilter");
if (!sourceNameFilter.isEmpty()) {
mFiltersNames.addAll(Arrays.asList(sourceNameFilter.toLowerCase().split(", ")));
}
var linkFilter = getPrefsValue("linkfilter");
var linkFilter = getString("linkfilter");
if (!linkFilter.isEmpty()) {
mFiltersLinks.addAll(Arrays.asList(linkFilter.toLowerCase().split(", ")));
}
@@ -156,7 +156,7 @@ public class NewsFeedFiltersUtils {
}
public static String getAllFilters() {
return getPrefsValue("spamfilters");
return getString("spamfilters");
}
public static boolean isBadNews(String text) {
@@ -1,33 +1,26 @@
package ru.vtosters.lite.utils;
import static java.lang.Long.MAX_VALUE;
import static ru.vtosters.lite.proxy.ProxyUtils.setProxy;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.setupFilters;
import static ru.vtosters.lite.utils.SignatureChecker.validateAppSignature;
import static ru.vtosters.lite.utils.VTVerifications.isPrometheus;
import static ru.vtosters.lite.utils.VTVerifications.isVerified;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.StrictMode;
import android.preference.PreferenceManager;
import android.util.Log;
import com.vtosters.lite.data.Users;
import com.vtosters.lite.fragments.SettingsListFragment;
import ru.vtosters.lite.ui.fragments.VTSettings;
import java.security.NoSuchAlgorithmException;
import ru.vtosters.lite.ui.fragments.VTSettings;
import static java.lang.Long.MAX_VALUE;
import static ru.vtosters.lite.proxy.ProxyUtils.setProxy;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.setupFilters;
import static ru.vtosters.lite.utils.SignatureChecker.validateAppSignature;
import static ru.vtosters.lite.utils.VTVerifications.isPrometheus;
import static ru.vtosters.lite.utils.VTVerifications.isVerified;
public class Preferences {
public static SharedPreferences preferences = getGlobalContext().getSharedPreferences("com.vtosters.lite_preferences", Context.MODE_PRIVATE);
public static String VERSIONNAME = "Beta";
public static void init(Application application) throws Exception {
@@ -41,6 +34,14 @@ public class Preferences {
LifecycleUtils.registerActivities(application);
} // VK Init
public static SharedPreferences getPreferences() {
return getGlobalContext().getSharedPreferences("com.vtosters.lite_preferences", Context.MODE_PRIVATE);
}
public static String getString(String name) {
return getPreferences().getString(name, "");
}
public static void forceOffline() {
setupFilters();
@@ -50,10 +51,7 @@ public class Preferences {
}
public static boolean getBoolValue(String key, Boolean value) {
if (preferences == null) {
preferences = PreferenceManager.getDefaultSharedPreferences(getGlobalContext());
}
return preferences.getBoolean(key, value);
return getPreferences().getBoolean(key, value);
} // Set bool by default and get value
public static SharedPreferences getPrefsFromFile(String filename) {
@@ -291,6 +289,15 @@ public class Preferences {
return !getBoolValue("isRoamingState", false) && isValidSignature() && (!dev() || getBoolValue("autoupdates", true));
}
public static boolean isNewBuild() {
return !getPreferences().getString("build_number", "")
.equals(About.getBuildNumber());
}
public static void updateBuildNumber() {
getPreferences().edit().putString("build_number", About.getBuildNumber()).commit();
}
public static boolean isValidSignature() {
try {
return validateAppSignature();
@@ -313,7 +320,7 @@ public class Preferences {
}
public static long getSizeForDelete() {
return switch (getPrefsValue("clearcache")) {
return switch (Preferences.getPreferences().getString("clearcache", "")) {
case "100mb" -> 104857600L;
case "500mb" -> 524288000L;
case "1gb" -> 1073741824L;
@@ -78,8 +78,7 @@ public class ReflectionUtils {
return findMethod(instance.getClass(), methodName, params);
}
public static Object getActivityThread(Context context, Class<?> clz)
throws InvocationTargetException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException {
public static Object getActivityThread(Context context, Class<?> clz) {
try {
if(clz == null) clz = findClass("android.app.ActivityThread");
final Method currentActivityThreadMtd = findMethod(clz, "currentActivityThread");
@@ -48,7 +48,7 @@ public class ThemesUtils {
} // Apply VKTheme and ImTheme (hard applying without dynamic theme changing)
public static boolean isCustomAccentEnabled() {
return ThemesUtils.isMonetTheme() || ThemesManager.hasTmpArchive();
return ThemesUtils.isMonetTheme() || ThemesManager.canApplyCustomAccent();
}
public static ColorStateList getAccenedColorStateList() {
@@ -101,6 +101,21 @@ public class ThemesUtils {
return getColorFromAttr(R.attr.accent);
} // Color accent
//region Used for migrating accent color to new version
public static int getReservedAccent() {
return Preferences.getPreferences().getInt("reserved_accent_color", Color.TRANSPARENT);
}
public static void reserveAccentColor(int accent, boolean async) {
final var editor = Preferences.getPreferences().edit();
editor.putInt("reserved_accent_color", accent);
if(async) editor.apply();
else editor.commit();
}
//endregion
public static int getMutedAccentColor() {
return getMutedColor(getAccentColor());
}
@@ -197,7 +212,7 @@ public class ThemesUtils {
}
public static void setCustomAccentColor(int newColor, boolean async) {
var editor = AndroidUtils.edit().putInt("accent_color", newColor);
var editor = Preferences.getPreferences().edit().putInt("accent_color", newColor);
if (async) editor.apply();
else editor.commit();
}
@@ -1,19 +1,15 @@
package ru.vtosters.lite.utils;
import android.util.Log;
import com.vtosters.lite.R;
import org.json.JSONException;
import org.json.JSONObject;
import static ru.vtosters.lite.net.Request.makeRequest;
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
import static ru.vtosters.lite.proxy.ProxyUtils.getOauth;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
import android.util.Log;
import com.vtosters.lite.R;
import org.json.JSONException;
import org.json.JSONObject;
public class VKMeHandler {
public static void getVkMeToken(String username, String password) {
makeRequest("https://" +
@@ -45,15 +41,15 @@ public class VKMeHandler {
}
public static void removeToken() {
edit().remove("vkmetoken").commit();
Preferences.getPreferences().edit().remove("vkmetoken").commit();
}
public static String getToken() {
return getPrefsValue("vkmetoken");
return Preferences.getString("vkmetoken");
}
public static void setToken(String token) {
edit().putString("vkmetoken", token).commit();
Preferences.getPreferences().edit().putString("vkmetoken", token).commit();
}
public static void setPrivacyStatus(String status) {
+4
View File
@@ -3,9 +3,13 @@ buildscript {
repositories {
google()
mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.1'
classpath 'org.mozilla.rust-android-gradle:plugin:0.9.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
+2
View File
@@ -0,0 +1,2 @@
/target
Cargo.lock
+18
View File
@@ -0,0 +1,18 @@
[package]
name = "native-effects"
version = "0.1.0"
edition = "2021"
[profile.release]
opt-level = 3
strip = true
lto = true
codegen-units = 1
[lib]
crate-type = ["cdylib"]
[dependencies]
jni = "0.20.0"
rand = "0.8.5"
image = "0.24.5"
+365
View File
@@ -0,0 +1,365 @@
use jni::objects::JByteBuffer;
use jni::objects::JClass;
use jni::sys::jfloat;
use jni::sys::jint;
use jni::sys::jstring;
use jni::JNIEnv;
use rand::Rng;
use std::cmp::max;
// We assume that input ByteBuffer is always in ARGB_8888 format
#[repr(C)]
#[derive(Debug, Clone, Copy)]
struct Pixel {
r: u8,
g: u8,
b: u8,
a: u8,
}
impl Pixel {
fn set_color(&mut self, r: u8, g: u8, b: u8) {
self.r = r;
self.g = g;
self.b = b;
}
fn invert(&mut self) {
self.r = 255 - self.r;
self.g = 255 - self.g;
self.b = 255 - self.b;
}
}
fn resolve_pixel_slice<'a>(env: &JNIEnv<'a>, bitmap_buffer: &JByteBuffer<'a>) -> &'a mut [Pixel] {
let start = env
.get_direct_buffer_address(*bitmap_buffer)
.expect("Unable to resolve DirectBuffer address");
let capacity = env
.get_direct_buffer_capacity(*bitmap_buffer)
.expect("Unable to resolve DirectBuffer size");
let s = start as *mut Pixel;
unsafe { std::slice::from_raw_parts_mut(s, capacity / 4) }
}
#[no_mangle]
pub extern "C" fn Java_ru_vtosters_lite_ui_wallpapers_NativeEffects_monochrome(
env: JNIEnv,
_: JClass,
bitmap_buffer: JByteBuffer,
) -> jstring {
let pixels = resolve_pixel_slice(&env, &bitmap_buffer);
pixels.iter_mut().for_each(|p| {
// value (V) from HSV
let value = max(p.r, max(p.g, p.b));
if value > 127 {
p.set_color(255, 255, 255);
} else {
p.set_color(0, 0, 0);
}
});
let output = env
.new_string("Applied Monochrome effect!")
.expect("Couldn't create java string!");
return **output;
}
#[no_mangle]
pub extern "C" fn Java_ru_vtosters_lite_ui_wallpapers_NativeEffects_invert(
env: JNIEnv,
_: JClass,
bitmap_buffer: JByteBuffer,
) -> jstring {
let pixels = resolve_pixel_slice(&env, &bitmap_buffer);
pixels.iter_mut().for_each(|p| p.invert());
let output = env
.new_string("Applied Invert effect!")
.expect("Couldn't create java string!");
return **output;
}
#[no_mangle]
pub extern "C" fn Java_ru_vtosters_lite_ui_wallpapers_NativeEffects_sepia(
env: JNIEnv,
_: JClass,
bitmap_buffer: JByteBuffer,
) -> jstring {
let pixels = resolve_pixel_slice(&env, &bitmap_buffer);
pixels.iter_mut().for_each(|p| {
let r = p.r as f32;
let g = p.g as f32;
let b = p.b as f32;
let new_red = 0.393 * r + 0.769 * g + 0.189 * b;
let new_green = 0.349 * r + 0.686 * g + 0.168 * b;
let new_blue = 0.272 * r + 0.534 * g + 0.131 * b;
p.set_color(new_red as u8, new_green as u8, new_blue as u8);
});
let output = env
.new_string("Applied Sepia effect!")
.expect("Couldn't create java string!");
return **output;
}
#[no_mangle]
pub extern "C" fn Java_ru_vtosters_lite_ui_wallpapers_NativeEffects_emboss(
env: JNIEnv,
_: JClass,
bitmap_buffer: JByteBuffer,
height: jint,
width: jint,
) -> jstring {
let pixels = resolve_pixel_slice(&env, &bitmap_buffer);
let kernel = [-1.0, 0.0, -1.0, 0.0, 4.0, 0.0, -1.0, 0.0, -1.0];
let out: &mut Vec<Pixel> = &mut Vec::new();
for (y, row) in pixels.chunks(width as usize).enumerate() {
for (x, pixel) in row.iter().enumerate() {
if y == 0 || x == 0 || y == (height - 1) as usize || x == (width - 1) as usize {
out.push(*pixel);
continue;
}
let start = y * width as usize + x - 1;
let end = start + 3;
let matrix = [
&pixels[start - width as usize..end - width as usize],
&pixels[start..end],
&pixels[start + width as usize..end + width as usize],
]
.concat();
let mut acc = [64.0, 64.0, 64.0];
for (p, k) in matrix.iter().zip(kernel.iter()) {
acc[0] += p.r as f32 * k;
acc[1] += p.g as f32 * k;
acc[2] += p.b as f32 * k;
}
out.push(Pixel {
r: acc[0] as u8,
g: acc[1] as u8,
b: acc[2] as u8,
a: pixel.a,
});
}
}
pixels.copy_from_slice(&out);
let output = env
.new_string("Applied Emboss effect!")
.expect("Couldn't create java string!");
return **output;
}
#[no_mangle]
pub extern "C" fn Java_ru_vtosters_lite_ui_wallpapers_NativeEffects_engrave(
env: JNIEnv,
_: JClass,
bitmap_buffer: JByteBuffer,
height: jint,
width: jint,
) -> jstring {
let pixels = resolve_pixel_slice(&env, &bitmap_buffer);
let kernel = [-2.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 0.0];
let out: &mut Vec<Pixel> = &mut Vec::new();
for (y, row) in pixels.chunks(width as usize).enumerate() {
for (x, pixel) in row.iter().enumerate() {
if y == 0 || x == 0 || y == (height - 1) as usize || x == (width - 1) as usize {
out.push(*pixel);
continue;
}
let start = y * width as usize + x - 1;
let end = start + 3;
let matrix = [
&pixels[start - width as usize..end - width as usize],
&pixels[start..end],
&pixels[start + width as usize..end + width as usize],
]
.concat();
let mut acc = [95.0, 95.0, 95.0];
for (p, k) in matrix.iter().zip(kernel.iter()) {
acc[0] += p.r as f32 * k;
acc[1] += p.g as f32 * k;
acc[2] += p.b as f32 * k;
}
out.push(Pixel {
r: acc[0] as u8,
g: acc[1] as u8,
b: acc[2] as u8,
a: pixel.a,
});
}
}
pixels.copy_from_slice(&out);
let output = env
.new_string("Applied Engrave effect!")
.expect("Couldn't create java string!");
return **output;
}
#[no_mangle]
pub extern "C" fn Java_ru_vtosters_lite_ui_wallpapers_NativeEffects_flea(
env: JNIEnv,
_: JClass,
bitmap_buffer: JByteBuffer,
) -> jstring {
let mut rng = rand::thread_rng();
let pixels = resolve_pixel_slice(&env, &bitmap_buffer);
for p in pixels {
p.set_color(
p.r | rng.gen::<u8>(),
p.g | rng.gen::<u8>(),
p.b | rng.gen::<u8>(),
)
}
let output = env
.new_string("Applied Flea effect!")
.expect("Couldn't create java string!");
return **output;
}
#[no_mangle]
pub extern "C" fn Java_ru_vtosters_lite_ui_wallpapers_NativeEffects_snow(
env: JNIEnv,
_: JClass,
bitmap_buffer: JByteBuffer,
) -> jstring {
let mut rng = rand::thread_rng();
let pixels = resolve_pixel_slice(&env, &bitmap_buffer);
for p in pixels {
let threshold: u8 = rng.gen();
if p.r > threshold && p.g > threshold && p.b > threshold {
p.set_color(255, 255, 255);
}
}
let output = env
.new_string("Applied Snow effect!")
.expect("Couldn't create java string!");
return **output;
}
#[no_mangle]
pub extern "C" fn Java_ru_vtosters_lite_ui_wallpapers_NativeEffects_gaussian(
env: JNIEnv,
_: JClass,
bitmap_buffer: JByteBuffer,
height: jint,
width: jint,
radius: jfloat,
) -> jstring {
let start = env
.get_direct_buffer_address(bitmap_buffer)
.expect("Unable to resolve DirectBuffer address");
let capacity = env
.get_direct_buffer_capacity(bitmap_buffer)
.expect("Unable to resolve DirectBuffer size");
let s = start as *mut u8;
let s = unsafe { std::slice::from_raw_parts_mut(s, capacity) };
let mut img = image::ImageBuffer::<image::Rgba<u8>, Vec<u8>>::from_raw(
width as u32,
height as u32,
s.to_vec(),
)
.unwrap();
let img = image::imageops::blur(&mut img, radius);
s.copy_from_slice(img.as_raw());
let output = env
.new_string("Applied Gaussian effect!")
.expect("Couldn't create java string!");
return **output;
}
#[no_mangle]
pub extern "C" fn Java_ru_vtosters_lite_ui_wallpapers_NativeEffects_dim(
env: JNIEnv,
_: JClass,
bitmap_buffer: JByteBuffer,
height: jint,
width: jint,
delta: jint,
) -> jstring {
let start = env
.get_direct_buffer_address(bitmap_buffer)
.expect("Unable to resolve DirectBuffer address");
let capacity = env
.get_direct_buffer_capacity(bitmap_buffer)
.expect("Unable to resolve DirectBuffer size");
let s = start as *mut u8;
let s = unsafe { std::slice::from_raw_parts_mut(s, capacity) };
let img = image::ImageBuffer::<image::Rgba<u8>, Vec<u8>>::from_raw(
width as u32,
height as u32,
s.to_vec(),
)
.unwrap();
let img = image::imageops::brighten(&img, delta);
s.copy_from_slice(img.as_raw());
let output = env
.new_string("Applied Dim effect!")
.expect("Couldn't create java string!");
return **output;
}
#[no_mangle]
pub extern "C" fn Java_ru_vtosters_lite_ui_wallpapers_NativeEffects_mosaic(
env: JNIEnv,
_: JClass,
bitmap_buffer: JByteBuffer,
height: jint,
width: jint,
scale: jint,
) -> jstring {
let start = env
.get_direct_buffer_address(bitmap_buffer)
.expect("Unable to resolve DirectBuffer address");
let capacity = env
.get_direct_buffer_capacity(bitmap_buffer)
.expect("Unable to resolve DirectBuffer size");
let s = start as *mut u8;
let s = unsafe { std::slice::from_raw_parts_mut(s, capacity) };
let mut img = image::ImageBuffer::<image::Rgba<u8>, Vec<u8>>::from_raw(
width as u32,
height as u32,
s.to_vec(),
)
.unwrap();
img = image::imageops::resize(
&img,
(width / scale) as u32,
(height / scale) as u32,
image::imageops::FilterType::Nearest,
);
img = image::imageops::resize(
&img,
width as u32,
height as u32,
image::imageops::FilterType::Nearest,
);
s.copy_from_slice(img.as_raw());
let output = env
.new_string("Applied Mosaic effect!")
.expect("Couldn't create java string!");
return **output;
}
+2 -1
View File
@@ -142,7 +142,7 @@
<application
android:name="com.vtosters.lite.VKApplication"
android:allowBackup="false"
android:allowBackup="true"
android:appComponentFactory="androidx.core.app.CoreComponentFactory"
android:debuggable="false"
android:hardwareAccelerated="true"
@@ -207,6 +207,7 @@
<intent-filter>
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.MULTIWINDOW_LAUNCHER" />
<action android:name="android.intent.action.APPLICATION_PREFERENCES" />
</intent-filter>
</activity>
<activity-alias
Binary file not shown.
Binary file not shown.
@@ -424,38 +424,38 @@
return v0
.end method
.method public final c()Ljava/lang/String;
.locals 3
# .method public final c()Ljava/lang/String;
# .locals 3
invoke-static {}, Lru/vtosters/lite/ui/wallpapers/WallpapersHooks;->getWallpaperUrl()Ljava/lang/String;
# invoke-static {}, Lru/vtosters/lite/ui/wallpapers/WallpapersHooks;->getWallpaperUrl()Ljava/lang/String;
move-result-object v0
# move-result-object v0
return-object v0
# return-object v0
.line 1
invoke-direct {p0}, Lcom/vk/im/ui/ImUiPrefs;->k()Landroid/content/SharedPreferences;
# .line 1
# invoke-direct {p0}, Lcom/vk/im/ui/ImUiPrefs;->k()Landroid/content/SharedPreferences;
move-result-object v0
# move-result-object v0
const-string v1, "pref_dialog_background_uri"
# const-string v1, "pref_dialog_background_uri"
const-string v2, "default"
# const-string v2, "default"
invoke-interface {v0, v1, v2}, Landroid/content/SharedPreferences;->getString(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
# invoke-interface {v0, v1, v2}, Landroid/content/SharedPreferences;->getString(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
move-result-object v0
# move-result-object v0
if-eqz v0, :cond_0
# if-eqz v0, :cond_0
goto :goto_0
# goto :goto_0
:cond_0
const-string v0, ""
# :cond_0
# const-string v0, ""
:goto_0
return-object v0
.end method
# :goto_0
# return-object v0
# .end method
.method public final d()J
.locals 4
@@ -772,180 +772,180 @@
return-void
.line 1
sget-object v0, Lcom/vk/im/ui/ImUiPrefs;->g:Lcom/vk/im/ui/ImUiPrefs;
# .line 1
# sget-object v0, Lcom/vk/im/ui/ImUiPrefs;->g:Lcom/vk/im/ui/ImUiPrefs;
invoke-virtual {v0}, Lcom/vk/im/ui/ImUiPrefs;->c()Ljava/lang/String;
# invoke-virtual {v0}, Lcom/vk/im/ui/ImUiPrefs;->c()Ljava/lang/String;
move-result-object v0
# move-result-object v0
.line 2
invoke-interface {v0}, Ljava/lang/CharSequence;->length()I
# .line 2
# invoke-interface {v0}, Ljava/lang/CharSequence;->length()I
move-result v1
# move-result v1
const/4 v2, 0x1
# const/4 v2, 0x1
const/4 v3, 0x0
# const/4 v3, 0x0
if-nez v1, :cond_0
# if-nez v1, :cond_0
const/4 v1, 0x1
# const/4 v1, 0x1
goto :goto_0
# goto :goto_0
:cond_0
const/4 v1, 0x0
# :cond_0
# const/4 v1, 0x0
:goto_0
const-string v4, "msgListComponent"
# :goto_0
# const-string v4, "msgListComponent"
const-string v5, "dialogBackgroundView"
# const-string v5, "dialogBackgroundView"
const/4 v6, 0x0
# const/4 v6, 0x0
if-nez v1, :cond_6
# if-nez v1, :cond_6
const-string v1, "default"
# const-string v1, "default"
invoke-static {v0, v1}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/Object;)Z
# invoke-static {v0, v1}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/Object;)Z
move-result v1
# move-result v1
if-nez v1, :cond_6
# if-nez v1, :cond_6
iget-object v1, p0, Lcom/vk/im/ui/fragments/ChatFragment;->E:Lcom/vk/im/engine/models/dialogs/DialogExt;
# iget-object v1, p0, Lcom/vk/im/ui/fragments/ChatFragment;->E:Lcom/vk/im/engine/models/dialogs/DialogExt;
if-eqz v1, :cond_5
# if-eqz v1, :cond_5
invoke-virtual {v1}, Lcom/vk/im/engine/models/dialogs/DialogExt;->t1()Lcom/vk/im/engine/models/dialogs/Dialog;
# invoke-virtual {v1}, Lcom/vk/im/engine/models/dialogs/DialogExt;->t1()Lcom/vk/im/engine/models/dialogs/Dialog;
move-result-object v1
# move-result-object v1
invoke-virtual {v1}, Lcom/vk/im/engine/models/dialogs/Dialog;->U1()Z
# invoke-virtual {v1}, Lcom/vk/im/engine/models/dialogs/Dialog;->U1()Z
move-result v1
# move-result v1
if-eqz v1, :cond_1
# if-eqz v1, :cond_1
goto :goto_1
# goto :goto_1
.line 3
:cond_1
iget-object v1, p0, Lcom/vk/im/ui/fragments/ChatFragment;->k0:Lcom/vk/im/ui/views/FrescoImageView;
# .line 3
# :cond_1
# iget-object v1, p0, Lcom/vk/im/ui/fragments/ChatFragment;->k0:Lcom/vk/im/ui/views/FrescoImageView;
if-eqz v1, :cond_4
# if-eqz v1, :cond_4
new-instance v3, Lcom/vk/im/engine/models/Image;
# new-instance v3, Lcom/vk/im/engine/models/Image;
invoke-direct {v3, v0}, Lcom/vk/im/engine/models/Image;-><init>(Ljava/lang/String;)V
# invoke-direct {v3, v0}, Lcom/vk/im/engine/models/Image;-><init>(Ljava/lang/String;)V
invoke-virtual {v1, v3}, Lcom/vk/im/ui/views/FrescoImageView;->setLocalImage(Lcom/vk/im/engine/models/Image;)V
# invoke-virtual {v1, v3}, Lcom/vk/im/ui/views/FrescoImageView;->setLocalImage(Lcom/vk/im/engine/models/Image;)V
.line 4
iget-object v0, p0, Lcom/vk/im/ui/fragments/ChatFragment;->k0:Lcom/vk/im/ui/views/FrescoImageView;
# .line 4
# iget-object v0, p0, Lcom/vk/im/ui/fragments/ChatFragment;->k0:Lcom/vk/im/ui/views/FrescoImageView;
if-eqz v0, :cond_3
# if-eqz v0, :cond_3
invoke-virtual {v0, v6}, Lcom/vk/im/ui/views/FrescoImageView;->setBackgroundImage(Landroid/graphics/drawable/Drawable;)V
# invoke-virtual {v0, v6}, Lcom/vk/im/ui/views/FrescoImageView;->setBackgroundImage(Landroid/graphics/drawable/Drawable;)V
.line 5
iget-object v0, p0, Lcom/vk/im/ui/fragments/ChatFragment;->d0:Lcom/vk/im/ui/components/msg_list/MsgListComponent;
# .line 5
# iget-object v0, p0, Lcom/vk/im/ui/fragments/ChatFragment;->d0:Lcom/vk/im/ui/components/msg_list/MsgListComponent;
if-eqz v0, :cond_2
# if-eqz v0, :cond_2
invoke-virtual {v0, v2}, Lcom/vk/im/ui/components/msg_list/MsgListComponent;->b(Z)V
# invoke-virtual {v0, v2}, Lcom/vk/im/ui/components/msg_list/MsgListComponent;->b(Z)V
goto :goto_2
# goto :goto_2
:cond_2
invoke-static {v4}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/String;)V
# :cond_2
# invoke-static {v4}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/String;)V
throw v6
# throw v6
.line 6
:cond_3
invoke-static {v5}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/String;)V
# .line 6
# :cond_3
# invoke-static {v5}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/String;)V
throw v6
# throw v6
.line 7
:cond_4
invoke-static {v5}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/String;)V
# .line 7
# :cond_4
# invoke-static {v5}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/String;)V
throw v6
# throw v6
:cond_5
const-string v0, "dialogExt"
# :cond_5
# const-string v0, "dialogExt"
.line 8
invoke-static {v0}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/String;)V
# .line 8
# invoke-static {v0}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/String;)V
throw v6
# throw v6
.line 9
:cond_6
:goto_1
iget-object v0, p0, Lcom/vk/im/ui/fragments/ChatFragment;->k0:Lcom/vk/im/ui/views/FrescoImageView;
# .line 9
# :cond_6
# :goto_1
# iget-object v0, p0, Lcom/vk/im/ui/fragments/ChatFragment;->k0:Lcom/vk/im/ui/views/FrescoImageView;
if-eqz v0, :cond_a
# if-eqz v0, :cond_a
invoke-virtual {v0, v6}, Lcom/vk/im/ui/views/FrescoImageView;->setLocalImage(Lcom/vk/im/engine/models/Image;)V
# invoke-virtual {v0, v6}, Lcom/vk/im/ui/views/FrescoImageView;->setLocalImage(Lcom/vk/im/engine/models/Image;)V
.line 10
iget-object v0, p0, Lcom/vk/im/ui/fragments/ChatFragment;->k0:Lcom/vk/im/ui/views/FrescoImageView;
# .line 10
# iget-object v0, p0, Lcom/vk/im/ui/fragments/ChatFragment;->k0:Lcom/vk/im/ui/views/FrescoImageView;
if-eqz v0, :cond_9
# if-eqz v0, :cond_9
new-instance v1, Landroid/graphics/drawable/ColorDrawable;
# new-instance v1, Landroid/graphics/drawable/ColorDrawable;
iget-object v2, p0, Lcom/vk/im/ui/fragments/ChatFragment;->L:Landroid/content/Context;
# iget-object v2, p0, Lcom/vk/im/ui/fragments/ChatFragment;->L:Landroid/content/Context;
if-eqz v2, :cond_8
# if-eqz v2, :cond_8
sget v5, Lcom/vk/im/ui/c;->im_bg_chat:I
# sget v5, Lcom/vk/im/ui/c;->im_bg_chat:I
invoke-static {v2, v5}, Lcom/vk/core/util/ContextExtKt;->h(Landroid/content/Context;I)I
# invoke-static {v2, v5}, Lcom/vk/core/util/ContextExtKt;->h(Landroid/content/Context;I)I
move-result v2
# move-result v2
invoke-direct {v1, v2}, Landroid/graphics/drawable/ColorDrawable;-><init>(I)V
# invoke-direct {v1, v2}, Landroid/graphics/drawable/ColorDrawable;-><init>(I)V
invoke-virtual {v0, v1}, Lcom/vk/im/ui/views/FrescoImageView;->setBackgroundImage(Landroid/graphics/drawable/Drawable;)V
# invoke-virtual {v0, v1}, Lcom/vk/im/ui/views/FrescoImageView;->setBackgroundImage(Landroid/graphics/drawable/Drawable;)V
.line 11
iget-object v0, p0, Lcom/vk/im/ui/fragments/ChatFragment;->d0:Lcom/vk/im/ui/components/msg_list/MsgListComponent;
# .line 11
# iget-object v0, p0, Lcom/vk/im/ui/fragments/ChatFragment;->d0:Lcom/vk/im/ui/components/msg_list/MsgListComponent;
if-eqz v0, :cond_7
# if-eqz v0, :cond_7
invoke-virtual {v0, v3}, Lcom/vk/im/ui/components/msg_list/MsgListComponent;->b(Z)V
# invoke-virtual {v0, v3}, Lcom/vk/im/ui/components/msg_list/MsgListComponent;->b(Z)V
:goto_2
return-void
# :goto_2
# return-void
:cond_7
invoke-static {v4}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/String;)V
# :cond_7
# invoke-static {v4}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/String;)V
throw v6
# throw v6
:cond_8
const-string v0, "themedContext"
# :cond_8
# const-string v0, "themedContext"
.line 12
invoke-static {v0}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/String;)V
# .line 12
# invoke-static {v0}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/String;)V
throw v6
# throw v6
:cond_9
invoke-static {v5}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/String;)V
# :cond_9
# invoke-static {v5}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/String;)V
throw v6
# throw v6
.line 13
:cond_a
invoke-static {v5}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/String;)V
# .line 13
# :cond_a
# invoke-static {v5}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/String;)V
throw v6
# throw v6
.end method
.method private final Y4()V