Merge branch 'vtl-remaster' into music

# Conflicts:
#	app/libs/classes-dex2jar.jar
#	app/libs/classes2-dex2jar.jar
#	app/libs/classes3-dex2jar.jar
#	app/libs/classes4-dex2jar.jar
#	app/libs/classes5-dex2jar.jar
#	app/src/main/java/ru/vtosters/lite/downloaders/notifications/NotificationChannels.java
#	app/src/main/java/ru/vtosters/lite/music/MP3Downloader.java
This commit is contained in:
aliveoutside
2022-08-19 13:54:46 +03:00
303 changed files with 6849 additions and 13711 deletions
+27
View File
@@ -0,0 +1,27 @@
---
name: Bug Report
about: Заготовка для репорта багов
title: Ошибка обновлении ленты новостей
labels: bug
assignees: ''
---
**Опишите сам баг**
При обновлении новостей вылезает ошибка
**Опишите действия для воспроизведения ошибки**
1. Обновил ленту интересных новостей
2. Пролистал до конца страницы
**Опишите ожидаемый результат**
Интересная лента должна прогружать результаты
**Скриншот ошибки**
**Информация об устройстве:**
- Устройство: Samsung Galaxy J1 Mini
- OS: Android 9 | OneUi 3.0
- Коммит: fa12e8f (В О Приложении написана версия коммита)
**Дополнительная информация о баге или мыслях почему оно может происходить (если есть)**
+15
View File
@@ -0,0 +1,15 @@
---
name: Feature request
about: Предложение функции
title: Улучшение голосовых сообщений
labels: enhancement
assignees: ''
---
**Опишите вашу идею максимально подробно и понятно**
Необходима функция улучшения голосовых сообщений. Она значительно улучшит запись голосовых сообщений и собеседнику будет лучше слышно меня
**Опишите возможное решение/реализацию функции (если понимаете как это можно реализовать на Java/C++)**
**Остальные мысли о предложенной функции**
+5 -1
View File
@@ -66,6 +66,7 @@
* Округление чисел
* Сокращение постов **(Показать полностью)**
* Результаты опросов без участия
* Возможность указывать папку для загрузки фото/видео/музыки/всего
* Интеграция с <a href="https://www.last.fm/">LAST.FM</a> (а также возможность скробблинга)
* Новый раздел музыки
* Возможность скачивать видео
@@ -90,6 +91,7 @@
* Возможность видеть онлайн пользователей, если у вас скрыт онлайн через VK Messenger
* Отключить уведомление о том, что вы сделали скриншот в беседе
* Отключение редиректа через away.php
* Отключение отправки метрики
* Внешний вид
* **Milkshake** тема (дизайн новых версий ВК)
* Название заголовков в докбаре
@@ -103,8 +105,10 @@
* Возможность отключить блок историй наверху ленты
* Возможность отключить боковую камеру в разделе «Новости»
* Возможность отключить блок «Что у вас нового?» в разделе «Новости»
* Возможность менять раздел, который запускается при запуске
* Возможность показывать лайки у постов справа
* Возможность менять стартовый раздел при запуске приложения
* Анимации фрагментов
* Возможность изменять размер закругления картинок (аватарок и прочего)
* Возможность отключить редизайн видеопостов
* Возможность отключить блок миниаппов/VK Pay/Superapp
* Возможность отключить сокращение названий разделов в меню
+2 -4
View File
@@ -73,12 +73,11 @@ android {
defaultConfig {
applicationId "ru.vtosters.lite.utils.lite"
minSdkVersion 21
minSdk 22
targetSdkVersion 32
versionCode 1
versionName "1.0"
multiDexEnabled true
multiDexEnabled false
}
compileOptions {
@@ -89,7 +88,6 @@ android {
}
dependencies {
implementation "androidx.multidex:multidex:2.0.1"
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.exifinterface:exifinterface:1.3.3'
implementation 'androidx.preference:preference:1.2.0'
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -16,6 +16,7 @@ import com.aefyr.tsg.g2.stickersgrabber.TelegramStickersGrabber;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicLong;
import ru.vtosters.lite.utils.AndroidUtils;
/**
* Created by Aefyr on 20.05.2018.
@@ -39,7 +40,7 @@ public class NotificationsHelper {
downloadingPacksNotificationsIds = new HashMap<>();
if (oreo()) {
NotificationChannel notificationChan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "Сервис стикеров Telegram в VTosters", NotificationManager.IMPORTANCE_HIGH);
NotificationChannel notificationChan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, AndroidUtils.getString("telegram_stickers_service"), NotificationManager.IMPORTANCE_HIGH);
((NotificationManager) c.getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(notificationChan);
}
}
@@ -49,8 +50,8 @@ public class NotificationsHelper {
downloadingPacksNotificationsIds.put(pack, notificationId);
Notification.Builder builder = commonBuilder();
builder.setContentTitle(pack.state == TelegramStickersPack.DOWNLOADING ? pack.title + ": загрузка" : pack.title + ": обновление");
builder.setContentText("Получение информации");
builder.setContentTitle(pack.state == TelegramStickersPack.DOWNLOADING ? pack.title + AndroidUtils.getString("telegram_stickers_downloading") : pack.title + AndroidUtils.getString("telegram_stickers_updating"));
builder.setContentText(AndroidUtils.getString("telegram_stickers_gettinginfo"));
builder.setOngoing(true);
manager.notify(notificationId, builder.build());
@@ -63,7 +64,7 @@ public class NotificationsHelper {
lastNotificationTime.set(System.currentTimeMillis());
Notification.Builder builder = commonBuilder();
builder.setContentTitle(pack.state == TelegramStickersPack.DOWNLOADING ? pack.title + ": загрузка" : pack.title + ": обновление");
builder.setContentTitle(pack.state == TelegramStickersPack.DOWNLOADING ? pack.title + AndroidUtils.getString("telegram_stickers_downloading") : pack.title + AndroidUtils.getString("telegram_stickers_updating"));
builder.setContentText(downloadProgress + "/" + pack.stickersCount);
builder.setProgress(pack.stickersCount, downloadProgress, false);
builder.setOngoing(true);
@@ -77,13 +78,13 @@ public class NotificationsHelper {
Notification.Builder builder = commonBuilder();
builder.setProgress(0, 0, false);
builder.setOngoing(false);
builder.setContentTitle("Сервис стикеров Telegram в VTosters");
builder.setContentTitle(AndroidUtils.getString("telegram_stickers_service"));
String text;
if (success)
text = wasUpdate ? pack.title + " успешно обновлен" : pack.title + " успешно загружен";
text = wasUpdate ? pack.title + AndroidUtils.getString("telegram_stickers_updated") : pack.title + AndroidUtils.getString("telegram_stickers_downloaded");
else
text = wasUpdate ? pack.title + ": ошибка при обновлении" : pack.title + ": ошибка при загрузке";
text = wasUpdate ? pack.title + AndroidUtils.getString("telegram_stickers_error_update") : pack.title + AndroidUtils.getString("telegram_stickers_error_download");
if (e instanceof TelegramStickersGrabber.TSGException) {
text = pack.title + ": " + e.getMessage();
@@ -0,0 +1,35 @@
package com.vk.api.gifts;
import android.content.Context;
import com.vk.api.base.ApiRequest;
import com.vk.dto.gift.CatalogedGift;
import org.json.JSONException;
import org.json.JSONObject;
public class GiftGetByStickerId extends ApiRequest<GiftGetByStickerId.a> {
public static class a {
public final int a;
public final CatalogedGift b;
public a(int i, CatalogedGift catalogedGift) {
this.a = i;
this.b = catalogedGift;
}
}
public GiftGetByStickerId(Context context, int i) {
super("execute.getGiftByStickerId");
b("sticker_id", i);
c("no_inapp", "0");
b("force_payment", 1);
}
@Override // com.vk.api.sdk.o.VKRequest
public GiftGetByStickerId.a a(JSONObject jSONObject) throws JSONException {
JSONObject jSONObject2 = jSONObject.getJSONObject("response");
return new a(jSONObject2.optInt("balance"),
new CatalogedGift(jSONObject2.getJSONObject("gift")));
}
}
@@ -0,0 +1,225 @@
package com.vk.core.util;
import static ru.vtosters.lite.utils.Preferences.getDownloadsDir;
import static ru.vtosters.lite.utils.Preferences.getMusicDir;
import static ru.vtosters.lite.utils.Preferences.getPhotosDir;
import static ru.vtosters.lite.utils.Preferences.getVideosDir;
import android.annotation.SuppressLint;
import android.app.DownloadManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import com.facebook.common.i.MediaUtils;
import com.facebook.x.g.EncodedImage;
import com.vk.core.concurrent.VkExecutors;
import com.vk.imageloader.VKImageLoader;
import com.vk.log.L;
import com.vk.metrics.eventtracking.VkTracker;
import com.vtosters.lite.R;
import java.io.File;
import java.io.InputStream;
import java.net.URI;
import java.util.HashSet;
import b.h.g.m.CameraUtils;
import b.h.g.m.FileUtils;
public class DownloadUtils {
public static final HashSet<Long> a = new HashSet<>();
public static void a(Context context, String str, String str2) {
a(context, str, str2, false);
}
public static void b(Context context, String str, String str2) {
a(context, str, str2, true);
}
private static void a(Context context, String str, String str2, boolean z) {
try {
b(context, str, str2, z);
} catch (Exception e2) {
L.d(e2);
ToastUtils.a(context.getString(R.string.error) + " [" + e2.getMessage() + "]");
}
}
private static void b(final Context context, String str, String str2, boolean z) {
if (TextUtils.isEmpty(str2)) {
return;
}
String file = a(str, str2);
File b2;
boolean c2 = MediaUtils.c(MediaUtils.b(str2));
if (file.endsWith(".jpg") || file.endsWith(".png") || file.endsWith(".jpeg")) {
b2 = new File(getPhotosDir(), file);
} else if (file.endsWith(".mp3") || file.endsWith(".wav") || file.endsWith(".ogg") || file.endsWith(".aac") || file.endsWith(".flac") || file.endsWith(".m4a")) {
b2 = new File(getMusicDir(), file);
} else if (file.endsWith(".mp4") || file.endsWith(".mkv") || file.endsWith(".avi") || file.endsWith(".flv") || file.endsWith(".wmv") || file.endsWith(".mov") || file.endsWith(".3gp")) {
b2 = new File(getVideosDir(), file);
} else {
b2 = new File(getDownloadsDir(), file);
}
if (c2) {
EncodedImage c3 = VKImageLoader.c(Uri.parse(str2));
final InputStream h = c3 == null ? null : c3.h();
if (h != null) {
try {
if (b2.getParentFile() != null) {
b2.createNewFile();
}
if (b2.exists()) {
VkExecutors.x.a().execute(() -> ToastUtils.a(context.getString(R.string.file_saved, b2.getAbsoluteFile())));
}
} catch (Exception e2) {
L.a(e2);
}
CameraUtils.a(context, b2, null);
return;
}
}
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(str2));
request.setDestinationUri(Uri.fromFile(b2));
request.setMimeType(FileUtils.f(new File(str)));
request.setNotificationVisibility(1);
request.allowScanningByMediaScanner();
request.setTitle(str);
DownloadManager a2 = a(context);
if (a2 == null) {
return;
}
try {
long enqueue = a2.enqueue(request);
if (!z) {
return;
}
a.add(enqueue);
} catch (IllegalArgumentException e3) {
L.a(e3);
b(context);
}
}
private static String a(String str, String str2) {
String lastPathSegment = Uri.parse(str2).getLastPathSegment();
if (!TextUtils.isEmpty(str)) {
String replace = str.replace('/', '_');
return !replace.contains(".") ? lastPathSegment : replace;
}
return lastPathSegment;
}
@SuppressLint("Range")
public static boolean a(Context context, Uri uri) {
try {
Cursor query = a(context).query(new DownloadManager.Query().setFilterByStatus(11));
if (query != null && query.moveToFirst()) {
while (!uri.toString().equals(query.getString(query.getColumnIndex("uri")))) {
if (!query.moveToNext()) {
query.close();
return false;
}
}
@SuppressLint("Range")
int i = query.getInt(query.getColumnIndex("status"));
@SuppressLint("Range")
String string = query.getString(query.getColumnIndex("local_uri"));
query.close();
if (i == 1 || i == 2) {
ToastUtils.a(R.string.download_is_in_progress);
query.close();
return true;
} else if (i != 8) {
query.close();
return false;
} else {
boolean a2 = a(context, string);
query.close();
return a2;
}
}
return false;
} catch (SQLiteException e2) {
VkTracker.k.b(e2);
return false;
}
}
private static void b(Context context) {
if (context != null) {
try {
context.startActivity(new Intent("android.settings.APPLICATION_DETAILS_SETTINGS").setData(Uri.parse("package:com.android.providers.downloads")));
} catch (ActivityNotFoundException e2) {
L.a(e2);
context.startActivity(new Intent("android.settings.MANAGE_APPLICATIONS_SETTINGS"));
}
ToastUtils.a("Please enable download manager", true);
}
}
public static boolean a(Context context, String str) {
File file;
try {
try {
file = new File(new URI(str));
try {
if (!file.exists()) {
return false;
}
Intent intent = new Intent("android.intent.action.VIEW");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
String f2 = FileUtils.f(file);
if (!TextUtils.isEmpty(f2)) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(FileUtils.uriFromFile(file), f2);
context.startActivity(intent);
return true;
}
throw new ActivityNotFoundException();
} catch (ActivityNotFoundException unused) {
return a(context, file);
}
} catch (ActivityNotFoundException unused2) {
unused2.printStackTrace();
}
} catch (Throwable th) {
VkTracker.k.b(th);
return false;
}
return false;
}
private static boolean a(Context context, File file) {
if (file != null && file.exists()) {
Intent intent = new Intent("android.intent.action.VIEW");
intent.setDataAndType(Uri.parse(file.getAbsolutePath()), "application/*");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(intent);
return true;
} catch (ActivityNotFoundException e2) {
L.a(e2);
}
}
return false;
}
private static DownloadManager a(Context context) {
return (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
}
}
@@ -34,4 +34,6 @@ public enum DialogAction {
DNT_OFF,
pinmsg,
unpinmsg,
ENCRYPT_SETT,
ENCRYPT
}
@@ -81,6 +81,7 @@ public final class DialogActionsHelper {
CollectionExt.a(arrayList, DialogAction.NOTIFICATIONS_OFF, dialog.b(b2));
return arrayList;
}
return new ArrayList<>();
}
@@ -98,9 +99,9 @@ public final class DialogActionsHelper {
DNRInjector.inject(dialog, arrayList);
if (dialog.hasUnread()) {
arrayList.add(DialogAction.MARK_AS_READ);
}
// if (dialog.hasUnread()) {
arrayList.add(DialogAction.MARK_AS_READ);
// }
if (!dialog.W1()) {
arrayList.add(DialogAction.CREATE_SHORTCUT);
@@ -10,5 +10,6 @@ public enum MsgAction {
SPAM,
PIN,
UNPIN,
TRANSLATE
TRANSLATE,
READTO
}
@@ -33,6 +33,7 @@ public final class MsgActionHelper {
CollectionExt.a(arrayList, MsgAction.PIN, MsgPermissionHelper.b.e(aVar));
CollectionExt.a(arrayList, MsgAction.UNPIN, MsgPermissionHelper.b.i(aVar));
CollectionExt.a(arrayList, MsgAction.TRANSLATE, true);
CollectionExt.a(arrayList, MsgAction.READTO, true);
return arrayList;
}
@@ -0,0 +1,131 @@
package com.vk.im.ui.views;
import androidx.annotation.NonNull;
public class Corners{
private int topLeft;
private int topRight;
private int bottomLeft;
private int bottomRight;
public Corners(int i, int i2, int i3, int i4){
this.topLeft = i;
this.topRight = i2;
this.bottomLeft = i3;
this.bottomRight = i4;
}
public Corners(int i, int i2, int i3, int i4, int i5) {
this((i5 & 1) != 0 ? 0 : i, (i5 & 2) != 0 ? 0 : i2, (i5 & 4) != 0 ? 0 : i3, (i5 & 8) != 0 ? 0 : i4);
}
public Corners() {
this(0, 0, 0, 0, 15);
}
public static Corners a(Corners corners, int i, int i2, int i3, int i4, int i5, Object obj){
if ((i5 & 1) != 0) {
i = corners.topLeft;
}
if ((i5 & 2) != 0) {
i2 = corners.topRight;
}
if ((i5 & 4) != 0) {
i3 = corners.bottomLeft;
}
if ((i5 & 8) != 0) {
i4 = corners.bottomRight;
}
corners.a(i, i2, i3, i4);
return corners;
}
public int a(){
return this.bottomLeft;
}
public int b(){
return this.bottomRight;
}
public int c(){
return this.topLeft;
}
public int d(){
return this.topRight;
}
public boolean e(){
int i;
int i2 = this.topLeft;
int i3 = this.topRight;
return i2 == i3 && i3 == (i = this.bottomRight) && this.bottomLeft == i;
}
public boolean equals(Object obj){
if (this != obj) {
if (!(obj instanceof Corners)) {
return false;
}
Corners corners = (Corners) obj;
return this.topLeft == corners.topLeft && this.topRight == corners.topRight && this.bottomLeft == corners.bottomLeft && this.bottomRight == corners.bottomRight;
}
return true;
}
public boolean f(){
return this.topLeft == 0 && e();
}
public void g(){
a(0, 0);
}
public int hashCode(){
return (((((this.topLeft * 31) + this.topRight) * 31) + this.bottomLeft) * 31) + this.bottomRight;
}
@NonNull
public String toString(){
return "Corners(topLeft=" + this.topLeft + ", topRight=" + this.topRight + ", bottomLeft=" + this.bottomLeft + ", bottomRight=" + this.bottomRight + ")";
}
public Corners a(int i, int i2){
if ((i2 & 1) > 0) {
this.topLeft = i;
}
if ((i2 & 2) > 0) {
this.topRight = i;
}
if ((i2 & 4) > 0) {
this.bottomLeft = i;
}
if ((i2 & 8) > 0) {
this.bottomRight = i;
}
if (i2 == 0) {
this.topLeft = 0;
this.topRight = 0;
this.bottomLeft = 0;
this.bottomRight = 0;
}
return this;
}
public Corners a(int i, int i2, int i3, int i4){
this.topLeft = i;
this.topRight = i2;
this.bottomLeft = i3;
this.bottomRight = i4;
return this;
}
public Corners a(Corners corners){
this.topLeft = corners.topLeft;
this.topRight = corners.topRight;
this.bottomLeft = corners.bottomLeft;
this.bottomRight = corners.bottomRight;
return this;
}
}
@@ -0,0 +1,137 @@
package com.vk.im.ui.views.avatars;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import com.vk.im.ui.o;
public class StoryBorderView extends View {
private boolean B;
private final Paint a;
private LinearGradient f15747b;
private int f15748c;
private int f15749d;
private int f15750e;
private int f15751f;
private final int g;
private final int h;
public StoryBorderView(Context context) {
this(context, null, 0, 6);
}
public StoryBorderView(Context context, AttributeSet attributeSet) {
this(context, attributeSet, 0, 4);
}
public StoryBorderView(Context context, AttributeSet attributeSet, int i, int i2) {
this(context, (i2 & 2) != 0 ? null : attributeSet, (i2 & 4) != 0 ? 0 : i);
}
public int getBorderColor() {
return this.f15749d;
}
public int getBorderGradientEndColor() {
return this.h;
}
public int getBorderGradientStartColor() {
return this.g;
}
public int getBorderWidth() {
return this.f15750e;
}
public int getPadding() {
return this.f15751f;
}
public int getViewSize() {
return this.f15748c;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawOval(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(), getHeight() - getPaddingBottom(), this.a);
}
@Override
protected void onMeasure(int i, int i2) {
int i3 = this.f15748c;
setMeasuredDimension(i3, i3);
}
public void setBorderColor(int i) {
if (this.f15749d != i) {
this.f15749d = i;
this.a.setColor(i);
invalidate();
}
}
public void setBorderWidth(int i) {
if (this.f15750e != i) {
this.f15750e = i;
this.a.setStrokeWidth(i);
invalidate();
}
}
@Override
public void setLayoutParams(ViewGroup.LayoutParams layoutParams) {
super.setLayoutParams(layoutParams);
boolean z = false;
this.f15748c = Math.min(layoutParams != null ? layoutParams.width : 0, layoutParams != null ? layoutParams.height : 0);
this.f15747b = new LinearGradient(0.0f, 0.0f, 0.0f, this.f15748c, this.g, this.h, Shader.TileMode.MIRROR);
if (this.f15748c > 0) {
z = true;
}
if (z) {
return;
}
throw new IllegalArgumentException("Only exact size supported, specify avatar sizes in layout params");
}
public void setLive(boolean z) {
if (this.B != z) {
this.a.setShader(z ? this.f15747b : null);
this.a.setColor(z ? -1 : this.f15749d);
this.B = z;
invalidate();
}
}
public void setPadding(int i) {
if (this.f15751f != i) {
this.f15751f = i;
setPadding(i, i, i, i);
}
}
public void setViewSize(int i) {
this.f15748c = i;
}
public StoryBorderView(Context context, AttributeSet attributeSet, int i) {
super(context, attributeSet, i);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
this.a = paint;
TypedArray obtainStyledAttributes = context.obtainStyledAttributes(attributeSet, o.StoryBorderView);
setBorderColor(obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderColor, 0));
this.g = obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderGradientStartColor, 0);
this.h = obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderGradientEndColor, 0);
setBorderWidth(obtainStyledAttributes.getDimensionPixelSize(o.StoryBorderView_vkim_borderWidth, 0));
obtainStyledAttributes.recycle();
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,106 @@
package com.vk.profile.ui.community;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.util.AttributeSet;
import com.vk.core.ui.themes.Themable;
import com.vk.core.ui.themes.VKThemeHelper;
import com.vk.core.util.ContextExtKt;
import com.vk.dto.stories.model.StoriesContainer;
import com.vk.stories.view.BorderedCircleImageView;
import com.vtosters.lite.R;
public final class CommunityBorderedImageView extends BorderedCircleImageView implements Themable{
private boolean f0;
private int g0;
private int h0;
private PorterDuffColorFilter i0;
private PorterDuffColorFilter j0;
private int unread;
private int read;
public CommunityBorderedImageView(Context context){
this(context, null, 0, 6);
}
public CommunityBorderedImageView(Context context, AttributeSet attributeSet){
this(context, attributeSet, 0, 4);
}
public CommunityBorderedImageView(Context context, AttributeSet attributeSet, int i, int i2){
this(context, (i2 & 2) != 0 ? null : attributeSet, (i2 & 4) != 0 ? 0 : i);
}
public CommunityBorderedImageView(Context context, AttributeSet attributeSet, int i){
super(context, attributeSet, i);
this.g0 = VKThemeHelper.d((int) R.attr.accent);
this.h0 = ContextExtKt.a(context, (int) R.color.gray_200);
this.i0 = new PorterDuffColorFilter(this.g0, PorterDuff.Mode.SRC_IN);
this.j0 = new PorterDuffColorFilter(this.h0, PorterDuff.Mode.SRC_IN);
}
public final void c(int unread, int read){ // get unread and read resid
this.unread = unread;
this.read = read;
this.T = BitmapFactory.decodeResource(getResources(), this.unread);
}
public final int getPrimaryColor(){
return this.g0;
}
public final void setPrimaryColor(int i){
this.g0 = i;
this.i0 = new PorterDuffColorFilter(i, PorterDuff.Mode.SRC_IN);
}
public final int getWasViewedColor(){
return this.h0;
}
public final void setWasViewedColor(int i){
this.h0 = i;
this.j0 = new PorterDuffColorFilter(i, PorterDuff.Mode.SRC_IN);
}
public final void o(){
this.f0 = false;
l();
}
@Override // com.vk.stories.view.ClippedImageView, android.widget.ImageView, android.view.View
public void onDraw(Canvas canvas){
super.onDraw(canvas);
if (this.f0) {
a(canvas);
}
}
public final void setStoryContainer(StoriesContainer storiesContainer){
if (storiesContainer.L1()) {
this.f0 = true;
m();
if (storiesContainer.K1()) {
this.T = BitmapFactory.decodeResource(getResources(), this.unread);
setBorderColorFilter(this.i0);
b(getWidth(), getHeight());
invalidate();
return;
}
this.T = BitmapFactory.decodeResource(getResources(), this.read);
setBorderColorFilter(this.j0);
b(getWidth(), getHeight());
invalidate();
return;
}
o();
}
@Override // com.vk.core.ui.themes.Themable
public void v(){
}
}
@@ -0,0 +1,304 @@
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;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.AttributeSet;
import androidx.annotation.UiThread;
import androidx.core.content.ContextCompat;
import com.facebook.drawee.drawable.ScalingUtils;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.view.DraweeHolder;
import com.vk.core.util.ContextExtKt;
import com.vk.core.util.Screen;
import com.vk.im.ui.views.avatars.AbbreviationAvatarDrawable;
import com.vk.imageloader.view.VKMultiImageView;
import com.vk.navigation.NavigatorKeys;
import com.vtosters.lite.R;
import com.vtosters.lite.a0;
import java.util.Arrays;
import ru.vtosters.lite.utils.AndroidUtils;
@UiThread
public class TargetImageView extends VKMultiImageView {
private static final int I = Screen.a(2);
private final int B;
private final int C;
private Drawable D;
private String[] F;
private int G;
private final RectF f21629d;
private final Paint f21630e;
private Canvas f21631f;
private final RectF g;
private final Paint h;
public TargetImageView(Context context, Drawable d) {
this(context, null, 0, 6);
}
public TargetImageView(Context context, AttributeSet attributeSet) {
this(context, attributeSet, 0, 4);
}
public TargetImageView(Context context, AttributeSet attributeSet, int i, int i2) {
this(context, (i2 & 2) != 0 ? null : attributeSet, (i2 & 4) != 0 ? 0 : i);
}
private void e() {
int i = this.G;
for (int i2 = 0; i2 < i; i2++) {
a(i2, this.F[i2]);
}
}
private void f() {
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int width = (getWidth() - paddingLeft) - getPaddingRight();
int height = (getHeight() - paddingTop) - getPaddingBottom();
int i = width / 2;
int i2 = height / 2;
int i3 = this.G;
if (i3 == 1) {
DraweeHolder<GenericDraweeHierarchy> a2 = this.a.a(0);
Drawable d2 = a2.d();
if (d2 != null) {
d2.setBounds(paddingLeft, paddingTop, width + paddingLeft, height + paddingTop);
}
} else if (i3 == 2) {
DraweeHolder<GenericDraweeHierarchy> a3 = this.a.a(0);
Drawable d3 = a3.d();
if (d3 != null) {
int i4 = i + paddingLeft;
int i5 = height + paddingTop;
d3.setBounds(paddingLeft, paddingTop, i4, i5);
DraweeHolder<GenericDraweeHierarchy> a4 = this.a.a(1);
Drawable d4 = a4.d();
if (d4 != null) {
d4.setBounds(i4, paddingTop, paddingLeft + width, i5);
}
}
} else if (i3 == 3) {
DraweeHolder<GenericDraweeHierarchy> a5 = this.a.a(0);
Drawable d5 = a5.d();
if (d5 != null) {
int i6 = i + paddingLeft;
int i7 = height + paddingTop;
d5.setBounds(paddingLeft, paddingTop, i6, i7);
DraweeHolder<GenericDraweeHierarchy> a6 = this.a.a(1);
Drawable d6 = a6.d();
if (d6 != null) {
int i9 = paddingLeft + width;
int i10 = i2 + paddingTop;
d6.setBounds(i6, paddingTop, i9, i10);
DraweeHolder<GenericDraweeHierarchy> a7 = this.a.a(2);
Drawable d7 = a7.d();
if (d7 != null) {
d7.setBounds(i6, i10, i9, i7);
}
}
}
} else {
DraweeHolder<GenericDraweeHierarchy> a8 = this.a.a(0);
Drawable d8 = a8.d();
if (d8 != null) {
int i11 = i + paddingLeft;
int i13 = i2 + paddingTop;
d8.setBounds(paddingLeft, paddingTop, i11, i13);
DraweeHolder<GenericDraweeHierarchy> a9 = this.a.a(1);
Drawable d9 = a9.d();
if (d9 != null) {
int i16 = height + paddingTop;
d9.setBounds(paddingLeft, i13, i11, i16);
DraweeHolder<GenericDraweeHierarchy> a10 = this.a.a(2);
Drawable d10 = a10.d();
if (d10 != null) {
int i18 = paddingLeft + width;
d10.setBounds(i11, paddingTop, i18, i13);
DraweeHolder<GenericDraweeHierarchy> a11 = this.a.a(3);
Drawable d11 = a11.d();
if (d11 != null) {
d11.setBounds(i11, i13, i18, i16);
}
}
}
}
}
}
private void g() {
if (getWidth() == 0 || getHeight() == 0) {
return;
}
f();
}
private AbbreviationAvatarDrawable getAbbreviationDrawable() {
return a(getContext(), null, 2);
}
private AbbreviationAvatarDrawable a(Context context, Typeface typeface, int i) {
return new AbbreviationAvatarDrawable(context, (i & 2) != 0 ? ContextExtKt.e(context, roboto_medium) : typeface);
}
public void a(String str) {
Arrays.fill(this.F, null);
if (str == null) {
b();
this.G = 1;
g();
e();
return;
}
Uri uri = Uri.parse(str);
if (uri.getScheme().equals("vkchatphoto")) {
this.G = 0;
while (true) {
String queryParameter = uri.getQueryParameter("photo" + this.G);
if (queryParameter != null) {
int i = this.G;
this.G = i + 1;
this.F[i] = queryParameter;
} else {
g();
e();
return;
}
}
} else if (uri.getScheme().equals("vkchatplaceholder")) {
this.G = 1;
g();
AbbreviationAvatarDrawable abbreviationDrawable = getAbbreviationDrawable();
String queryParameter2 = uri.getQueryParameter(NavigatorKeys.Q);
int parseInt = queryParameter2 != null ? Integer.parseInt(queryParameter2) : 0;
String queryParameter3 = uri.getQueryParameter(NavigatorKeys.d);
if (queryParameter3 == null) {
queryParameter3 = "";
}
abbreviationDrawable.a(parseInt, queryParameter3);
a(0, getAbbreviationDrawable());
} else {
this.F[0] = str;
this.G = 1;
g();
e();
}
}
@Override // android.view.View
protected void onDraw(Canvas canvas) {
Canvas canvas2 = this.f21631f;
int pref = preferences.getInt("pic_rounding", 0);
if (canvas2 != null) {
canvas2.drawColor(0, PorterDuff.Mode.CLEAR);
}
int i = this.G;
for (int i2 = 0; i2 < i; i2++) {
DraweeHolder<GenericDraweeHierarchy> a2 = this.a.a(i2);
Drawable d2 = a2.d();
if (d2 != null) {
Canvas canvas3 = this.f21631f;
d2.draw(canvas3);
}
}
if (pref > 0) {
canvas.drawRoundRect(this.f21629d, pref, pref, this.f21630e);
} else {
canvas.drawOval(this.f21629d, this.f21630e);
}
if (isSelected()) {
if (pref > 0) {
canvas.drawRoundRect(this.g.left, this.g.top, this.g.right, this.g.bottom, pref, pref, this.h);
} else {
canvas.drawCircle(this.g.centerX(), this.g.centerY(), this.g.width() / 2, this.h);
}
this.D.draw(canvas);
}
}
@Override // android.view.View
protected void onSizeChanged(int i, int i2, int i3, int i4) {
super.onSizeChanged(i, i2, i3, i4);
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
int paddingTop = getPaddingTop();
int i5 = i - paddingRight;
int paddingBottom = i2 - getPaddingBottom();
this.f21629d.set(paddingLeft, paddingTop, i5, paddingBottom);
Bitmap createBitmap = Bitmap.createBitmap(i5, paddingBottom, Bitmap.Config.ARGB_8888);
this.f21631f = new Canvas(createBitmap);
Shader.TileMode tileMode = Shader.TileMode.CLAMP;
this.f21630e.setShader(new BitmapShader(createBitmap, tileMode, tileMode));
float f2 = I / 2;
this.g.set(f2, f2, i - f2, (float) i2 - f2);
float f4 = i / 2;
this.h.setShader(new LinearGradient(f4, 0.0f, f4, (float) i2, this.B, this.C, Shader.TileMode.CLAMP));
Drawable drawable = this.D;
drawable.setBounds(i - drawable.getIntrinsicWidth(), i2 - this.D.getIntrinsicHeight(), i, i2);
f();
}
public TargetImageView(Context context, AttributeSet attributeSet, int i) {
super(context, attributeSet, i);
this.f21629d = new RectF();
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
paint.setFilterBitmap(true);
this.f21630e = paint;
this.g = new RectF();
Paint paint2 = new Paint();
paint2.setAntiAlias(true);
paint2.setStrokeWidth(I);
paint2.setStyle(Paint.Style.STROKE);
this.h = paint2;
this.B = getAccentColor();
this.C = this.B;
Drawable c2 = ContextExtKt.c(context, R.drawable.ic_check_circle_composite_24_full);
if (c2 != null) {
this.D = c2;
this.F = new String[4];
int i2 = I * 2;
setPadding(i2, i2, i2, i2);
if (attributeSet != null) {
TypedArray obtainStyledAttributes = context.obtainStyledAttributes(attributeSet, a0.TargetImageView);
setSelected(obtainStyledAttributes.getBoolean(0, false));
obtainStyledAttributes.recycle();
}
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.user_placeholder);
for (int i3 = 0; i3 <= 3; i3++) {
a();
DraweeHolder<GenericDraweeHierarchy> a3 = this.a.a(i3);
a3.b().e(drawable);
}
setScaleType(ScalingUtils.b.o);
}
}
}
@@ -0,0 +1,447 @@
package com.vk.stories.view;
import static ru.vtosters.lite.utils.ThemesUtils.getColor2;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.AttributeSet;
import android.view.ViewTreeObserver;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.LottieCompositionFactory;
import com.airbnb.lottie.LottieDrawable;
import com.airbnb.lottie.LottieListener;
import com.facebook.common.internal.Supplier;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.DataSource;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import com.facebook.u.b.a.PipelineDraweeControllerBuilder;
import com.facebook.x.g.CloseableImage;
import com.vk.core.drawable.BorderDrawable;
import com.vk.core.ui.themes.Themable;
import com.vk.core.ui.themes.VKThemeHelper;
import com.vk.core.util.DrawableUtils;
import com.vk.core.util.ResUtils;
import com.vk.core.util.Screen;
import com.vk.dto.stories.d.StoriesContainerExt;
import com.vk.dto.stories.model.CommunityGroupedStoriesContainer;
import com.vk.dto.stories.model.StoriesContainer;
import com.vk.dto.stories.model.StoryEntry;
import com.vk.im.engine.models.Image;
import com.vk.im.ui.views.avatars.AvatarDataSource;
import com.vk.imageloader.FrescoWrapper;
import com.vk.stories.StoriesController;
import com.vtosters.lite.R;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import ru.vtosters.lite.utils.AndroidUtils;
public class StoryCircleImageView extends BorderedCircleImageView implements Themable{
private static final HashSet<Integer> B0 = new HashSet<>();
private final PipelineDraweeControllerBuilder f0;
private int A0;
private Drawable g0;
private Drawable h0;
private Drawable i0;
private int j0;
private int k0;
private int l0;
private int m0;
private int n0;
private int o0;
private Bitmap p0;
private Bitmap q0;
private Bitmap r0;
private Bitmap s0;
private boolean t0;
private boolean u0;
private boolean v0;
private boolean w0;
private boolean x0;
private String y0;
private LottieDrawable z0;
public StoryCircleImageView(Context context){
this(context, null);
}
public StoryCircleImageView(Context context, AttributeSet attributeSet){
this(context, attributeSet, 0);
}
public StoryCircleImageView(Context context, AttributeSet attributeSet, int i){
super(context, attributeSet, i);
this.f0 = FrescoWrapper.c.d();
a(context, attributeSet, i);
}
private void b(Canvas canvas){
this.z0.draw(canvas);
}
private boolean o(){
return !this.u0 && !this.t0 && this.z0 == null && !this.w0 && !this.v0;
}
private void p(){
this.z0.stop();
this.z0 = null;
invalidate();
}
private void q(){
int i = this.j0;
if (i != 0 && VKThemeHelper.k.a(i)) {
this.k0 = VKThemeHelper.d(this.j0);
}
this.g0 = DrawableUtils.a(this.g0, ColorStateList.valueOf(this.k0));
Drawable drawable = this.g0;
int i2 = this.A0;
this.p0 = DrawableUtils.a(drawable, i2, i2);
int i3 = this.l0;
if (i3 != 0 && VKThemeHelper.k.a(i3)) {
this.m0 = VKThemeHelper.d(this.l0);
}
int i4 = this.m0;
if (i4 != 0) {
this.i0 = DrawableUtils.a(this.i0, ColorStateList.valueOf(i4));
}
int i5 = this.n0;
if (i5 != 0 && VKThemeHelper.k.a(i5)) {
this.o0 = VKThemeHelper.d(this.n0);
}
Drawable a2 = DrawableUtils.a(this.g0, ColorStateList.valueOf(0));
int i6 = this.A0;
DrawableUtils.a(a2, i6, i6);
Drawable a3 = DrawableUtils.a(this.h0, ColorStateList.valueOf(this.o0));
int i7 = this.A0;
this.r0 = DrawableUtils.a(a3, i7, i7);
Drawable a4 = DrawableUtils.a(this.g0, ColorStateList.valueOf(ContextCompat.getColor(getContext(), R.color.orange)));
int i8 = this.A0;
this.s0 = DrawableUtils.a(a4, i8, i8);
}
private void r(){
this.c0 = Screen.a(o() ? 0 : 2);
m();
q();
}
private void setUploadFailed(boolean z){
this.u0 = z;
invalidate();
}
@Override // com.vk.stories.view.ClippedImageView, android.widget.ImageView, android.view.View
public void onDraw(Canvas canvas){
super.onDraw(canvas);
setBorderAlpha(255);
if (this.u0) {
this.i0.draw(canvas);
} else if (this.t0) {
if (this.z0 != null) {
b(canvas);
return;
}
this.T = this.x0 ? this.s0 : this.p0;
b(getWidth(), getHeight());
a(canvas);
} else if (this.z0 != null) {
p();
} else if (!this.w0) {
} else {
this.T = this.r0;
setBorderAlpha(163);
b(getWidth(), getHeight());
a(canvas);
}
}
@Override // com.vk.stories.view.BorderedCircleImageView, android.view.View
public void onSizeChanged(int i, int i2, int i3, int i4){
super.onSizeChanged(i, i2, i3, i4);
this.i0.setBounds(0, 0, i, i2);
b(i);
}
public void setStoryContainer(@Nullable StoriesContainer storiesContainer){
boolean z = true;
boolean z2 = storiesContainer != null && storiesContainer.Q1();
this.v0 = storiesContainer != null && storiesContainer.S1() && !storiesContainer.L1();
boolean z3 = storiesContainer instanceof CommunityGroupedStoriesContainer;
this.x0 = z3;
if (storiesContainer != null) {
if (!StoriesContainerExt.c(storiesContainer) && !StoriesContainerExt.d(storiesContainer)) {
this.T = this.p0;
} else {
this.T = this.q0;
}
b(getWidth(), getHeight());
if (StoriesContainerExt.e(storiesContainer)) {
a(storiesContainer);
} else if (this.z0 != null) {
p();
}
this.w0 = !storiesContainer.K1() && storiesContainer.L1();
if (z2) {
String h = storiesContainer.h(ResUtils.c(R.dimen.story_preview_image_size));
if (h != null) {
a(h);
} else {
g();
}
if (StoriesController.a(storiesContainer)) {
setUploadFailed(true);
a(false, false);
} else {
setUploadFailed(false);
if (!storiesContainer.K1() && !StoriesContainerExt.c(storiesContainer)) {
a(false, false);
} else {
StoryEntry A1 = storiesContainer.A1();
if (A1 != null) {
a(true, !B0.contains(A1.b));
B0.add(A1.b);
} else {
a(true, false);
}
}
}
} else {
setUploadFailed(false);
if (!storiesContainer.K1() && !StoriesContainerExt.c(storiesContainer)) {
z = false;
}
a(z, false);
if (z3) {
b(((CommunityGroupedStoriesContainer) storiesContainer).j(ResUtils.c(R.dimen.story_preview_image_size)));
} else {
String h2 = storiesContainer.h(ResUtils.c(R.dimen.story_preview_image_size));
if (h2 != null) {
a(h2);
} else {
g();
}
}
}
} else {
g();
a(false, false);
setUploadFailed(false);
this.w0 = false;
}
r();
}
@Override // com.vk.core.ui.themes.Themable
public void v(){
r();
invalidate();
}
private void b(int i){
LottieDrawable lottieDrawable = this.z0;
if (lottieDrawable == null || lottieDrawable.e() == null) {
return;
}
this.z0.d(i / this.z0.e().a().width());
}
protected void a(Context context, AttributeSet attributeSet, int i){
TypedArray obtainStyledAttributes = context.obtainStyledAttributes(attributeSet, com.vtosters.lite.a0.StoryCircleImageView, i, 0);
a(context, attributeSet, obtainStyledAttributes);
obtainStyledAttributes.recycle();
r();
this.T = this.p0;
}
public void b(@Nullable List<String> list){
PipelineDraweeControllerBuilder pipelineDraweeControllerBuilder = this.f0;
pipelineDraweeControllerBuilder.j();
pipelineDraweeControllerBuilder.a(getController());
setControllerListener(pipelineDraweeControllerBuilder);
a(pipelineDraweeControllerBuilder, list);
setController(pipelineDraweeControllerBuilder.k0());
}
@SuppressLint("ResourceType")
private void a(Context context, AttributeSet attributeSet, TypedArray typedArray){ // bullshit vk code is not working with custom bordered circle image
Drawable drawable;
this.A0 = typedArray.getDimensionPixelSize(0, Screen.a(64.0f));
if (typedArray.hasValue(2)) {
this.g0 = typedArray.getDrawable(2);
} else {
this.g0 = ContextCompat.getDrawable(context, R.drawable.bg_stores_unread_border_80);
}
if (typedArray.hasValue(3)) {
this.h0 = typedArray.getDrawable(3);
} else {
this.h0 = ContextCompat.getDrawable(context, R.drawable.bg_stores_read_border_80);
}
int b2 = VKThemeHelper.b(attributeSet, "vk_borderTint");
if (b2 != 0 && VKThemeHelper.k.a(b2)) {
this.j0 = b2;
} else if (typedArray.hasValue(5)) {
this.k0 = typedArray.getColor(5, 0);
} else {
this.j0 = R.attr.accent;
}
int b3 = VKThemeHelper.b(attributeSet, "vk_failBorderTint");
if (b3 != 0 && VKThemeHelper.k.a(b3)) {
this.l0 = b3;
} else if (typedArray.hasValue(7)) {
this.m0 = typedArray.getColor(7, 0);
}
int b4 = VKThemeHelper.b(attributeSet, "vk_borderSeenTint");
if (b4 != 0 && VKThemeHelper.k.a(b4)) {
this.n0 = b4;
} else if (typedArray.hasValue(4)) {
this.o0 = typedArray.getColor(4, 0);
} else {
this.o0 = 0;
}
if (typedArray.hasValue(6)) {
this.i0 = typedArray.getDrawable(6);
} else {
this.i0 = ContextCompat.getDrawable(context, R.drawable.ic_story_error_size64);
}
if (typedArray.hasValue(8)) {
drawable = typedArray.getDrawable(8);
} else {
drawable = ContextCompat.getDrawable(context, R.drawable.bg_live_unread_border);
}
if (typedArray.hasValue(9)) {
this.y0 = typedArray.getString(9);
} else {
this.y0 = "stories_animation_64.json";
}
int i = this.A0;
this.q0 = DrawableUtils.a(Objects.requireNonNull(drawable), i, i);
Drawable drawable2 = this.g0;
int i2 = this.A0;
DrawableUtils.a(drawable2, i2, i2);
Drawable drawable3 = this.h0;
int i3 = this.A0;
this.r0 = DrawableUtils.a(drawable3, i3, i3);
Drawable drawable4 = this.g0;
int i4 = this.A0;
this.s0 = DrawableUtils.a(drawable4, i4, i4);
}
public void a(StoriesContainer storiesContainer){
if (this.z0 == null) {
LottieCompositionFactory.a(getContext(), this.y0).b(new a(storiesContainer));
}
}
public void a(StoriesContainer storiesContainer, LottieComposition lottieComposition){
this.z0 = new LottieDrawable();
this.z0.a(lottieComposition);
this.z0.d(-1);
b(getWidth());
if (!StoriesContainerExt.f(storiesContainer)) {
this.z0.a(new b());
this.z0.start();
return;
}
this.z0.stop();
}
private void a(boolean z, boolean z2){
k();
this.t0 = z;
if (!z2) {
setSelectionAmount(1.0f);
} else {
n();
}
}
private void a(@NonNull PipelineDraweeControllerBuilder pipelineDraweeControllerBuilder, @Nullable final List<String> list){
pipelineDraweeControllerBuilder.b(null);
pipelineDraweeControllerBuilder.a((Supplier<DataSource<CloseableReference<com.facebook.x.g.CloseableImage>>>) null);
if (list != null && !list.isEmpty()) {
if (list.size() == 1) {
ImageRequestBuilder b2 = ImageRequestBuilder.b(Uri.parse(list.get(0)));
b2.a(ImageRequest.CacheChoice.SMALL);
pipelineDraweeControllerBuilder.b(b2.a());
return;
}
pipelineDraweeControllerBuilder.a((Supplier<DataSource<CloseableReference<CloseableImage>>>) () -> StoryCircleImageView.this.a(list));
return;
}
pipelineDraweeControllerBuilder.b(null);
}
public DataSource<CloseableReference<CloseableImage>> a(@Nullable List<String> list){
ArrayList<Image> arrayList = new ArrayList<>();
for (String o : Objects.requireNonNull(list)) {
arrayList.add(new Image(-1, -1, o));
}
return AvatarDataSource.a(arrayList, this.A0, 0);
}
public class a implements LottieListener<LottieComposition>{
final StoriesContainer a;
a(StoriesContainer storiesContainer){
this.a = storiesContainer;
}
@Override // com.airbnb.lottie.LottieListener
public void a(LottieComposition lottieComposition){
if (StoryCircleImageView.this.getWidth() > 0) {
StoryCircleImageView.this.a(this.a, lottieComposition);
} else {
StoryCircleImageView.this.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver$OnGlobalLayoutListenerC0393a(lottieComposition));
}
}
public class ViewTreeObserver$OnGlobalLayoutListenerC0393a implements ViewTreeObserver.OnGlobalLayoutListener{
final LottieComposition a;
ViewTreeObserver$OnGlobalLayoutListenerC0393a(LottieComposition lottieComposition){
this.a = lottieComposition;
}
@Override // android.view.ViewTreeObserver.OnGlobalLayoutListener
public void onGlobalLayout(){
StoryCircleImageView.this.getViewTreeObserver().removeOnGlobalLayoutListener(this);
a aVar = a.this;
StoryCircleImageView.this.a(aVar.a, this.a);
}
}
}
public class b implements ValueAnimator.AnimatorUpdateListener{
b(){
}
@Override // android.animation.ValueAnimator.AnimatorUpdateListener
public void onAnimationUpdate(ValueAnimator valueAnimator){
StoryCircleImageView.this.invalidate();
}
}
}
+20 -20
View File
@@ -3560,26 +3560,26 @@ public class R {
public static final int stickers_notifications_size = 0x7f070285;
public static final int stickers_tabs_padding = 0x7f070286;
public static final int stickers_tabs_size = 0x7f070287;
public static final int stiсkers_catalog_button_padding_bottom = 0x7f070288;
public static final int stiсkers_catalog_button_padding_left = 0x7f070289;
public static final int stiсkers_catalog_button_padding_right = 0x7f07028a;
public static final int stiсkers_catalog_button_padding_top = 0x7f07028b;
public static final int stiсkers_catalog_double_stacked_slider_image_bg_size = 0x7f07028c;
public static final int stiсkers_catalog_double_stacked_slider_image_corner_radius = 0x7f07028d;
public static final int stiсkers_catalog_double_stacked_slider_image_size = 0x7f07028e;
public static final int stiсkers_catalog_large_slider_image_bg_height = 0x7f07028f;
public static final int stiсkers_catalog_large_slider_image_bg_width = 0x7f070290;
public static final int stiсkers_catalog_large_slider_image_corner_radius = 0x7f070291;
public static final int stiсkers_catalog_large_slider_image_size = 0x7f070292;
public static final int stiсkers_catalog_small_slider_image_bg_size = 0x7f070293;
public static final int stiсkers_catalog_small_slider_image_corner_radius = 0x7f070294;
public static final int stiсkers_catalog_small_slider_image_size = 0x7f070295;
public static final int stiсkers_catalog_triple_stacked_slider_image_bg_size = 0x7f070296;
public static final int stiсkers_catalog_triple_stacked_slider_image_corner_radius = 0x7f070297;
public static final int stiсkers_catalog_triple_stacked_slider_image_size = 0x7f070298;
public static final int stiсkers_catalog_vertical_list_image_bg_size = 0x7f070299;
public static final int stiсkers_catalog_vertical_list_image_corner_radius = 0x7f07029a;
public static final int stiсkers_catalog_vertical_list_image_size = 0x7f07029b;
public static final int stickers_catalog_button_padding_bottom = 0x7f070288;
public static final int stickers_catalog_button_padding_left = 0x7f070289;
public static final int stickers_catalog_button_padding_right = 0x7f07028a;
public static final int stickers_catalog_button_padding_top = 0x7f07028b;
public static final int stickers_catalog_double_stacked_slider_image_bg_size = 0x7f07028c;
public static final int stickers_catalog_double_stacked_slider_image_corner_radius = 0x7f07028d;
public static final int stickers_catalog_double_stacked_slider_image_size = 0x7f07028e;
public static final int stickers_catalog_large_slider_image_bg_height = 0x7f07028f;
public static final int stickers_catalog_large_slider_image_bg_width = 0x7f070290;
public static final int stickers_catalog_large_slider_image_corner_radius = 0x7f070291;
public static final int stickers_catalog_large_slider_image_size = 0x7f070292;
public static final int stickers_catalog_small_slider_image_bg_size = 0x7f070293;
public static final int stickers_catalog_small_slider_image_corner_radius = 0x7f070294;
public static final int stickers_catalog_small_slider_image_size = 0x7f070295;
public static final int stickers_catalog_triple_stacked_slider_image_bg_size = 0x7f070296;
public static final int stickers_catalog_triple_stacked_slider_image_corner_radius = 0x7f070297;
public static final int stickers_catalog_triple_stacked_slider_image_size = 0x7f070298;
public static final int stickers_catalog_vertical_list_image_bg_size = 0x7f070299;
public static final int stickers_catalog_vertical_list_image_corner_radius = 0x7f07029a;
public static final int stickers_catalog_vertical_list_image_size = 0x7f07029b;
public static final int story_author_title_top_space = 0x7f07029c;
public static final int story_cadre_bottom_btn_top_padding = 0x7f07029d;
public static final int story_camera_tabs_height = 0x7f07029e;
@@ -1,5 +1,6 @@
package com.vtosters.lite.ui.bottomnavigation;
import static ru.vtosters.lite.utils.Preferences.*;
import static ru.vtosters.lite.utils.ThemesUtils.getCSTDock;
import android.annotation.SuppressLint;
@@ -30,6 +31,7 @@ import com.vk.core.ui.themes.VKThemeHelper;
import com.vtosters.lite.R;
import me.grishka.appkit.utils.V;
import ru.vtosters.lite.utils.Preferences;
public class BottomNavigationItemView extends FrameLayout implements MenuView.ItemView {
private final TextView mSmallLabel;
@@ -219,13 +221,19 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
// ViewCompat.setScaleY(mLargeLabel, !mStaticModeEnabled && !checked ? mLargeScale : 1.0f);
ViewCompat.setScaleX(mSmallLabel, !mStaticModeEnabled && checked ? mSmallScale : 1.0f);
ViewCompat.setScaleY(mSmallLabel, !mStaticModeEnabled && checked ? mSmallScale : 1.0f);
// make mLargeLabel and mSmallLabel are bold
mLargeLabel.setTypeface(null, Typeface.BOLD);
mSmallLabel.setTypeface(null, Typeface.BOLD);
// make mLargeLabel and mSmallLabel text size is 10sp
mLargeLabel.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
mSmallLabel.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
int textsize;
if (vkme()){
textsize = 11;
} else {
textsize = 10;
}
mLargeLabel.setTextSize(TypedValue.COMPLEX_UNIT_SP, textsize);
mSmallLabel.setTextSize(TypedValue.COMPLEX_UNIT_SP, textsize);
mLargeLabel.setVisibility(/*checked ? VISIBLE :*/ INVISIBLE);
mSmallLabel.setVisibility(VISIBLE);//checked ? INVISIBLE : VISIBLE);
@@ -1,5 +1,7 @@
package ru.vtosters.lite.deviceinfo;
import androidx.annotation.NonNull;
public class Device {
private String androidId;
private String bluetoothMac;
@@ -86,6 +88,7 @@ public class Device {
return this;
}
@NonNull
public String toString() {
return "Device{serialId='" + this.serialId + "', androidId='" + this.androidId + "', wifiMac='" + this.wifiMac + "', bluetoothMac='" + this.bluetoothMac + "'}";
}
@@ -1,5 +1,6 @@
package ru.vtosters.lite.deviceinfo;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.net.wifi.WifiInfo;
@@ -28,6 +29,7 @@ public class DeviceInfoCollector {
private String serialId() {
String str;
try {
@SuppressLint("PrivateApi")
Class<?> cls = Class.forName("android.os.SystemProperties");
Method method = cls.getMethod("get", String.class);
str = (String) method.invoke(cls, "gsm.sn1");
@@ -53,6 +55,7 @@ public class DeviceInfoCollector {
return null;
}
@SuppressLint("HardwareIds")
private String androidId(Context context) {
return Settings.Secure.getString(context.getContentResolver(), "android_id").toLowerCase();
}
@@ -99,7 +102,7 @@ public class DeviceInfoCollector {
StringBuilder sb = new StringBuilder();
int length = hardwareAddress.length;
for (int i = 0; i < length; i++) {
sb.append(String.format("%02X:", Byte.valueOf(hardwareAddress[i])));
sb.append(String.format("%02X:", hardwareAddress[i]));
}
if (sb.length() > 0) {
sb.deleteCharAt(sb.length() - 1);
@@ -1,93 +1,232 @@
package ru.vtosters.lite.dnr;
import static com.vk.im.engine.h.im_ic_done;
import static com.vk.im.engine.h.im_ic_edit_msg;
import static com.vk.im.engine.h.im_ic_more_vertical;
import static com.vk.im.engine.h.im_ic_pinned_msg_hide;
import static com.vk.im.engine.h.im_ic_pinned_msg_show;
import static com.vk.im.engine.h.im_ic_write_msg;
import static com.vk.im.ui.c.im_ic_keyboard;
import static ru.vtosters.lite.dnr.DNRModule.hookDNR;
import static ru.vtosters.lite.dnr.DNRModule.hookDNT;
import static ru.vtosters.lite.dnr.DNRModule.isDnrEnabledFor;
import static ru.vtosters.lite.dnr.DNRModule.isDntEnabledFor;
import static ru.vtosters.lite.encryption.EncryptProvider.decryptMessage;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.Log;
import com.vk.core.network.Network;
import com.vk.im.engine.ImEngine1;
import com.vk.im.engine.events.OnDialogUpdateEvent;
import com.vk.im.engine.models.EntityIntMap;
import com.vk.im.engine.models.ProfilesSimpleInfo;
import com.vk.im.engine.models.dialogs.Dialog;
import com.vk.im.engine.models.messages.Msg;
import com.vk.im.engine.models.messages.MsgFromUser;
import com.vk.im.ui.components.common.DialogAction;
import com.vk.im.ui.components.common.MsgAction;
import com.vk.im.ui.components.viewcontrollers.popup.DelegateMsg;
import com.vk.im.ui.views.dialog_actions.DialogActionsListView;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import ru.vtosters.lite.encryption.EncryptProvider;
import ru.vtosters.lite.encryption.base.IMProcessor;
import ru.vtosters.lite.hooks.CryptImHook;
import ru.vtosters.lite.ui.dialogs.Translate;
import ru.vtosters.lite.utils.AndroidUtils;
public class DNRInjector {
public static void inject(Dialog dialog, List<DialogAction> list) {
int peerId = dialog.getId();
int peerId = 0;
list.add(DialogAction.valueOf("pinmsg"));
list.add(DialogAction.valueOf("unpinmsg"));
if (dialog != null) {
peerId = dialog.getId();
}
list.add(DialogAction.pinmsg);
list.add(DialogAction.unpinmsg);
if (isDnrEnabledFor(peerId)) {
list.add(DialogAction.valueOf("DNR_OFF"));
list.add(DialogAction.DNR_OFF);
} else {
list.add(DialogAction.valueOf("DNR_ON"));
list.add(DialogAction.DNR_ON);
}
if (isDntEnabledFor(peerId)) {
list.add(DialogAction.valueOf("DNT_OFF"));
list.add(DialogAction.DNT_OFF);
} else {
list.add(DialogAction.valueOf("DNT_ON"));
list.add(DialogAction.DNT_ON);
}
list.add(DialogAction.ENCRYPT);
IMProcessor prov = EncryptProvider.getProcessorFor(peerId);
if (prov != null && !prov.isPublic()) {
list.add(DialogAction.ENCRYPT_SETT);
}
}
public static LinkedHashMap<DialogAction, Integer> injectToHashMap(LinkedHashMap<DialogAction, Integer> hashMap) {
hashMap.put(DialogAction.valueOf("DNR_ON"), getIdentifier("DNR_ON", "string"));
hashMap.put(DialogAction.valueOf("DNR_OFF"), getIdentifier("DNR_OFF", "string"));
hashMap.put(DialogAction.valueOf("DNT_ON"), getIdentifier("DNT_ON", "string"));
hashMap.put(DialogAction.valueOf("DNT_OFF"), getIdentifier("DNT_OFF", "string"));
hashMap.put(DialogAction.DNR_ON, getIdentifier("DNR_ON", "string"));
hashMap.put(DialogAction.DNR_OFF, getIdentifier("DNR_OFF", "string"));
hashMap.put(DialogAction.DNT_ON, getIdentifier("DNT_ON", "string"));
hashMap.put(DialogAction.DNT_OFF, getIdentifier("DNT_OFF", "string"));
hashMap.put(DialogAction.ENCRYPT, getIdentifier("encryption", "string"));
hashMap.put(DialogAction.ENCRYPT_SETT, getIdentifier("encryption_sett", "string"));
hashMap.put(DialogAction.valueOf("pinmsg"), getIdentifier("pinmsg", "string"));
hashMap.put(DialogAction.valueOf("unpinmsg"), getIdentifier("unpinmsg", "string"));
// hashMap.put(DialogAction.pinmsg, getIdentifier("pinmsg", "string"));
// hashMap.put(DialogAction.unpinmsg, getIdentifier("unpinmsg", "string"));
return hashMap;
}
public static boolean onClick(Dialog dialog, DialogAction action) {
var id = dialog.getId();
@SuppressLint("ResourceType")
public static List<Object> injectToList(List<Object> actions) {
var list = new ArrayList<>(actions);
if (action == DialogAction.valueOf("MARK_AS_READ")) {
list.add(new DialogActionsListView.b.a(DialogAction.DNR_ON, 2, im_ic_pinned_msg_hide, getIdentifier("DNR_ON", "string"))); // DialogAction, Int, Icon, String
list.add(new DialogActionsListView.b.a(DialogAction.DNR_OFF, 2, im_ic_pinned_msg_show, getIdentifier("DNR_OFF", "string"))); // DialogAction, Int, Icon, String
list.add(new DialogActionsListView.b.a(DialogAction.DNT_ON, 2, im_ic_edit_msg, getIdentifier("DNT_ON", "string"))); // DialogAction, Int, Icon, String
list.add(new DialogActionsListView.b.a(DialogAction.DNT_OFF, 2, im_ic_edit_msg, getIdentifier("DNT_OFF", "string"))); // DialogAction, Int, Icon, String
list.add(new DialogActionsListView.b.a(DialogAction.ENCRYPT, 3, im_ic_keyboard, getIdentifier("encryption", "string"))); // DialogAction, Int, Icon, String
list.add(new DialogActionsListView.b.a(DialogAction.ENCRYPT_SETT, 3, im_ic_more_vertical, getIdentifier("encryption_sett", "string"))); // DialogAction, Int, Icon, String
list.add(new DialogActionsListView.b.a(DialogAction.MARK_AS_READ, 4, im_ic_done, getIdentifier("vkim_dialogs_list_option_mark_as_read", "string"))); // DialogAction, Int, Icon, String
return list;
}
public static void forceInvalidateDialogActions(Dialog d) {
EntityIntMap<Dialog> map = new EntityIntMap<>();
map.a(d.getId(), d);
ImEngine1.a().a(new OnDialogUpdateEvent(null, map));
}
public static List<DialogAction> injectToListAccess(List<DialogAction> actions, Dialog dialog) {
int peerId = 0;
if (dialog != null) {
peerId = dialog.getId();
}
if (isDnrEnabledFor(peerId)) {
actions.add(DialogAction.DNR_OFF);
} else {
actions.add(DialogAction.DNR_ON);
}
if (isDntEnabledFor(peerId)) {
actions.add(DialogAction.DNT_OFF);
} else {
actions.add(DialogAction.DNT_ON);
}
actions.add(DialogAction.ENCRYPT);
IMProcessor prov = EncryptProvider.getProcessorFor(peerId);
if (prov != null && !prov.isPublic()) {
actions.add(DialogAction.ENCRYPT_SETT);
}
actions.add(DialogAction.MARK_AS_READ);
return actions;
}
public static boolean onClickHeader(DialogAction action, Dialog dialog) {
int peerId = 0;
if (dialog != null) {
peerId = dialog.getId();
}
if (action == DialogAction.MARK_AS_READ) {
DNRModule.hookRead(dialog);
forceInvalidateDialogActions(dialog);
}
if (action == DialogAction.DNR_ON) {
setDnr(dialog, true);
forceInvalidateDialogActions(dialog);
return true;
} else if (action == DialogAction.DNR_OFF) {
setDnr(dialog, false);
forceInvalidateDialogActions(dialog);
return true;
}
if (action == DialogAction.DNT_ON) {
setDnt(dialog, true);
forceInvalidateDialogActions(dialog);
return true;
} else if (action == DialogAction.DNT_OFF) {
setDnt(dialog, false);
forceInvalidateDialogActions(dialog);
return true;
}
if (action == DialogAction.ENCRYPT_SETT) {
CryptImHook.hookPref(peerId);
return true;
} else if (action == DialogAction.ENCRYPT) {
CryptImHook.hook(peerId, dialog);
return true;
}
return false;
}
public static boolean onClick(Dialog dialog, DialogAction action) {
int peerId = 0;
if (dialog != null) {
peerId = dialog.getId();
}
if (action == DialogAction.MARK_AS_READ) {
DNRModule.hookRead(dialog);
}
if (action == DialogAction.valueOf("DNR_ON")) {
if (action == DialogAction.DNR_ON) {
setDnr(dialog, true);
return true;
} else if (action == DialogAction.valueOf("DNR_OFF")) {
} else if (action == DialogAction.DNR_OFF) {
setDnr(dialog, false);
return true;
}
if (action == DialogAction.valueOf("DNT_ON")) {
if (action == DialogAction.DNT_ON) {
setDnt(dialog, true);
return true;
} else if (action == DialogAction.valueOf("DNT_OFF")) {
} else if (action == DialogAction.DNT_OFF) {
setDnt(dialog, false);
return true;
}
if (action == DialogAction.valueOf("pinmsg")) {
pinnedMsg(id, true);
if (action == DialogAction.pinmsg) {
pinnedMsg(peerId, true);
return true;
} else if (action == DialogAction.valueOf("unpinmsg")) {
pinnedMsg(id, false);
} else if (action == DialogAction.unpinmsg) {
pinnedMsg(peerId, false);
return true;
}
if (action == DialogAction.ENCRYPT_SETT) {
CryptImHook.hookPref(peerId);
return true;
} else if (action == DialogAction.ENCRYPT) {
CryptImHook.hook(peerId, dialog);
return true;
}
@@ -96,26 +235,42 @@ public class DNRInjector {
public static LinkedHashMap<MsgAction, DelegateMsg.a.a> injectToHashMapMsg(LinkedHashMap<MsgAction, DelegateMsg.a.a> hashMap) {
hashMap.put(MsgAction.valueOf("TRANSLATE"), new DelegateMsg.a.a(getIdentifier("translator", "string")));
hashMap.put(MsgAction.valueOf("READTO"), new DelegateMsg.a.a(getIdentifier("readto", "string")));
return hashMap;
}
public static boolean onClickMsg(Context context, MsgAction action, Msg msg) {
var text = ((MsgFromUser) msg).f();
var peerId = msg.v1();
var fullMsg = ((MsgFromUser) msg).j2(); // text + reply
var reply = fullMsg.substring(text.length() + 1);
if (action == MsgAction.valueOf("READTO")) {
DNRModule.hookReadStartMsgTo(msg);
return true;
}
var isTextExist = !text.isEmpty() && !text.equals(" ");
var isReplyExist = !reply.isEmpty() && !reply.equals(" ");
if (isReplyExist) {
reply = decryptMessage(reply, peerId);
}
if (isTextExist) {
text = decryptMessage(text, peerId);
}
if (action == MsgAction.valueOf("TRANSLATE")) {
if (isTextExist && isReplyExist) {
Translate.showTranslatedText(context, text + "\n\nРеплай:\n" + reply);
Translate.showTranslatedText(context, text + "\n\n" + AndroidUtils.getString("translator_reply") + "\n" + reply);
} else if (isReplyExist) {
Translate.showTranslatedText(context, "Реплай:\n" + reply);
Translate.showTranslatedText(context, AndroidUtils.getString("translator_reply") + "\n" + reply);
} else if (isTextExist) {
Translate.showTranslatedText(context, text);
} else {
sendToast("Нет текста для перевода");
sendToast(AndroidUtils.getString("translator_no_text"));
}
}
@@ -143,15 +298,27 @@ public class DNRInjector {
thread.start();
sendToast("Диалог успешно " + (needToBePinned ? "закреплен" : "откреплен"));
sendToast(AndroidUtils.getString("pin_dialog") + " " + (needToBePinned ? AndroidUtils.getString("dialog_pinned") : AndroidUtils.getString("dialog_unpinned")));
}
public static void setDnr(Dialog dialog, boolean value) {
hookDNR(dialog.getId());
int peerId = 0;
if (dialog != null) {
peerId = dialog.getId();
}
hookDNR(peerId);
}
public static void setDnt(Dialog dialog, boolean value) {
hookDNT(dialog.getId());
int peerId = 0;
if (dialog != null) {
peerId = dialog.getId();
}
hookDNT(peerId);
}
}
@@ -2,10 +2,13 @@ package ru.vtosters.lite.dnr;
import static ru.vtosters.lite.net.Request.makeRequest;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
import static ru.vtosters.lite.utils.ProxyUtils.getApi;
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
import android.util.Log;
import com.vk.im.engine.commands.messages.SetUserActivityCmd;
import com.vk.im.engine.models.dialogs.Dialog;
import com.vk.im.engine.models.messages.Msg;
import java.util.List;
@@ -54,6 +57,12 @@ public class DNRModule {
});
}
public static void hookReadStartMsgTo(Msg dialog) {
Log.d("DNR", "hookReadStartMsgTo: " + dialog.C1() + " " + dialog.v1());
makeRequest("https://" + getApi() + "/method/messages.markAsRead?start_message_id=" + dialog.C1() + "&peer_id=" + dialog.v1() + "&v=5.119&access_token=" + getUserToken(), response -> {
});
}
public static void hookDNR(int peerId) {
mDoNotReadDBHelper.setEnabledForPeerId(peerId, !mDoNotReadDBHelper.isEnabledForPeerId(peerId));
}
@@ -31,11 +31,21 @@ public class AudioDownloader {
public static void downloadM3U8(MusicTrack track) {
if (track.D == null) {
ToastUtils.a("Не удалось найти ссылку на аудиозапись");
ToastUtils.a(AndroidUtils.getString("link_audio_error"));
return;
}
var musicPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath();
var musicDir = new File(musicPath);
if (!musicDir.exists()) {
if (musicDir.mkdirs()) {
Log.d("AudioDownloader", "Created music dir");
} else {
Log.e("AudioDownloader", "Failed to create music dir");
return;
}
}
var tempId = track.d;
var downloadPath = musicPath + File.separator + tempId;
@@ -54,7 +64,7 @@ public class AudioDownloader {
var success = FFMpeg.convert(downloadPath, musicPath + File.separator + fileName + ".mp3");
if (success) {
notification
.setContentText("Загрузка завершена")
.setContentText(AndroidUtils.getString("player_download_finished"))
.setProgress(0, 0, false)
.setSmallIcon(android.R.drawable.stat_sys_download_done);
notificationManager.notify(tempId, notification.build());
@@ -62,7 +72,7 @@ public class AudioDownloader {
onFailure();
}
} catch (UnsatisfiedLinkError e) {
Log.e("AudioDownloader", "Опять эти нативные либы");
Log.e("AudioDownloader", "native libs");
Log.e("AudioDownloader", e.getMessage());
onFailure();
}
@@ -70,7 +80,7 @@ public class AudioDownloader {
@Override
public void onFailure() {
notification.setContentText("Не удалось загрузить аудиозапись").setProgress(0, 0, false);
notification.setContentText(AndroidUtils.getString("load_audio_error")).setProgress(0, 0, false);
notificationManager.notify(tempId, notification.build());
}
@@ -99,7 +109,7 @@ public class AudioDownloader {
private static NotificationCompat.Builder buildDownloadNotification(MusicTrack track, int id) {
var notificationBuilder = new NotificationCompat.Builder(AndroidUtils.getGlobalContext(), NotificationChannels.MUSIC_DOWNLOAD_CHANNEL_ID)
.setSmallIcon(android.R.drawable.stat_sys_download)
.setContentTitle("Загрузка аудиозаписи")
.setContentTitle(AndroidUtils.getString("audio_downloading"))
.setContentText(track.toString())
.setPriority(NotificationCompat.PRIORITY_LOW)
.setCategory(NotificationCompat.CATEGORY_PROGRESS)
@@ -11,6 +11,8 @@ import android.content.IntentFilter;
import android.net.Uri;
import android.os.Environment;
import com.vk.core.dialogs.alert.VkAlertDialog;
import java.io.File;
import b.h.g.m.FileUtils;
@@ -46,7 +48,7 @@ public class OTADownloader {
maxIndex = Math.max(maxIndex, Integer.parseInt(name.replaceFirst(".+-(\\d+).+", "$1")));
}
File apk = maxIndex == -1 ? new File(downloadDir, "VTLite.apk") : new File(downloadDir, "VTLite-" + maxIndex + ".apk");
APKInstallActivity.installOta(context, FileUtils.n(apk));
APKInstallActivity.installOta(context, FileUtils.uriFromFile(apk));
} else if (status == DownloadManager.STATUS_FAILED) {
AndroidUtils.sendToast(getString("downloaderr"));
}
@@ -56,16 +58,31 @@ public class OTADownloader {
public static void downloadBuild(String url) {
var context = AndroidUtils.getGlobalContext();
var uri = Uri.parse(url);
try {
var uri = Uri.parse(url);
context.registerReceiver(callback, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
context.registerReceiver(callback, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
var request = new DownloadManager.Request(uri);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle("VTLite.apk");
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "VTLite.apk");
var request = new DownloadManager.Request(uri);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle("VTLite.apk");
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "VTLite.apk");
var manager = (DownloadManager) AndroidUtils.getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
var manager = (DownloadManager) AndroidUtils.getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
} catch (Exception e) {
e.printStackTrace();
VkAlertDialog.Builder alertDialog = new VkAlertDialog.Builder(context);
alertDialog.setTitle(AndroidUtils.getString("update_error"));
alertDialog.setMessage(AndroidUtils.getString("update_error_text"));
alertDialog.setPositiveButton(AndroidUtils.getString("no"), (dialog, which) -> {
dialog.cancel();
});
alertDialog.setNeutralButton(AndroidUtils.getString("yes"), (dialog, which) -> {
context.startActivity(new Intent("android.intent.action.VIEW").setData(Uri.parse("https://github.com/vtosters/lite/releases/latest/download/VTLite.apk")));
});
var alert = alertDialog.create();
alert.show();
}
}
}
@@ -2,6 +2,7 @@ package ru.vtosters.lite.downloaders;
import static ru.vtosters.lite.downloaders.VideoDownloader.downloadVideo;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.Preferences.getPhotosDir;
import android.app.DownloadManager;
import android.content.Context;
@@ -23,7 +24,7 @@ public class StoryDownloader {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle("photo" + story.E.a);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DCIM, "/Stories/photo" + story.E.a + ".jpg");
request.setDestinationInExternalPublicDir(getPhotosDir().getAbsolutePath(), "/Stories/photo" + story.E.a + ".jpg");
((DownloadManager) getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
return;
}
@@ -5,6 +5,7 @@ import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.getString;
import static ru.vtosters.lite.utils.Preferences.getVideosDir;
import android.app.AlertDialog;
import android.app.DownloadManager;
@@ -27,6 +28,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.ExternalLinkParser;
public class VideoDownloader {
@@ -104,7 +106,7 @@ public class VideoDownloader {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle(videoFile.toString());
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_MOVIES, videoFile + ".mp4");
request.setDestinationInExternalPublicDir(getVideosDir().getAbsolutePath(), videoFile + ".mp4");
((DownloadManager) getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
return;
}
@@ -115,7 +117,7 @@ public class VideoDownloader {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle(videoFile.toString());
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_MOVIES, videoFile + ".mp4");
request.setDestinationInExternalPublicDir(getVideosDir().getAbsolutePath(), videoFile + ".mp4");
((DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
}));
builder.show();
@@ -123,12 +125,12 @@ public class VideoDownloader {
public static void parseVideoLink(String url, Context ctx) {
if (url.contains("vk.com/story")) {
ToastUtils.a("Не поддерживается загрузка историй");
ToastUtils.a(AndroidUtils.getString("video_dl_stories_not_supported"));
return;
}
if (!url.contains("vk.com/video")) {
ToastUtils.a("Неверная ссылка");
ToastUtils.a(AndroidUtils.getString("video_dl_wrong_link"));
return;
}
@@ -136,7 +138,7 @@ public class VideoDownloader {
String ownerId = videoId.split("_")[0];
final ProgressDialog progressDialog = new ProgressDialog(ctx);
progressDialog.setMessage("Обработка видео");
progressDialog.setMessage(AndroidUtils.getString("video_dl_progress"));
progressDialog.show();
makeRequest("https://" + "api.vk.com" + "/method/video.get?owner_id=" + ownerId + "&videos=" + videoId + "&v=5.99&access_token=" + getUserToken(),
@@ -152,7 +154,7 @@ public class VideoDownloader {
downloadVideo(videoFile, ctx);
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(ctx, "Видео нельзя скачать", Toast.LENGTH_SHORT).show();
Toast.makeText(ctx, AndroidUtils.getString("video_dl_error"), Toast.LENGTH_SHORT).show();
}
});
}
@@ -1,10 +1,14 @@
package ru.vtosters.lite.encryption;
import static ru.vtosters.lite.hooks.MessagesHook.injectOwnText;
import static ru.vtosters.lite.hooks.MessagesHook.injectOwnTextAll;
import android.util.Log;
import android.util.Pair;
import com.vk.im.engine.models.messages.Msg;
import com.vk.im.engine.models.messages.MsgFromUser;
import com.vk.im.ui.components.msg_list.MsgListComponent;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -48,6 +52,48 @@ public class EncryptProvider {
public static int getPeerId(Msg msg) {
return msg.v1();
}
// For message editing
public static String decryptMessage(MsgFromUser msg, boolean showEmoji) {
var decryptedMessage = decryptMessage(getBody(msg), getPeerId(msg));
if (!showEmoji && !decryptedMessage.equals(injectOwnTextAll(getBody(msg)))) decryptedMessage = decryptedMessage.replaceAll("^\uD83D\uDD12 ", "");
return decryptedMessage;
}
public static String decryptMessage(String msg, MsgListComponent list) {
var peerid = list.G().getId();
var decryptedMessage = decryptMessage(msg, peerid);
if (!decryptedMessage.equals(injectOwnTextAll(msg))) decryptedMessage = decryptedMessage.replaceAll("^\uD83D\uDD12 ", "");
return decryptedMessage;
}
public static CharSequence decryptMessage(CharSequence msg, int peerid) {
return decryptMessage(msg.toString(), peerid);
}
public static CharSequence decryptMessage(Msg msg, CharSequence orig) {
if (msg instanceof MsgFromUser) {
var decrypted = decryptMessage(((MsgFromUser) msg).f(), msg.v1());
if (decrypted.contains("\uD83D\uDD12")) {
return decrypted;
}
}
return orig;
}
public static String decryptMessages(String msgBody, int peer, boolean showEmoji) {
return (String) decryptMessage(msgBody, peer, showEmoji);
}
// For MentionsFormatter that requires CharSequence
public static CharSequence decryptMessage(String msgBody, int peer, boolean showEmoji) {
var decryptedMessage = decryptMessage(msgBody, peer);
if (!showEmoji && !decryptedMessage.equals(injectOwnTextAll(msgBody))) decryptedMessage = decryptedMessage.replaceAll("^\uD83D\uDD12 ", "");
return decryptedMessage;
}
// This will run through EVERY single processor available.
public static String decryptMessage(MsgFromUser msg) {
@@ -58,12 +104,13 @@ public class EncryptProvider {
try {
for (IMProcessor processor : processors) {
if ((processor.isUsed() || !processor.isPublic()) && processor.isEncrypted(msgBody) && (processor.isPublic() || getKeyForProcessor(processor, peer) != null))
return "\uD83D\uDD12 " + processor.decode(msgBody, getKeyForProcessor(processor, peer));
return "\uD83D\uDD12 " + injectOwnTextAll(processor.decode(msgBody, getKeyForProcessor(processor, peer)));
}
} catch (Exception e) {
e.printStackTrace();
}
return msgBody;
return injectOwnTextAll(msgBody);
}
private static byte[] getKeyForProcessor(IMProcessor processor, int peer) {
@@ -84,9 +131,8 @@ public class EncryptProvider {
return keyString.getBytes();
}
// This will use only the processor which was chosen in chat menu [that's why ID is needed, bruh]
// This will use only the processor which was chosen in chat menu
public static String encryptMessage(MsgFromUser msg) {
String msgBody = getBody(msg);
Log.d("EncryptProvider", "encryptMessage: msg = " + msg);
@@ -96,11 +142,11 @@ public class EncryptProvider {
for (IMProcessor processor : processors) {
int peer = getPeerId(msg);
if (processor.isUsedToEncrypt(peer)) {
return processor.encode(msgBody, getKeyForProcessor(processor, peer));
return injectOwnText(processor.encode(msgBody, getKeyForProcessor(processor, peer)));
}
}
return msgBody;
return injectOwnText(msgBody);
}
// For rendering UI
@@ -2,11 +2,13 @@ package ru.vtosters.lite.foaf;
import static android.widget.Toast.LENGTH_SHORT;
import static android.widget.Toast.makeText;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.getString;
import static ru.vtosters.lite.utils.ProxyUtils.apiproxy;
import static ru.vtosters.lite.utils.ProxyUtils.getApi;
import static ru.vtosters.lite.proxy.ProxyUtils.isApiProxyEnabled;
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Context;
import android.util.Log;
@@ -16,11 +18,15 @@ import androidx.exifinterface.media.ExifInterface;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vk.core.network.Network;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Objects;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
@@ -29,11 +35,13 @@ import java.util.regex.Pattern;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import ru.vtosters.lite.net.Request;
import ru.vtosters.lite.utils.AccountManagerUtils;
public class FoafBase {
private static final Pattern FOAF_REGEX = Pattern.compile("<ya:created dc:date=\"(.+?)\"\\/>");
private static final Pattern FOAF_REGEX_LAST_SEEN = Pattern.compile("<ya:lastLoggedIn dc:date=\"(.*)(((\\+|-)\\d\\d):(\\d\\d))\"\\/>");
private static final Pattern FOAF_REGEX_LOGIN = Pattern.compile("<ya:created dc:date=\"(.+?)\"\\/>");
private static final String API_VKNEXT = "https://api.vknext.net/v1/getBypassedOnlineInfo?json=1&ids=";
private static final OkHttpClient client = new OkHttpClient();
public static long getLastSeen(long origtime, int id) throws ParseException, IOException {
@@ -57,15 +65,57 @@ public class FoafBase {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Moscow"));
Date date = sdf.parse(matcher.group(1));
Date date = sdf.parse(Objects.requireNonNull(matcher.group(1)));
sdf.setTimeZone(TimeZone.getDefault());
return sdf.parse(sdf.format(date)).getTime() / 1000;
}
public static JSONObject getBypassedOnlineInfo(int id) throws JSONException {
var request = new okhttp3.Request.a()
.b(API_VKNEXT + Integer.toString(id))
.a();
String response = null;
var dummy = new JSONObject();
dummy.put("last_seen", 0);
try {
response = client.a(request).execute().a().g();
var online_info = new JSONObject(response).optJSONObject("response").optJSONObject(Integer.toString(id));
return online_info == null ? dummy : online_info;
} catch (Exception e) {
Log.e("GetBypassedOnlineInfo", e.getMessage());
return dummy;
}
}
public static JSONObject getBypassedOnlineInfo(String ids) throws JSONException {
var request = new okhttp3.Request.a()
.b(API_VKNEXT + ids)
.a();
String response = null;
var dummy = new JSONObject();
try {
response = client.a(request).execute().a().g();
var online_info = new JSONObject(response).optJSONObject("response");
return online_info == null ? dummy : online_info;
} catch (Exception e) {
Log.e("GetBypassedOnlineInfo1", e.getMessage());
return dummy;
}
}
private static String getLink(int i) {
String str;
StringBuilder sb;
if (apiproxy()) {
if (isApiProxyEnabled()) {
sb = new StringBuilder();
str = "https://" + getApi() + "/_/vk.com/foaf.php?id=";
} else {
@@ -94,18 +144,19 @@ public class FoafBase {
Matcher matcher2 = FOAF_REGEX_LOGIN.matcher(str);
matcher.find();
matcher2.find();
String normalHumanDate = getNormalHumanDate(matcher.group(1));
getNormalHumanDate(matcher2.group(1));
String normalHumanDate = getNormalHumanDate(Objects.requireNonNull(matcher.group(1)));
getNormalHumanDate(Objects.requireNonNull(matcher2.group(1)));
VkAlertDialog.Builder a2 = new VkAlertDialog.Builder(context).setTitle(getIdentifier("addinf", "string"));
a2.setMessage(getString("foafid") + " " + i + getString("foafregdate") + " " + normalHumanDate + getString("foafdate") + " " + daysPassedFromFoafDate(normalHumanDate)).setPositiveButton(17039370, null).create().show();
} catch (Exception e) {
e.printStackTrace();
makeText(context, getString("foaferr"), LENGTH_SHORT).show();
makeText(getGlobalContext(), getString("foaferr"), LENGTH_SHORT).show();
}
}
private static long daysPassedFromFoafDate(String str) {
private static long daysPassedFromFoafDate(String str) {
try {
@SuppressLint("SimpleDateFormat")
Date parse = new SimpleDateFormat("yyyy-MM-dd").parse(str.split(" ")[1]);
return TimeUnit.DAYS.convert(new Date().getTime() - parse.getTime(), TimeUnit.MILLISECONDS);
} catch (ParseException e) {
@@ -0,0 +1,129 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.dnr.DNRInjector.forceInvalidateDialogActions;
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
import static ru.vtosters.lite.utils.AndroidUtils.getString;
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
import static ru.vtosters.lite.utils.LifecycleUtils.getCurrentActivity;
import static ru.vtosters.lite.utils.ThemesUtils.getAlertStyle;
import static ru.vtosters.lite.utils.ThemesUtils.getSTextAttr;
import android.content.Context;
import android.content.res.ColorStateList;
import android.text.Editable;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.LinearLayout;
import androidx.appcompat.app.AlertDialog;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vk.im.engine.models.dialogs.Dialog;
import java.util.List;
import java.util.Objects;
import ru.vtosters.lite.encryption.EncryptProvider;
import ru.vtosters.lite.encryption.base.IMProcessor;
public class CryptImHook{
public static boolean isPrivateProcessor(int peerID){
for (IMProcessor processor : EncryptProvider.processors) {
if (processor.isUsedToEncrypt(peerID)) {
return !processor.isPublic();
}
}
return false;
}
public static void hook(int peerId, Dialog d){
List<IMProcessor> processors = EncryptProvider.processors;
IMProcessor enabled = null;
int enabledPosition = 0;
String[] titles = new String[processors.size() + 1];
titles[0] = getString("encryption_disable");
for (int i = 0; i < processors.size(); i++) {
IMProcessor proc = processors.get(i);
titles[i + 1] = proc.getUIName();
if (proc.isUsedToEncrypt(peerId)) {
enabled = proc;
enabledPosition = i + 1;
}
}
IMProcessor finalEnabled = enabled;
new VkAlertDialog.Builder(getCurrentActivity())
.setTitle(getString("encryption_sett"))
.setSingleChoiceItems(titles, enabledPosition, (dialog, which) -> {
if (which == 0) {
if (finalEnabled != null) finalEnabled.disableEncryptFor(peerId);
} else {
IMProcessor proc = processors.get(which - 1);
if (proc.isUsedToEncrypt(peerId)) {
proc.disableEncryptFor(peerId);
} else {
proc.enableEncryptFor(peerId);
if (finalEnabled != null) finalEnabled.disableEncryptFor(peerId);
}
}
dialog.dismiss();
forceInvalidateDialogActions(d);
}).create().show();
}
public static void hookPref(int peerId){
IMProcessor enabled = null;
String key = null;
for (IMProcessor processor : EncryptProvider.processors) {
if (processor.isUsedToEncrypt(peerId)) {
enabled = processor;
}
}
if (enabled != null && enabled.isPublic()) {
sendToast(getString("encryption_public_algorithm_error"));
return;
}
if (Objects.requireNonNull(enabled).getEncryptionKeyFor(peerId) != null) {
key = enabled.getEncryptionKeyFor(peerId);
}
if (key.equals("VTAesDefault")) {
key = null;
}
Context ctx = getCurrentActivity();
LinearLayout linearLayout = new LinearLayout(ctx);
final EditText editText = new EditText(ctx);
editText.setHintTextColor(getSTextAttr());
editText.setBackgroundTintList(ColorStateList.valueOf(getSTextAttr()));
linearLayout.addView(editText);
editText.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
ViewGroup.MarginLayoutParams margin = ((ViewGroup.MarginLayoutParams) editText.getLayoutParams());
margin.setMargins(dp2px(24f), 0, dp2px(24f), 0);
editText.setLayoutParams(margin);
editText.setText(key == null ? "" : key);
IMProcessor finalEnabled = enabled;
new AlertDialog.Builder(ctx, getAlertStyle())
.setTitle(getString("encryption_enter_key"))
.setMessage(String.format(getString("encryption_current_algorithm_title"), enabled.getUIName()))
.setView(linearLayout)
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
Editable edit = editText.getText();
finalEnabled.setEncryptionKeyFor(peerId, edit == null ? null : edit.toString());
}).setNegativeButton(android.R.string.cancel, null).create().show();
}
}
@@ -1,6 +1,12 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.AndroidUtils.MD5;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.provider.Settings;
import android.util.Log;
import java.util.Random;
@@ -13,27 +19,30 @@ public class DeviceInfoHook{
}
public static String getDeviceId(String input) {
Log.d("DeviceInfoHook", "getDeviceId: " + input);
Log.d("DeviceInfoHook", "getDeviceId shuffled: " + shuffle(input));
if (getBoolValue("hideDeviceInfo", true)) return shuffle(input);
return input;
return findDeviceId() + ":" + getDeviceId();
}
public static String shuffle(String string) {
StringBuilder sb = new StringBuilder(string.length());
double rnd;
for (char c: string.toCharArray()) {
rnd = Math.random();
if (rnd < 0.34)
sb.append(c);
else if (rnd < 0.67)
sb.insert(sb.length() / 2, c);
else
sb.insert(0, c);
public static String getDeviceId() {
String sb2 = Build.PRODUCT +
Build.BOARD +
Build.BOOTLOADER +
Build.BRAND +
Build.DEVICE +
Build.DISPLAY +
Build.FINGERPRINT +
Build.HARDWARE +
Build.HOST +
Build.ID +
Build.MANUFACTURER +
Build.MODEL +
Build.PRODUCT +
Build.TAGS;
sb.append(new Random().nextInt(10));
sb.deleteCharAt(0);
}
return sb.toString();
return MD5(sb2);
}
@SuppressLint("HardwareIds")
private static String findDeviceId() {
return Settings.Secure.getString(getGlobalContext().getContentResolver(), "android_id");
}
}
@@ -35,6 +35,7 @@ import com.vk.core.fragments.FragmentImpl;
import com.vk.core.util.StringUtils;
import com.vk.navigation.right.RightMenu;
import com.vtosters.lite.MenuCountersState;
import com.vtosters.lite.fragments.ProfileFragment;
import com.vtosters.lite.ui.bottomnavigation.BottomNavigationMenuView;
import com.vtosters.lite.ui.bottomnavigation.BottomNavigationView;
@@ -286,7 +287,7 @@ public class DockBarInjector {
}
public static Class<?> interceptClick(int id, RightMenu rightMenu) {
if (id == tab_menu) {
if (id == tab_menu && rightMenu != null) {
rightMenu.a();
}
@@ -294,6 +295,7 @@ public class DockBarInjector {
if (id == tab.id)
return tab.fragmentClass;
}
for (DockBarTab tab : sManager.getDisabledTabs()) {
if (id == tab.id)
return tab.fragmentClass;
@@ -1,7 +1,10 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.foaf.FoafBase.getLastSeen;
import static ru.vtosters.lite.foaf.FoafBase.getBypassedOnlineInfo;
import static ru.vtosters.lite.hooks.OnlineFormatterHook.onlineHookProfiles;
import static ru.vtosters.lite.hooks.DateHook.getLocale;
import static ru.vtosters.lite.utils.AndroidUtils.getDefaultPrefs;
import static ru.vtosters.lite.utils.Base64Utils.decode;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.checkCaption;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.checkCopyright;
@@ -21,6 +24,7 @@ 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.network.Network;
@@ -33,6 +37,8 @@ import org.json.JSONObject;
import java.io.IOException;
import java.text.ParseException;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Random;
@@ -69,7 +75,7 @@ public class JsonInjectors {
}
public static JSONObject donateRecomm() throws JSONException {
var title = "Помоги проекту донатом и получи бонус!";
var title = AndroidUtils.getString("donate_to_vtl");
var link = "https://vk.com/vtosters_official";
var text_color = "2D81E0";
@@ -110,7 +116,7 @@ public class JsonInjectors {
}
public static JSONObject vktesters(int id) throws JSONException {
var title = "Карточка Тестера";
var title = AndroidUtils.getString("tester_profile");
var text_color = "2D81E0";
var link = "https://static.vk.com/bugs?lang=" + LangUtils.a() + "#/reporter" + id;
@@ -154,7 +160,7 @@ public class JsonInjectors {
var peerid = Objects.requireNonNull(orig.optJSONObject("peer")).optInt("id");
var pic = "https://image.pngaaa.com/641/326641-middle.png"; // can be null
var text = "Я не загрузил данные (9(9((";
var text = AndroidUtils.getString("no_data_error");
var link = "https://vtosters.app"; // can be null
var linktitle = "Test button"; // can be null
@@ -171,9 +177,9 @@ public class JsonInjectors {
if (!hasIcon) icon = "";
if (!hasButton) buttons = "";
if (isVerified(peerid)) text = "Я купил VTosters Premium";
if (isPrometheus(peerid)) text = "Я купил VTosters Premium Gold Prime Pro Plus";
if (isDeveloper(peerid)) text = "Я создал говно";
if (isVerified(peerid)) text = AndroidUtils.getString("i_bought") + " VTosters Premium";
if (isPrometheus(peerid)) text = AndroidUtils.getString("i_bought") + " VTosters Premium Gold Prime Pro Plus";
if (isDeveloper(peerid)) text = AndroidUtils.getString("i_created_poop");
if (!isVerified(peerid) || text.equals("")) {
if (getBoolValue("convBarRecomm", false)) {
return null;
@@ -267,29 +273,82 @@ public class JsonInjectors {
public static JSONObject setOnlineInfo(JSONObject json) throws ParseException, IOException, JSONException {
var id = json.optInt("id");
if (id == AccountManagerUtils.getUserId()) {
return json;
}
var onlineinfo = json.optJSONObject("online_info");
var time = getLastSeen(0L, id);
if (onlineinfo != null && !onlineinfo.optBoolean("visible")) {
var bypassed = getBypassedOnlineInfo(id);
if (bypassed.optInt("last_seen", 0) != 0) {
json.remove("online_info");
if (time != 0L && onlineinfo != null && !onlineinfo.optBoolean("is_online") && id != AccountManagerUtils.getUserId()) {
json.remove("online_info");
var online_info = new JSONObject()
.put("visible", true)
.put("last_seen", bypassed.optInt("last_seen"))
.put("is_online", bypassed.optBoolean("is_online"))
.put("app_id", bypassed.optInt("app_id"))
.put("is_mobile", bypassed.optBoolean("is_mobile"));
var online_info = new JSONObject()
.put("visible", true)
.put("last_seen", time)
.put("is_online", false)
.put("app_id", 0)
.put("is_mobile", false);
var last_seen = new JSONObject()
.put("platform", bypassed.optInt("platform"))
.put("time", bypassed.optInt("last_seen"));
var last_seen = new JSONObject()
.put("platform", 4)
.put("time", time);
json.put("last_seen", last_seen).put("online_info", online_info);
json.put("last_seen", last_seen).put("online_info", online_info);
}
}
return json;
}
public static JSONArray setOnlineInfoUsers(JSONArray profiles) throws ParseException, IOException, JSONException {
if (profiles == null || profiles.length() == 0) return profiles;
StringBuilder sb = new StringBuilder();
var curVkId = AccountManagerUtils.getUserId();
for (int i=0; i < profiles.length(); i++) {
JSONObject profile = profiles.getJSONObject(i);
int id = profile.optInt("id", -1);
JSONObject onlinfo = profile.optJSONObject("online_info");
if (id == curVkId || id < 0 || onlinfo == null || onlinfo.optBoolean("visible")) {
continue;
}
sb.append(id);
sb.append(",");
}
var ids = sb.toString();
if (ids.length() > 0) {
ids = ids.substring(0, ids.length() - 1);
} else {
return profiles;
}
JSONObject bypassedObj = getBypassedOnlineInfo(ids);
for (int i=0; i < profiles.length(); i++) {
JSONObject profile = profiles.getJSONObject(i);
int id = profile.optInt("id");
JSONObject bypassed = bypassedObj.optJSONObject(Integer.toString(id));
if (bypassed == null) {
continue;
}
profile.remove("online_info");
var online_info = new JSONObject()
.put("visible", true)
.put("last_seen", bypassed.optInt("last_seen"))
.put("is_online", bypassed.optBoolean("is_online"))
.put("app_id", bypassed.optInt("app_id"))
.put("is_mobile", bypassed.optBoolean("is_mobile"));
var last_seen = new JSONObject()
.put("platform", bypassed.optInt("platform"))
.put("time", bypassed.optInt("last_seen"));
profile.put("last_seen", last_seen).put("online_info", online_info);
}
return profiles;
}
public static JSONObject storiesads(JSONObject json, boolean isDeleteFix) throws JSONException {
if (!adsstories()) {
return json;
@@ -371,14 +430,37 @@ public class JsonInjectors {
}
public static JSONArray newsfeedlist(JSONArray items) throws JSONException {
for (int j = 0; j < items.length(); j++) {
var list = items.optJSONObject(j);
var name = list.optString("id");
var selectedItems = getDefaultPrefs().getString("news_feed_selected_items", "");
var filtersSet = getDefaultPrefs().getStringSet("news_feed_items_set", null);
var mutableFiltersSet = Collections.synchronizedSet(new LinkedHashSet<String>());
if (filtersSet != null)
mutableFiltersSet.addAll(filtersSet);
if (!name.equals("kpop") && !name.equals("foryou") && !name.equals("qazaqstan")) {
list.put("is_hidden", false).put("is_unavailable", false);
if (dev()) Log.d("NewsfeedListInj", "Unlocked " + name + " in newsfeed list");
synchronized (mutableFiltersSet) {
for (int i = 0; i < items.length(); i++) {
var item = items.optJSONObject(i);
if (item == null) continue;
var id = item.optString("id");
var title = item.optString("title");
if (TextUtils.isEmpty(id) || TextUtils.isEmpty(title)
// this items not working
|| id.equals("kpop") || id.equals("foryou")
|| id.equals("qazaqstan") || id.equals("podcasts"))
continue;
mutableFiltersSet.add(id + "|" + title);
var hide = selectedItems.contains(id);
Log.d("NewsfeedList", "Added list " + id + " to feed");
item.put("is_hidden", hide)
.put("is_unavailable", hide);
if (dev()) Log.d("NewsfeedListInj", "Unlocked " + id + " in newsfeed list");
}
getDefaultPrefs().edit().putStringSet("news_feed_items_set", mutableFiltersSet)
.apply();
}
return items;
@@ -527,7 +609,7 @@ public class JsonInjectors {
Log.d("VKMusic", "title: " + title + " id: " + id + " url: " + url + " value: " + value);
if (url.contains(value)) {
if (url.contains(value) && !value.isEmpty()) {
catalog.put("default_section", id);
if (dev()) Log.d("VKMusic", "Added " + title + " as default music section");
}
@@ -585,8 +667,8 @@ public class JsonInjectors {
return null;
}
public static JSONObject friends(JSONObject json) throws JSONException {
JSONObject catalog = json;
public static JSONObject friends(JSONObject json) throws JSONException, ParseException, IOException {
JSONObject catalog = onlineHookProfiles(json);
boolean sectionexecute = true;
boolean hasBirthday = false;
@@ -2,6 +2,7 @@ package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.ui.dialogs.ServerDialog.sendRequest;
import static ru.vtosters.lite.utils.CacheUtils.getInstance;
import static ru.vtosters.lite.utils.DeletedMessagesHandler.reloadMessagesList;
import static ru.vtosters.lite.utils.Preferences.checkupdates;
import static ru.vtosters.lite.utils.ThemesUtils.isDarkTheme;
import static ru.vtosters.lite.utils.ThemesUtils.setNeededTheme;
@@ -24,6 +25,7 @@ public class MainActivityInjector {
ServerDialog.activity = activity;
sendRequest();
if (checkupdates()) OTADialog.checkUpdates(activity);
reloadMessagesList();
Start.alert(activity);
InstallGMS.alert(activity);
DisableBattery.alert(activity);
@@ -5,7 +5,6 @@ import static ru.vtosters.lite.ui.dialogs.MessageSettings.bombCount;
import static ru.vtosters.lite.ui.dialogs.MessageSettings.isSilentEnabled;
import static ru.vtosters.lite.utils.Preferences.autoalltranslate;
import static ru.vtosters.lite.utils.Preferences.autotranslate;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Preferences.savemsgsett;
import android.text.TextUtils;
@@ -15,18 +14,56 @@ import com.vk.api.internal.MethodCall;
import ru.vtosters.lite.translators.BaseTranslator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.ArrayList;
public class MessagesHook {
public static String injectOwnText(String oldText) {
if (!autotranslate() || TextUtils.isEmpty(oldText))
return oldText;
return BaseTranslator.getInstance().getTranslation(oldText);
var instance = BaseTranslator.getInstance();
return replaceMentions(oldText, instance);
}
public static String injectOwnTextAll(String oldText) {
if (!autoalltranslate() || TextUtils.isEmpty(oldText)) {
return oldText;
}
return BaseTranslator.getInstance().getTranslation(oldText);
var instance = BaseTranslator.getInstance();
return replaceMentions(oldText, instance);
}
public static String replaceMentions(String oldText, BaseTranslator instance) {
try {
var matcher = Pattern.compile("(\\[(?:club|id|public)\\d+\\|[^]]+\\])|(@[^\\s]+)").matcher(oldText);
var mentionsCount = 0;
var textBuff = new StringBuffer();
var mentions = new ArrayList<String>();
while (matcher.find()) {
mentions.add(matcher.group());
matcher.appendReplacement(textBuff, "vtl_mention" + mentionsCount + ""); ++mentionsCount;
}
matcher.appendTail(textBuff);
var translatedText = instance.getTranslation(textBuff.toString());
var matcherMentions = Pattern.compile("vtl_mention(\\d+)").matcher(translatedText);
var retTextBuff = new StringBuffer();
while (matcherMentions.find()) {
matcherMentions.appendReplacement(retTextBuff, mentions.get(
Integer.parseInt(matcherMentions.group(1))
));
}
matcherMentions.appendTail(retTextBuff);
return retTextBuff.toString();
} catch(Exception e) {
e.printStackTrace();
return instance.getTranslation(oldText);
}
}
public static void onLongClick(View view) {
@@ -14,6 +14,10 @@ import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.isMusicBlock;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.isNewsBlock;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.isPostRecommendations;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.isRecomsGroup;
import static ru.vtosters.lite.utils.Preferences.ads;
import static ru.vtosters.lite.utils.Preferences.adsslider;
import static ru.vtosters.lite.utils.Preferences.authorsrecomm;
import static ru.vtosters.lite.utils.Preferences.friendsrecomm;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Preferences.vkme;
@@ -23,6 +27,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
public class NewsfeedHook {
@@ -73,4 +78,42 @@ public class NewsfeedHook {
}
return list;
}
public static String[] feedParams(){
HashSet<String> params = new HashSet<>();
params.add("post");
params.add("photo");
params.add("photo_tag");
if (!friendsrecomm()) {
params.add("friends_recomm");
}
if (!ads()) {
params.add("app_widget");
params.add("promo_button");
}
if (!authorsrecomm()) {
params.add("authors_rec");
}
return params.toArray(new String[0]);
}
public static void adsParams(HashSet<String> hashSet) {
if (ads() || adsslider()) {
hashSet.add("ads_disabled");
return;
}
hashSet.add("ads_app");
hashSet.add("ads_site");
hashSet.add("ads_post");
hashSet.add("ads_app_slider");
hashSet.add("ads_site_slider");
hashSet.add("ads_app_video");
hashSet.add("ads_post_pretty_cards");
hashSet.add("ads_post_snippet_video");
}
}
@@ -1,6 +1,7 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.hooks.JsonInjectors.setOnlineInfo;
import static ru.vtosters.lite.hooks.JsonInjectors.setOnlineInfoUsers;
import static ru.vtosters.lite.net.Request.makeRequest;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
import static ru.vtosters.lite.utils.AndroidUtils.getString;
@@ -8,7 +9,9 @@ import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
import static ru.vtosters.lite.utils.Preferences.dev;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Preferences.getPrefsFromFile;
import static ru.vtosters.lite.utils.ProxyUtils.getApi;
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
@@ -17,6 +20,8 @@ import org.json.JSONObject;
import java.io.IOException;
import java.text.ParseException;
import ru.vtosters.lite.utils.AndroidUtils;
public class OnlineFormatterHook {
private static String AppName;
@@ -59,37 +64,37 @@ public class OnlineFormatterHook {
case 5027722:
return "VK Messenger (Desktop)";
case 6146827:
return "VK Мессенджер (Android)";
return AndroidUtils.getString("vk_messenger") + " (Android)"; // VK Мессенджер (Android)
case 6482950:
return "VK Мессенджер (iPhone)";
return AndroidUtils.getString("vk_messenger") + " (iPhone)"; // VK Мессенджер (iPhone)
case 6481715:
return "VK Мессенджер Dev (iPhone)";
return AndroidUtils.getString("vk_messenger") + " Dev (iPhone)"; // VK Мессенджер Dev (iPhone)
case 7799655:
return "VK Почта";
return AndroidUtils.getString("vk_mail_online"); // VK Почта
case 7598572:
return "Сферум (Android)";
return AndroidUtils.getString("sferum_online") + " (Android)"; // Сферум (Android)
case 7571751:
return "Сферум (iPhone)";
return AndroidUtils.getString("sferum_online") + " (iPhone)"; // Сферум (iPhone)
case 7556576:
return "Сферум";
return AndroidUtils.getString("sferum_online"); // Сферум
case 7497650:
return "VK ID";
case 8094476:
return "VK Звонки (Android)";
return AndroidUtils.getString("vk_calls_online") + " (Android)"; // VK Звонки (Android)
case 8093730:
return "VK Звонки (iPhone)";
return AndroidUtils.getString("vk_calls_online") + " (iPhone)"; // VK Звонки (iPhone)
case 7793118:
return "VK Звонки (Desktop)";
return AndroidUtils.getString("vk_calls_online") + " (Desktop)"; // VK Звонки (Desktop)
case 6767438:
return "VK Музыка (Android)";
return AndroidUtils.getString("vk_music_online") + " (Android)"; // VK Музыка (Android)
case 8113297:
return "VK Клипы (Android)";
return AndroidUtils.getString("vk_clips_online") + " (Android)"; // VK Клипы (Android)
case 8106428:
return "VK Клипы (iPhone)";
return AndroidUtils.getString("vk_clips_online") + " (iPhone)"; // VK Клипы (iPhone)
case 5044491:
return "Candy";
case 8114066:
return "VK Видео";
return AndroidUtils.getString("vk_video_online"); // VK Видео
case 4894723:
return "Phoenix Lite";
case 4994316:
@@ -165,14 +170,66 @@ public class OnlineFormatterHook {
return getString("custom_online") + " " + appname;
}
public static JSONObject onlineHook(JSONObject json, boolean isGlobalHook) throws ParseException, IOException, JSONException {
if (!getBoolValue("onlinefix", false)) return json;
public static JSONObject onlineHook(JSONObject json) throws ParseException, IOException, JSONException {
if (getBoolValue("onlinefix", false)) setOnlineInfo(json);
if (isGlobalHook && !getBoolValue("globalUsersOnline", false)) {
return json;
return json;
}
public static JSONArray onlineHookList(JSONArray jsonArr) throws ParseException, IOException, JSONException {
if (!getBoolValue("onlinefix", false)) return jsonArr;
try {
setOnlineInfoUsers(jsonArr);
} catch (Exception e) {
Log.e("onlineHookProfiles", e.getMessage());
}
setOnlineInfo(json);
return jsonArr;
}
public static JSONObject onlineHookProfiles(JSONObject json) throws ParseException, IOException, JSONException {
if (!getBoolValue("onlinefix", false)) return json;
try {
setOnlineInfoUsers(json.optJSONArray("profiles"));
} catch (Exception e) {
Log.e("onlineHookProfiles", e.getMessage());
}
return json;
}
public static JSONObject onlineHookItems(JSONObject json) throws ParseException, IOException, JSONException {
if (!getBoolValue("onlinefix", false)) return json;
try {
setOnlineInfoUsers(json.optJSONArray("items"));
} catch (Exception e) {
Log.e("onlineHookItems", e.getMessage());
}
return json;
}
public static JSONObject onlineHookRequestsAndRecommendations(JSONObject json) throws ParseException, IOException, JSONException {
if (!getBoolValue("onlinefix", false)) return json;
try {
setOnlineInfoUsers(json.optJSONObject("read_requests").optJSONArray("items"));
} catch (Exception e) {
Log.e("onlineHookItems", e.getMessage());
}
try {
setOnlineInfoUsers(json.optJSONObject("recommendations").optJSONArray("items"));
} catch (Exception e) {
Log.e("onlineHookItems", e.getMessage());
}
try {
setOnlineInfoUsers(json.optJSONArray("profiles"));
} catch (Exception e) {
Log.e("onlineHookItems", e.getMessage());
}
return json;
}
}
@@ -1,5 +1,6 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.AndroidUtils.getString;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
@@ -15,10 +16,15 @@ 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.drawable.RecoloredDrawable;
import com.vk.core.util.ToastUtils;
import com.vk.dto.common.AttachmentWithMedia;
import com.vk.dto.common.ImageSize;
import com.vtosters.lite.R;
import com.vtosters.lite.attachments.DocumentAttachment;
import com.vtosters.lite.attachments.PhotoAttachment;
import org.json.JSONException;
@@ -26,6 +32,7 @@ import org.json.JSONObject;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
@@ -36,18 +43,17 @@ import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.ThemesUtils;
public class PhotoViewer {
static OkHttpClient client = new OkHttpClient();
public static boolean interceptClick(AttachmentWithMedia attachment, MenuItem item, View view) {
if (item.getItemId() == AndroidUtils.getIdentifier("search_photo", "id")) {
searchPhoto(getUrlFromAttachment((PhotoAttachment) attachment));
searchPhoto(getUrlFromPhotoAttachment((PhotoAttachment) attachment));
return true;
} else if (item.getItemId() == AndroidUtils.getIdentifier("copy_photo_url", "id")) {
copyPhotoUrl(getUrlFromAttachment((PhotoAttachment) attachment));
copyPhotoUrl(getUrlFromPhotoAttachment((PhotoAttachment) attachment));
return true;
} else if (item.getItemId() == AndroidUtils.getIdentifier("open_original_photo", "id")) {
openUrl(getUrlFromAttachment((PhotoAttachment) attachment));
openUrl(getUrlFromPhotoAttachment((PhotoAttachment) attachment));
return true;
}
return true;
@@ -61,7 +67,7 @@ public class PhotoViewer {
: new RecoloredDrawable(AndroidUtils.getGlobalContext().getDrawable(R.drawable.ic_menu_search_outline_28), ThemesUtils.getAccentColor()),
false,
() -> {
searchPhoto(getUrlFromAttachment((PhotoAttachment) attachment));
searchPhoto(getUrlFromPhotoAttachment((PhotoAttachment) attachment));
return null;
}
);
@@ -71,7 +77,7 @@ public class PhotoViewer {
: new RecoloredDrawable(AndroidUtils.getGlobalContext().getDrawable(R.drawable.ic_copy_outline_28), Color.WHITE),
false,
() -> {
copyPhotoUrl(getUrlFromAttachment((PhotoAttachment) attachment));
copyPhotoUrl(getUrlFromPhotoAttachment((PhotoAttachment) attachment));
return null;
}
);
@@ -82,14 +88,32 @@ public class PhotoViewer {
ThemesUtils.getAccentColor()),
false,
() -> {
openUrl(getUrlFromAttachment((PhotoAttachment) attachment));
if (attachment instanceof PhotoAttachment) {
openUrl(getUrlFromPhotoAttachment((PhotoAttachment) attachment));
} else if (attachment instanceof DocumentAttachment) {
var documentAttachment = (DocumentAttachment) attachment;
if (documentAttachment.J != null)
openUrl(getUrlFromDocumentAttachment(documentAttachment));
else
ToastUtils.a(getString("photo_get_error"));
}
return null;
}
);
}
private static String getUrlFromAttachment(PhotoAttachment attachment) {
private static String getUrlFromDocumentAttachment(DocumentAttachment attachment) {
var imageSizes = attachment.J.t1();
return getUrlFromImageSizeList(imageSizes);
}
private static String getUrlFromPhotoAttachment(PhotoAttachment attachment) {
var imageSizes = attachment.D.Q.t1();
return getUrlFromImageSizeList(imageSizes);
}
@Nullable
private static String getUrlFromImageSizeList(List<ImageSize> imageSizes) {
if (imageSizes.isEmpty())
return null;
var max = imageSizes.get(0);
@@ -0,0 +1,82 @@
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 com.facebook.drawee.generic.RoundingParams;
import ru.vtosters.lite.utils.AndroidUtils;
public class PicRoundingHook{
private static final int pref = preferences.getInt("pic_rounding", 0);
public static RoundingParams inject() {
if (pref > 0) {
return customParams();
} else {
return new RoundingParams().a(true);
}
}
public static RoundingParams inject(float orig) {
if (pref > 0) {
return customParams();
} else {
return new RoundingParams().b(orig);
}
}
public static RoundingParams inject(float orig, float orig2, float orig3, float orig4) {
if (pref > 0) {
return new RoundingParams().a(AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref));
} else {
return new RoundingParams().a(orig, orig2, orig3, orig4);
}
}
public static void inject(float orig, Canvas canvas, Paint paint){
if (pref > 0) {
canvas.drawRoundRect(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), paint);
} else {
canvas.drawCircle(orig, orig, orig, paint);
}
}
public static void inject(Canvas canvas, Paint paint, float orig){
if (pref > 0) {
canvas.drawRoundRect(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), paint);
} else {
canvas.drawCircle(canvas.getClipBounds().exactCenterX(), canvas.getClipBounds().exactCenterY(), orig, paint);
}
}
public static void inject(Canvas canvas, float orig, float orig2, float orig3, Paint paint){
if (pref > 0) {
canvas.drawRoundRect(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), paint);
} else {
canvas.drawCircle(orig, orig2, orig3, paint);
}
}
public static void inject(Bitmap bitmap, Bitmap bitmap2, Paint b2) {
Shader.TileMode tileMode = Shader.TileMode.CLAMP;
b2.setShader(new BitmapShader(bitmap2, tileMode, tileMode));
Canvas canvas = new Canvas(bitmap);
float width = bitmap2.getWidth() / 2;
if (pref > 0) {
canvas.drawRoundRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), b2);
} else {
canvas.drawCircle(width, width, width, b2);
}
}
private static RoundingParams customParams(){
return RoundingParams.b(AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref));
}
}
@@ -0,0 +1,67 @@
package ru.vtosters.lite.hooks;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import androidx.recyclerview.widget.RecyclerView;
import com.vk.newsfeed.holders.BaseFooterHolder;
import com.vtosters.lite.R;
import ru.vtosters.lite.utils.Preferences;
public class PostViewHook {
/**
* For displaying child elements with custom direction in rtl container we should remove their, set layout direction and add again */
private static void saveChildDirectionForRlt(ViewGroup container) {
var children = new View[container.getChildCount()];
for (int i = 0; i < container.getChildCount(); i++) {
var child = container.getChildAt(i);
child.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
children[i] = child;
}
container.removeAllViews();
for (View child : children) {
container.addView(child);
}
container.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
}
// res/layout/likes_panel.xml
public static void injectBaseFooterHolder(BaseFooterHolder baseFooterHolder) {
if (!Preferences.isLikesOnRightEnabled())
return;
try {
var container = (ViewGroup) ((RecyclerView.ViewHolder) baseFooterHolder).itemView;
saveChildDirectionForRlt((ViewGroup) container.getChildAt(1));
} catch (Exception e) {
e.printStackTrace();
}
}
// res/layout/photo_viewer_bottom.xml
public static void injectPhotoViewer(View container) {
if (!Preferences.isLikesOnRightEnabled())
return;
try {
var bottomPanel = (ViewGroup) container.findViewById(R.id.photo_viewer_bottom_panel);
saveChildDirectionForRlt(bottomPanel);
} catch (Exception e) {
e.printStackTrace();
}
}
// res/layout/video_bottom_view.xml
public static void injectVideoView(RelativeLayout container) {
if (!Preferences.isLikesOnRightEnabled())
return;
try {
var bottomBar = (ViewGroup) container.findViewById(R.id.bottom_bar);
saveChildDirectionForRlt(bottomBar);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -2,10 +2,9 @@ package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.LifecycleUtils.restartApplication;
import static ru.vtosters.lite.utils.ProxyUtils.apiproxy;
import static ru.vtosters.lite.utils.ProxyUtils.isZaboronaEnabled;
import static ru.vtosters.lite.proxy.ProxyUtils.isRandomProxyEnabled;
import static ru.vtosters.lite.proxy.ProxyUtils.isZaboronaEnabled;
import static ru.vtosters.lite.utils.ThemesUtils.getAccentColor;
import static ru.vtosters.lite.utils.ThemesUtils.getAlertStyle;
import static ru.vtosters.lite.utils.ThemesUtils.getTextAttr;
@@ -14,7 +13,6 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.widget.RadioButton;
@@ -27,11 +25,12 @@ import com.vk.auth.ui.VkAuthTextView;
import com.vk.navigation.Navigator;
import ru.vtosters.lite.ui.fragments.ProxySettingsFragment;
import ru.vtosters.lite.utils.AndroidUtils;
public class ProxyHook {
public static void hookAuth(View v) {
VkAuthTextView button = (VkAuthTextView) v;
button.setText("Настроить прокси");
button.setText(AndroidUtils.getString("proxy_setup"));
button.setOnClickListener(v1 -> callProxyDialog(v1.getContext()));
}
@@ -40,44 +39,50 @@ public class ProxyHook {
RadioGroup rg = new RadioGroup(ctx);
RadioButton rgDefault = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
RadioButton rgProxy = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
RadioButton rgZaborona = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
RadioButton rgRandomProxy = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
rg.addView(rgDefault);
rg.addView(rgProxy);
rg.addView(rgZaborona);
rg.addView(rgRandomProxy);
rgDefault.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
rgProxy.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
rgZaborona.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
rgRandomProxy.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
rg.setPadding(dp2px(18f), dp2px(12f), dp2px(18f), 0);
rgDefault.setText("Отключить");
rgDefault.setText(AndroidUtils.getString("proxy_disable"));
rgDefault.setTextColor(getTextAttr());
rgProxy.setText("Включить (Zaborona)");
rgProxy.setTextColor(getTextAttr());
rgZaborona.setText(AndroidUtils.getString("proxy_enable") + " (Zaborona)");
rgZaborona.setTextColor(getTextAttr());
rgProxy.setChecked(isZaboronaEnabled());
rgRandomProxy.setText(AndroidUtils.getString("proxy_enable") + " (RandomProxy)");
rgRandomProxy.setTextColor(getTextAttr());
rgZaborona.setChecked(isZaboronaEnabled());
rgDefault.setChecked(!isZaboronaEnabled());
rgRandomProxy.setChecked(isRandomProxyEnabled());
AlertDialog.Builder builder = new AlertDialog.Builder(ctx, getAlertStyle());
builder.setTitle("Прокси");
builder.setMessage("Zaborona никак не связана с ВТостерс и мы не можем гарантировать её работу и безопасность");
builder.setTitle(AndroidUtils.getString("vtlproxy"));
builder.setMessage(AndroidUtils.getString("proxy_warning"));
builder.setView(rg);
builder.setPositiveButton("Применить", ((dialog, which) -> {
if (rgProxy.isChecked()) {
builder.setPositiveButton(AndroidUtils.getString("vtl_confirm"), ((dialog, which) -> { // Применить
if (rgZaborona.isChecked()) {
edit().putString("proxy", "zaborona").commit();
restartApplication();
} else if (rgRandomProxy.isChecked()) {
edit().putString("proxy", "randomproxy").commit();
restartApplication();
} else {
if (isZaboronaEnabled()) {
edit().putString("proxy", "noproxy").commit();
restartApplication();
}
edit().putString("proxy", "noproxy").commit();
restartApplication();
}
}));
builder.setNeutralButton("Настройки прокси", ((dialog, which) -> {
builder.setNeutralButton(AndroidUtils.getString("proxy_settings"), ((dialog, which) -> {
Intent a2 = new Navigator(ProxySettingsFragment.class).b(ctx);
a2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ctx.startActivity(a2);
@@ -90,47 +95,4 @@ public class ProxyHook {
alert.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(getAccentColor());
alert.getButton(DialogInterface.BUTTON_NEUTRAL).setTextColor(getAccentColor());
}
public static String linkReplacer(String link) {
var vkapi = "api.vk.com";
var oauth = "oauth.vk.com";
var vkstatic = "static.vk.com";
var proxyapi = getPrefsValue("proxyapi");
var proxyoauth = getPrefsValue("proxyoauth");
var proxystatic = getPrefsValue("proxystatic");
if (!apiproxy() || link.isEmpty()) {
return link;
}
if (proxyapi.isEmpty() || proxyoauth.isEmpty() || proxystatic.isEmpty()) {
Log.d("VTLite", "Proxy is not set" + " " + proxyapi + " " + proxyoauth + " " + proxystatic);
return link;
}
if (link.contains(vkapi)) {
return link.replace(proxyapi, vkapi);
}
if (link.contains(oauth)) {
return link.replace(proxyoauth, oauth);
}
if (link.contains(vkstatic)) {
return link.replace(proxystatic, vkstatic);
}
return link;
}
public static String getAwayPhpCom() {
var proxyapi = getPrefsValue("proxyapi");
if (apiproxy() & !proxyapi.isEmpty()) {
return proxyapi;
}
return "m.vk.com";
}
}
@@ -0,0 +1,26 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.Preferences.dev;
import android.util.Log;
import com.vk.api.internal.MethodCall;
import java.util.LinkedHashMap;
public class RequestDumper{
public static void addParams(MethodCall.a paramslist, String method, LinkedHashMap params, String apiver) {
if (method.contains("execute.getGiftByStickerId") ) {
apiver = "5.187";
}
if (dev()) {
Log.d("RequestDumper", "Method: " + method);
Log.d("RequestDumper", "API version: " + apiver);
Log.d("RequestDumper", "Params: " + params);
}
paramslist.a(method);
paramslist.a(params);
paramslist.b(apiver);
}
}
@@ -5,8 +5,10 @@ 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.getAttrId;
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;
@@ -59,8 +61,13 @@ public class VKUIHook {
.replace("%header_text%", hex(getHeaderText()))
.replace("%accent%", hex(getAccentColor()))
.replace("%background_page%", hex(getBackgroundPage()))
.replace("%content_tint_background%", hex(getColorFromAttr(getAttrId("content_tint_background"))))
.replace("%button_primary_background%", hex(getColorFromAttr(getAttrId("button_primary_background"))))
.replace("%button_outline_foreground%", hex(getColorFromAttr(getAttrId("button_outline_foreground"))))
.replace("%button_outline_border%", hex(getColorFromAttr(getAttrId("button_outline_border"))))
.replace("%text_primary%", hex(getTextAttr()));
loadedCSSAmoled = load("vt_ui_oled.css");
isLoaded = true;
}
@@ -0,0 +1,14 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.encryption.EncryptProvider.decryptMessage;
import com.vk.im.engine.models.ProfilesSimpleInfo;
import com.vk.im.engine.models.messages.MsgFromUser;
import com.vk.im.ui.views.ReplyView;
public class WritebarReplyHook {
public static void injectWithDecrypt(ReplyView replyView, MsgFromUser msgFromUser, ProfilesSimpleInfo profilesSimpleInfo) {
msgFromUser.d(decryptMessage(msgFromUser)); // set new value of text in MsgFromUser class
replyView.a(msgFromUser, profilesSimpleInfo, msgFromUser.H1());
}
}
@@ -41,7 +41,7 @@ public class FFMpeg {
private static void checkFFMpegLibs() {
var lib = new File(AndroidUtils.getGlobalContext().getFilesDir(), "libffmpegkit_abidetect.so");
if (!lib.exists()) {
ToastUtils.a("Копирование библиотеки ffmpegkit");
ToastUtils.a(AndroidUtils.getString("ffmpegkit_copy"));
copyAssets();
}
}
@@ -24,6 +24,7 @@ import ru.vtosters.lite.net.NetCallback;
import ru.vtosters.lite.net.NetClient;
import ru.vtosters.lite.net.NetRequest;
import ru.vtosters.lite.net.NetResponse;
import ru.vtosters.lite.utils.AndroidUtils;
public class Scrobbler {
private static final String key = "5965d63402414776c54c266db0211746";
@@ -103,7 +104,7 @@ public class Scrobbler {
public static void auth(String login, String pass) {
if (login == null || pass == null) {
sendToast("Логин или пароль не заданы");
sendToast(AndroidUtils.getString("lastfm_credentials_empty"));
return;
}
@@ -119,7 +120,7 @@ public class Scrobbler {
@Override
public void onFailure(NetCall call, IOException e) {
Log.d("Scrobbler", "Auth failed", e);
sendToast("Ошибка входа");
sendToast(AndroidUtils.getString("lastfm_auth_error"));
}
@Override
@@ -155,7 +156,7 @@ public class Scrobbler {
edit().remove("username").apply();
edit().remove("sessionKey").apply();
scrobbled.clear();
sendToast("Вы успешно вышли из учетной записи");
sendToast(AndroidUtils.getString("lastfm_logout_success"));
}
public static boolean needToBeScrobble(String uid) {
@@ -0,0 +1,30 @@
package ru.vtosters.lite.proxy;
import android.util.Log;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import okhttp3.OkHttpClient;
import okhttp3.Request;
public class GithubList{
private static final OkHttpClient mClient = new OkHttpClient();
public static ArrayList<String> getProxy(String url, String proxyname) throws IOException{
Request link = new Request.a()
.b(url)
.a();
var response = mClient.a(link).execute().a().g();
if (!response.contains(":")) {
Log.d(proxyname, "No proxy found");
return null;
}
Log.d(proxyname, response);
return new ArrayList<>(Arrays.asList(response.split("\n")));
}
}
@@ -0,0 +1,131 @@
package ru.vtosters.lite.proxy;
import static java.lang.System.clearProperty;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.util.ArrayMap;
import android.util.Log;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
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;
public class ProxyUtils{
public static String getApi(){
var proxyapi = getPrefsValue("proxyapi");
if (isApiProxyEnabled() & !proxyapi.isEmpty()) {
return proxyapi;
}
return "api.vk.com";
}
public static Boolean isZaboronaEnabled(){
return getPrefsValue("proxy").equals("zaborona");
}
public static Boolean isRandomProxyEnabled(){
return getPrefsValue("proxy").equals("randomproxy");
}
public static Boolean isApiProxyEnabled(){
return getPrefsValue("proxy").equals("apiproxy");
}
public static Boolean isVikaProxyEnabled(){
return getPrefsValue("proxy").equals("vika");
}
public static void forceProxyApplying(){
Log.d("Proxy", "Setting proxy...");
try {
var context = getGlobalContext().getApplicationContext();
Class<?> applicationClass = Class.forName("android.app.Application");
@SuppressLint("DiscouragedPrivateApi") @SuppressWarnings("JavaReflectionMemberAccess")
Field mLoadedApkField = applicationClass.getDeclaredField("mLoadedApk");
mLoadedApkField.setAccessible(true);
Object mLoadedApkObject = mLoadedApkField.get(context);
@SuppressLint("PrivateApi")
Class<?> loadedApkClass = Class.forName("android.app.LoadedApk");
@SuppressLint("DiscouragedPrivateApi") Field mReceiversField = loadedApkClass.getDeclaredField("mReceivers");
mReceiversField.setAccessible(true);
ArrayMap<?, ?> receivers = (ArrayMap<?, ?>) mReceiversField.get(mLoadedApkObject);
if (receivers != null) {
for (Object receiverMap : receivers.values()) {
for (Object receiver : ((ArrayMap<?, ?>) receiverMap).keySet()) {
Class<?> receiverClass = receiver.getClass();
if (receiverClass.getName().contains("ProxyChangeListener")) {
Method onReceiveMethod = receiverClass.getDeclaredMethod("onReceive", Context.class, Intent.class);
Intent intent = new Intent(android.net.Proxy.PROXY_CHANGE_ACTION);
onReceiveMethod.invoke(receiver, context, intent);
} else {
for (Field field : receiverClass.getDeclaredFields()) {
if (field.getType().getName().contains("ProxyChangeListener")) {
Method onReceiveMethod = receiverClass.getDeclaredMethod("onReceive", Context.class, Intent.class);
Intent intent = new Intent(android.net.Proxy.PROXY_CHANGE_ACTION);
onReceiveMethod.invoke(receiver, context, intent);
}
}
}
}
}
}
Log.d("Proxy", "Setting proxy successful!");
} catch (Exception e) {
Log.d("Proxy", "Setting proxy failed!");
}
}
public static boolean hasProxy(String list){
return list.contains(":"); // proxy format: ip:port
}
public static void setProxy() throws IOException{
switch(getPrefsValue("proxy")) {
case "zaborona":
Zaborona.loadProxy();
break;
case "randomproxy":
RandomProxy.loadProxy();
break;
case "socks":
CustomSocks.loadProxy();
break;
case "http":
CustomHttp.loadProxy();
break;
case "https":
CustomHttps.loadProxy();
break;
default:
resetProxy();
break;
}
}
public static void resetProxy(){
clearProperty("https.proxyHost");
clearProperty("https.proxyPort");
clearProperty("https.proxyUser");
clearProperty("https.proxyPassword");
clearProperty("http.proxyHost");
clearProperty("http.proxyPort");
clearProperty("http.proxyUser");
clearProperty("http.proxyPassword");
clearProperty("socksProxyHost");
clearProperty("socksPortHost");
} // Reset all proxies
}
@@ -0,0 +1,84 @@
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.AndroidUtils.sendToast;
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;
public class RandomProxy{
public static String type = preferences.getString("random_type", "none");
public static String host = preferences.getString("random_host", "");
public static boolean showProxyResult = false;
public static void loadProxy() throws IOException{
if (host.isEmpty()) {
getProxy();
loadProxy();
return;
}
switch(type) {
case "socks":
System.setProperty("socksProxyHost", host.split(":")[0]);
System.setProperty("socksProxyPort", host.split(":")[1]);
break;
case "http":
System.setProperty("http.proxyHost", host.split(":")[0]);
System.setProperty("http.proxyPort", host.split(":")[1]);
break;
case "https":
System.setProperty("https.proxyHost", host.split(":")[0]);
System.setProperty("https.proxyPort", host.split(":")[1]);
break;
}
}
public static void setupNewProxy() throws IOException{
edit().putString("random_type", "none").putString("random_host", "").commit();
resetProxy();
forceProxyApplying();
showProxyResult = true;
getProxy();
edit().putString("proxy", "randomproxy").commit();
}
public static void getProxy() throws IOException{
var random = new java.util.Random();
var randomInt = random.nextInt(7);
switch(randomInt) {
case 0:
Hookzof.loadProxy();
break;
case 1:
TheSpeedX.loadProxy();
break;
case 2:
Jetkai.loadProxy();
break;
case 3:
Roosterkid.loadProxy();
break;
case 4:
ru.vtosters.lite.proxy.http.Jetkai.loadProxy();
break;
case 5:
ru.vtosters.lite.proxy.http.TheSpeedX.loadProxy();
break;
case 6:
ru.vtosters.lite.proxy.https.Jetkai.loadProxy();
break;
case 7:
ru.vtosters.lite.proxy.https.Roosterkid.loadProxy();
break;
}
}
}
@@ -0,0 +1,57 @@
package ru.vtosters.lite.proxy.api;
import static ru.vtosters.lite.proxy.ProxyUtils.isApiProxyEnabled;
import static ru.vtosters.lite.proxy.ProxyUtils.isVikaProxyEnabled;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import android.util.Log;
public class ApiProxy{
public static String linkReplacer(String link){
var vkapi = "api.vk.com";
var oauth = "oauth.vk.com";
var vkstatic = "static.vk.com";
var proxyapi = getPrefsValue("proxyapi");
var proxyoauth = getPrefsValue("proxyoauth");
var proxystatic = getPrefsValue("proxystatic");
if (isVikaProxyEnabled()) {
proxyapi = VikaMobile.getApiHost();
proxyoauth = VikaMobile.getOauthHost();
proxystatic = VikaMobile.getStaticHost();
}
if (!isApiProxyEnabled() || link.isEmpty()) {
return link;
}
if (proxyapi.isEmpty() || proxyoauth.isEmpty() || proxystatic.isEmpty()) {
Log.d("VTLite", "Proxy is not set" + " " + proxyapi + " " + proxyoauth + " " + proxystatic);
return link;
}
if (link.contains(vkapi)) {
return link.replace(proxyapi, vkapi);
}
if (link.contains(oauth)) {
return link.replace(proxyoauth, oauth);
}
if (link.contains(vkstatic)) {
return link.replace(proxystatic, vkstatic);
}
return link;
}
public static String getAwayPhpCom(){
var proxyapi = getPrefsValue("proxyapi");
if (isApiProxyEnabled() & !proxyapi.isEmpty()) {
return proxyapi;
}
return "m.vk.com";
}
}
@@ -0,0 +1,20 @@
package ru.vtosters.lite.proxy.api;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
public class VikaMobile{
public static String getApiHost(){
return isAlternativeHost() ? "vk-api-proxy.vikamobile.ru" : "vk-api-proxy.symbian.live";
}
public static String getOauthHost(){
return isAlternativeHost() ? "vk-oauth-proxy.vikamobile.ru" : "vk-oauth-proxy.symbian.live";
}
public static String getStaticHost(){
return isAlternativeHost() ? "vk-static-proxy.vikamobile.ru" : "vk-static-proxy.symbian.live";
}
public static Boolean isAlternativeHost(){
return getBoolValue("altervika", false);
}
}
@@ -0,0 +1,33 @@
package ru.vtosters.lite.proxy.http;
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
public class CustomHttp{
public static void loadProxy(){
System.setProperty("http.proxyHost", proxyHostHTTP());
System.setProperty("http.proxyPort", proxyPortHTTP());
System.setProperty("http.proxyUser", proxyUserHTTP());
System.setProperty("http.proxyPassword", proxyPassHTTP());
forceProxyApplying();
}
private static String proxyHostHTTP(){
var string = getPrefsValue("proxyHostHTTP");
return string.isEmpty() ? "192.168.0.1" : string;
}
private static String proxyPortHTTP(){
var string = getPrefsValue("proxyPortHTTP");
return string.isEmpty() ? "8888" : string;
}
private static String proxyUserHTTP(){
var string = getPrefsValue("proxyUserHTTP");
return string.isEmpty() ? "" : string;
}
private static String proxyPassHTTP(){
var string = getPrefsValue("proxyPassHTTP");
return string.isEmpty() ? "" : string;
}
}
@@ -0,0 +1,47 @@
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;
import java.io.IOException;
import java.util.ArrayList;
import ru.vtosters.lite.proxy.RandomProxy;
import ru.vtosters.lite.utils.AndroidUtils;
public class Jetkai{
private static final String TAG = "Jetkai_Http";
public static void loadProxy() throws IOException{
ArrayList<String> proxyList = getProxy("https://raw.githubusercontent.com/jetkai/proxy-list/main/online-proxies/txt/proxies-http.txt", TAG);
if (proxyList == null) {
Log.d(TAG, "No proxy found");
return;
}
String proxy = proxyList.get(new java.util.Random().nextInt(proxyList.size()));
if (!hasProxy(proxy)) {
Log.d(TAG, "No proxy port found");
return;
}
Log.d(TAG, "Setting proxy: " + proxy.split(":")[0] + ":" + proxy.split(":")[1]);
if (RandomProxy.showProxyResult) {
AndroidUtils.sendToast("Прокси установлен, хост: " + proxy);
RandomProxy.showProxyResult = false;
RandomProxy.showProxyResult = false;
}
edit().putString("random_type", "http").putString("random_host", proxy).commit();
System.setProperty("http.proxyHost", proxy.split(":")[0]);
System.setProperty("http.proxyPort", proxy.split(":")[1]);
forceProxyApplying();
}
}
@@ -0,0 +1,46 @@
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;
import java.io.IOException;
import java.util.ArrayList;
import ru.vtosters.lite.proxy.RandomProxy;
import ru.vtosters.lite.utils.AndroidUtils;
public class TheSpeedX{
private static final String TAG = "TheSpeedX_Http";
public static void loadProxy() throws IOException{
ArrayList<String> proxyList = getProxy("https://raw.githubusercontent.com/TheSpeedX/PROXY-List/master/http.txt", TAG);
if (proxyList == null) {
Log.d(TAG, "No proxy found");
return;
}
String proxy = proxyList.get(new java.util.Random().nextInt(proxyList.size()));
if (!hasProxy(proxy)) {
Log.d(TAG, "No proxy port found");
return;
}
Log.d(TAG, "Setting proxy: " + proxy.split(":")[0] + ":" + proxy.split(":")[1]);
if (RandomProxy.showProxyResult) {
AndroidUtils.sendToast("Прокси установлен, хост: " + proxy);
RandomProxy.showProxyResult = false;
}
edit().putString("random_type", "http").putString("random_host", proxy).commit();
System.setProperty("http.proxyHost", proxy.split(":")[0]);
System.setProperty("http.proxyPort", proxy.split(":")[1]);
forceProxyApplying();
}
}
@@ -0,0 +1,33 @@
package ru.vtosters.lite.proxy.https;
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
public class CustomHttps{
public static void loadProxy(){
System.setProperty("https.proxyHost", proxyHostHTTPS());
System.setProperty("https.proxyPort", proxyPortHTTPS());
System.setProperty("https.proxyUser", proxyUserHTTPS());
System.setProperty("https.proxyPassword", proxyPassHTTPS());
forceProxyApplying();
}
private static String proxyHostHTTPS(){
var string = getPrefsValue("proxyHostHTTPS");
return string.isEmpty() ? "192.168.0.1" : string;
}
private static String proxyPortHTTPS(){
var string = getPrefsValue("proxyPortHTTPS");
return string.isEmpty() ? "8888" : string;
}
private static String proxyUserHTTPS(){
var string = getPrefsValue("proxyUserHTTPS");
return string.isEmpty() ? "" : string;
}
private static String proxyPassHTTPS(){
String string = getPrefsValue("proxyPassHTTPS");
return string.isEmpty() ? "" : string;
}
}
@@ -0,0 +1,46 @@
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;
import java.io.IOException;
import java.util.ArrayList;
import ru.vtosters.lite.proxy.RandomProxy;
import ru.vtosters.lite.utils.AndroidUtils;
public class Jetkai{
private static final String TAG = "Jetkai_Https";
public static void loadProxy() throws IOException{
ArrayList<String> proxyList = getProxy("https://raw.githubusercontent.com/jetkai/proxy-list/main/online-proxies/txt/proxies-https.txt", TAG);
if (proxyList == null) {
Log.d(TAG, "No proxy found");
return;
}
String proxy = proxyList.get(new java.util.Random().nextInt(proxyList.size()));
if (!hasProxy(proxy)) {
Log.d(TAG, "No proxy port found");
return;
}
Log.d(TAG, "Setting proxy: " + proxy.split(":")[0] + ":" + proxy.split(":")[1]);
if (RandomProxy.showProxyResult) {
AndroidUtils.sendToast("Прокси установлен, хост: " + proxy);
RandomProxy.showProxyResult = false;
}
edit().putString("random_type", "https").putString("random_host", proxy).commit();
System.setProperty("https.proxyHost", proxy.split(":")[0]);
System.setProperty("https.proxyPort", proxy.split(":")[1]);
forceProxyApplying();
}
}
@@ -0,0 +1,47 @@
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;
import java.io.IOException;
import java.util.ArrayList;
import ru.vtosters.lite.proxy.RandomProxy;
import ru.vtosters.lite.utils.AndroidUtils;
public class Roosterkid{
private static final String TAG = "Roosterkid_Https";
public static void loadProxy() throws IOException{
ArrayList<String> proxyList = getProxy("https://raw.githubusercontent.com/roosterkid/openproxylist/main/HTTPS_RAW.txt", TAG);
if (proxyList == null) {
Log.d(TAG, "No proxy found");
return;
}
String proxy = proxyList.get(new java.util.Random().nextInt(proxyList.size()));
if (!hasProxy(proxy)) {
Log.d(TAG, "No proxy port found");
return;
}
Log.d(TAG, "Setting proxy: " + proxy.split(":")[0] + ":" + proxy.split(":")[1]);
if (RandomProxy.showProxyResult) {
AndroidUtils.sendToast("Прокси установлен, хост: " + proxy);
RandomProxy.showProxyResult = false;
}
edit().putString("random_type", "https").putString("random_host", proxy).commit();
System.setProperty("https.proxyHost", proxy.split(":")[0]);
System.setProperty("https.proxyPort", proxy.split(":")[1]);
forceProxyApplying();
}
}
@@ -0,0 +1,21 @@
package ru.vtosters.lite.proxy.socks;
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
public class CustomSocks{
public static void loadProxy(){
System.setProperty("socksProxyHost", proxyHostSocks());
System.setProperty("socksProxyPort", proxyPortSocks());
forceProxyApplying();
}
private static String proxyHostSocks(){
var string = getPrefsValue("proxyHostSocks");
return string.isEmpty() ? "192.168.0.1" : string;
}
private static String proxyPortSocks(){
var string = getPrefsValue("proxyPortSocks");
return string.isEmpty() ? "8888" : string;
}
}
@@ -0,0 +1,46 @@
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;
import java.io.IOException;
import java.util.ArrayList;
import ru.vtosters.lite.proxy.RandomProxy;
import ru.vtosters.lite.utils.AndroidUtils;
public class Hookzof{
private static final String TAG = "Hookzof_Socks";
public static void loadProxy() throws IOException{
ArrayList<String> proxyList = getProxy("https://raw.githubusercontent.com/hookzof/socks5_list/master/proxy.txt", TAG);
if (proxyList == null) {
Log.d(TAG, "No proxy found");
return;
}
String proxy = proxyList.get(new java.util.Random().nextInt(proxyList.size()));
if (!hasProxy(proxy)) {
Log.d(TAG, "No proxy port found");
return;
}
Log.d(TAG, "Setting proxy: " + proxy.split(":")[0] + ":" + proxy.split(":")[1]);
if (RandomProxy.showProxyResult) {
AndroidUtils.sendToast("Прокси установлен, хост: " + proxy);
RandomProxy.showProxyResult = false;
}
edit().putString("random_type", "socks").putString("random_host", proxy).commit();
System.setProperty("socksProxyHost", proxy.split(":")[0]);
System.setProperty("socksProxyPort", proxy.split(":")[1]);
forceProxyApplying();
}
}
@@ -0,0 +1,46 @@
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;
import java.io.IOException;
import java.util.ArrayList;
import ru.vtosters.lite.proxy.RandomProxy;
import ru.vtosters.lite.utils.AndroidUtils;
public class Jetkai{
private static final String TAG = "Jetkai_Socks";
public static void loadProxy() throws IOException{
ArrayList<String> proxyList = getProxy("https://raw.githubusercontent.com/jetkai/proxy-list/main/online-proxies/txt/proxies-socks5.txt", TAG);
if (proxyList == null) {
Log.d(TAG, "No proxy found");
return;
}
String proxy = proxyList.get(new java.util.Random().nextInt(proxyList.size()));
if (!hasProxy(proxy)) {
Log.d(TAG, "No proxy port found");
return;
}
Log.d(TAG, "Setting proxy: " + proxy.split(":")[0] + ":" + proxy.split(":")[1]);
if (RandomProxy.showProxyResult) {
AndroidUtils.sendToast("Прокси установлен, хост: " + proxy);
RandomProxy.showProxyResult = false;
}
edit().putString("random_type", "socks").putString("random_host", proxy).commit();
System.setProperty("socksProxyHost", proxy.split(":")[0]);
System.setProperty("socksProxyPort", proxy.split(":")[1]);
forceProxyApplying();
}
}
@@ -0,0 +1,46 @@
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;
import java.io.IOException;
import java.util.ArrayList;
import ru.vtosters.lite.proxy.RandomProxy;
import ru.vtosters.lite.utils.AndroidUtils;
public class Roosterkid{
private static final String TAG = "Roosterkid_Socks";
public static void loadProxy() throws IOException{
ArrayList<String> proxyList = getProxy("https://raw.githubusercontent.com/roosterkid/openproxylist/main/SOCKS5_RAW.txt", TAG);
if (proxyList == null) {
Log.d(TAG, "No proxy found");
return;
}
String proxy = proxyList.get(new java.util.Random().nextInt(proxyList.size()));
if (!hasProxy(proxy)) {
Log.d(TAG, "No proxy port found");
return;
}
Log.d(TAG, "Setting proxy: " + proxy.split(":")[0] + ":" + proxy.split(":")[1]);
if (RandomProxy.showProxyResult) {
AndroidUtils.sendToast("Прокси установлен, хост: " + proxy);
RandomProxy.showProxyResult = false;
}
edit().putString("random_type", "socks").putString("random_host", proxy).commit();
System.setProperty("socksProxyHost", proxy.split(":")[0]);
System.setProperty("socksProxyPort", proxy.split(":")[1]);
forceProxyApplying();
}
}
@@ -0,0 +1,46 @@
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;
import java.io.IOException;
import java.util.ArrayList;
import ru.vtosters.lite.proxy.RandomProxy;
import ru.vtosters.lite.utils.AndroidUtils;
public class TheSpeedX{
private static final String TAG = "TheSpeedX_Socks";
public static void loadProxy() throws IOException{
ArrayList<String> proxyList = getProxy("https://raw.githubusercontent.com/TheSpeedX/PROXY-List/master/socks5.txt", TAG);
if (proxyList == null) {
Log.d(TAG, "No proxy found");
return;
}
String proxy = proxyList.get(new java.util.Random().nextInt(proxyList.size()));
if (!hasProxy(proxy)) {
Log.d(TAG, "No proxy port found");
return;
}
Log.d(TAG, "Setting proxy: " + proxy.split(":")[0] + ":" + proxy.split(":")[1]);
if (RandomProxy.showProxyResult) {
AndroidUtils.sendToast("Прокси установлен, хост: " + proxy);
RandomProxy.showProxyResult = false;
}
edit().putString("random_type", "socks").putString("random_host", proxy).commit();
System.setProperty("socksProxyHost", proxy.split(":")[0]);
System.setProperty("socksProxyPort", proxy.split(":")[1]);
forceProxyApplying();
}
}
@@ -0,0 +1,10 @@
package ru.vtosters.lite.proxy.socks;
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
public class Zaborona{
public static void loadProxy(){
System.setProperty("socksProxyHost", "socks.zaboronahelp.pp.ua");
System.setProperty("socksProxyPort", "1488");
forceProxyApplying();
}
}
@@ -22,6 +22,8 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import ru.vtosters.lite.utils.AndroidUtils;
public class LogWriterService extends Service {
public LogWriterService() {
}
@@ -44,12 +46,12 @@ public class LogWriterService extends Service {
writeLog(intent, file);
} catch (Exception e) {
e.printStackTrace();
makeText(getGlobalContext(), "Не удалось сохранить лог-файл", LENGTH_SHORT).show();
makeText(getGlobalContext(), AndroidUtils.getString("logfile_error"), LENGTH_SHORT).show();
}
var notificationId = intent.getIntExtra("notificationId", 1);
var manager = (NotificationManager) getGlobalContext().getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(notificationId);
makeText(getGlobalContext(), "Лог-файл был сохранен", LENGTH_SHORT).show();
makeText(getGlobalContext(), AndroidUtils.getString("logfile_saved"), LENGTH_SHORT).show();
stopSelf();
return START_NOT_STICKY;
@@ -11,6 +11,8 @@ import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import ru.vtosters.lite.utils.AndroidUtils;
public class APKInstallActivity extends AppCompatActivity {
public static final int REQUEST_INSTALL_PERMISSION = 1;
@@ -65,7 +67,7 @@ public class APKInstallActivity extends AppCompatActivity {
startActivity(intent);
} catch (Exception e) {
Toast.makeText(this, "Ошибка установки обновления " + e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
Toast.makeText(this, AndroidUtils.getString("apk_install_error") + " " + e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
finish();
@@ -34,10 +34,10 @@ public class CategorizedAdapter extends RecyclerView.Adapter<CategorizedAdapter.
public static final int SELECTED_STATE = -0x1;
public static final int DISABLED_STATE = -0x2;
private List mSelectedItems;
private List mDisabledItems;
private List mUnmovedItems;
private IViewHolderBinder mBinder;
private final List mSelectedItems;
private final List mDisabledItems;
private final List mUnmovedItems;
private final IViewHolderBinder mBinder;
private int mMinSelectedItems = -1;
private int mMaxSelectedItems = -1;
@@ -25,7 +25,7 @@ import ru.vtosters.lite.utils.LayoutUtils;
public class ImagineArrayAdapter extends ArrayAdapter<ImagineArrayAdapter.ImagineArrayAdapterItem> {
private List<ImagineArrayAdapterItem> mItems = new ArrayList<>();
private OnClickListener mListener;
private final OnClickListener mListener;
private int mSelectedIndex = -1;
public ImagineArrayAdapter(@NonNull Context context, OnClickListener listener) {
@@ -134,8 +134,8 @@ public class ImagineArrayAdapter extends ArrayAdapter<ImagineArrayAdapter.Imagin
}
public static class ImagineArrayAdapterItem {
private Drawable mIcon;
private String mText;
private final Drawable mIcon;
private final String mText;
public ImagineArrayAdapterItem(Drawable icon, String text) {
this.mIcon = icon;
@@ -167,6 +167,6 @@ public class ImagineArrayAdapter extends ArrayAdapter<ImagineArrayAdapter.Imagin
}
public interface OnClickListener {
public void onClick(int i);
void onClick(int i);
}
}
@@ -20,13 +20,10 @@ import com.vtosters.lite.R;
import ru.vtosters.lite.utils.AndroidUtils;
public class MessagesPreviewAdapter extends RecyclerView.Adapter<MessagesPreviewAdapter.MessagePreviewViewHolder> {
private static final int ME = 0x0;
private static final int ANONYMOUS = -0x1;
private final String[] mMessages = {
"Доброе время", "Доброе утро, день, вечер. ночь", "Как живёшь?", "Не мёртвый, и то хорошо"
};
private final String[] mMessages = AndroidUtils.getArray("wallpaper_change_dialog");
@Override
public int getItemViewType(int i) {
@@ -7,6 +7,7 @@ import static ru.vtosters.lite.utils.ThemesUtils.getSTextAttr;
import static ru.vtosters.lite.utils.ThemesUtils.getTextAttr;
import static ru.vtosters.lite.utils.ThemesUtils.recolorDrawable;
import android.annotation.SuppressLint;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
@@ -28,8 +29,9 @@ import ru.vtosters.lite.tgs.TGPref;
import ru.vtosters.lite.utils.AndroidUtils;
public class StickerPackAdapter extends RecyclerView.Adapter<StickerPackAdapter.StickerPackViewHolder> {
private static TelegramStickersService sService = TelegramStickersService.getInstance(getGlobalContext());
private static final TelegramStickersService sService = TelegramStickersService.getInstance(getGlobalContext());
@SuppressLint("UseCompatLoadingForDrawables")
@NonNull
@Override
public StickerPackViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
@@ -61,13 +63,13 @@ public class StickerPackAdapter extends RecyclerView.Adapter<StickerPackAdapter.
}
public class StickerPackViewHolder extends RecyclerView.ViewHolder {
private LinearLayout mContainer;
private ImageView mStickerPreview;
private ImageView mUpdateButton;
private ImageView mDeleteButton;
private TextView mName;
private TextView mStickersCount;
private SwitchCompat mSwitch;
private final LinearLayout mContainer;
private final ImageView mStickerPreview;
private final ImageView mUpdateButton;
private final ImageView mDeleteButton;
private final TextView mName;
private final TextView mStickersCount;
private final SwitchCompat mSwitch;
public StickerPackViewHolder(@NonNull View view) {
@@ -82,6 +84,7 @@ public class StickerPackAdapter extends RecyclerView.Adapter<StickerPackAdapter.
mStickersCount = view.findViewWithTag("vkim_cancel_label_text");
}
@SuppressLint("SetTextI18n")
public void bind(int position) {
final TelegramStickersPack pack = sService.getPacksListReference().get(position);
if (pack.state != TelegramStickersPack.DOWNLOADED) return;
@@ -23,6 +23,7 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.IOUtils;
import ru.vtosters.lite.utils.Preferences;
@@ -42,7 +43,7 @@ public class BackupManager {
public static void backupOnlines() throws IOException {
if (getPrefContent("onlines.xml") == null) {
Toast.makeText(getGlobalContext(), "Нет данных для резервного копирования", LENGTH_SHORT).show();
Toast.makeText(getGlobalContext(), AndroidUtils.getString("no_data_to_backup"), LENGTH_SHORT).show();
return;
}
@@ -54,10 +55,10 @@ public class BackupManager {
FileWriter out = new FileWriter(file);
out.write(getPrefContent("onlines.xml"));
out.close();
Toast.makeText(getGlobalContext(), "Сохранено в файл " + file.getAbsolutePath(), LENGTH_LONG).show();
Toast.makeText(getGlobalContext(), AndroidUtils.getString("backup_saved_in") + " " + file.getAbsolutePath(), LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getGlobalContext(), "Не удалось сохранить файл", LENGTH_SHORT).show();
Toast.makeText(getGlobalContext(), AndroidUtils.getString("backup_save_error"), LENGTH_SHORT).show();
}
}
@@ -70,10 +71,10 @@ public class BackupManager {
FileWriter out = new FileWriter(file);
out.write(getPrefContent("com.vtosters.lite_preferences.xml"));
out.close();
Toast.makeText(getGlobalContext(), "Сохранено в файл " + file.getAbsolutePath(), LENGTH_LONG).show();
Toast.makeText(getGlobalContext(), AndroidUtils.getString("backup_saved_in") + " " + file.getAbsolutePath(), LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getGlobalContext(), "Не удалось сохранить файл", LENGTH_SHORT).show();
Toast.makeText(getGlobalContext(), AndroidUtils.getString("backup_save_error"), LENGTH_SHORT).show();
}
}
@@ -5,6 +5,7 @@ import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.getString;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -57,6 +58,7 @@ public class CrashReporter {
var saveLogIntent = new Intent(getGlobalContext(), LogWriterService.class);
saveLogIntent.putExtra("log", logString);
saveLogIntent.putExtra("notificationId", 1);
@SuppressLint("UnspecifiedImmutableFlag")
var psaveLogIntent = PendingIntent.getService(getGlobalContext(), 0, saveLogIntent, PendingIntent.FLAG_CANCEL_CURRENT);
var builder = new Notification.Builder(getGlobalContext());
@@ -65,12 +67,8 @@ public class CrashReporter {
builder.setContentText(logString);
builder.setStyle(new Notification.BigTextStyle().bigText(logString));
builder.setAutoCancel(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
builder.addAction(new Notification.Action(0, getString("vtl_crash_upload"), PendingIntent.getActivity(getGlobalContext(), (int) (Math.random() * 100.0d), foxbinIntent, PendingIntent.FLAG_CANCEL_CURRENT)));
builder.addAction(new Notification.Action(0, getString("vtl_crash_save"), psaveLogIntent));
} else {
builder.setContentIntent(PendingIntent.getActivity(activity, 0, foxbinIntent, PendingIntent.FLAG_ONE_SHOT));
}
builder.addAction(new Notification.Action(0, getString("vtl_crash_upload"), PendingIntent.getActivity(getGlobalContext(), (int) (Math.random() * 100.0d), foxbinIntent, PendingIntent.FLAG_CANCEL_CURRENT)));
builder.addAction(new Notification.Action(0, getString("vtl_crash_save"), psaveLogIntent));
if (Build.VERSION.SDK_INT >= 26) {
builder.setChannelId("crashes");
@@ -10,6 +10,8 @@ import static ru.vtosters.lite.utils.Preferences.videonewcatalog;
import static ru.vtosters.lite.utils.Preferences.vkme;
import static ru.vtosters.lite.utils.Preferences.vkme_notifs;
import android.os.Build;
import com.vk.apps.AppsFragment;
import com.vk.discover.ThemedFeedFragment;
import com.vk.fave.fragments.FaveTabFragment;
@@ -47,7 +49,6 @@ import ru.vtosters.lite.ui.items.DockBarTab;
import ru.vtosters.lite.utils.AndroidUtils;
public class DockBarEditorManager {
public static final int MIN_SELECTED_TABS = 3;
public static final int MAX_SELECTED_TABS = 9;
@@ -97,18 +98,30 @@ public class DockBarEditorManager {
List<String> allTags = new ArrayList<>(Arrays.asList("tab_news", "tab_superapps", "tab_messages", "tab_feedback", "tab_profile",
"tab_friends", "tab_groups", "tab_photos", "tab_audios", "tab_videos", "tab_lives", "tab_games", "tab_liked",
"tab_fave", "tab_documents", "tab_payments", "tab_vk_apps", "tab_settings", "tab_menu"));
for (String tag : selectedTabsTags) {
mSelectedTabs.add(getTabByTag(tag));
allTags.remove(tag);
}
allTags.forEach(tag -> mDisabledTabs.add(getTabByTag(tag)));
for (String tag : allTags) {
mDisabledTabs.add(getTabByTag(tag));
}
}
public void save() {
AndroidUtils.getPreferences().edit().putString("dockbar_tabs", mSelectedTabs.stream()
.map(tab -> tab.tag)
.collect(Collectors.joining(",")))
.commit();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
getPreferences().edit().putString("dockbar_tabs", mSelectedTabs.stream()
.map(tab -> tab.tag)
.collect(Collectors.joining(",")))
.commit();
} else {
StringBuilder sb = new StringBuilder();
for (DockBarTab tab : mSelectedTabs) {
sb.append(tab.tag).append(",");
}
getPreferences().edit().putString("dockbar_tabs", sb.toString()).commit();
}
}
public void reset() {
@@ -1,7 +1,6 @@
package ru.vtosters.lite.ui.components;
public interface IItemMovingListener {
void onItemDismiss(int index);
boolean onItemMove(int fromPosition, int toPosition);
@@ -0,0 +1,63 @@
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 java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import ru.vtosters.lite.ui.vkui.VBottomSheetBuilder;
import ru.vtosters.lite.utils.AndroidUtils;
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.synchronizedSet(new LinkedHashSet<>()));
var list = new ArrayList<VBListItem>();
if (filtersSet.size() == 0) {
sendToast(AndroidUtils.getString("newsfeed_update_feed"));
return;
}
synchronized (filtersSet) {
for (String item : filtersSet) {
var id = item.substring(0, item.indexOf("|"));
var title = item.substring(item.indexOf("|") + 1);
list.add(new VBListItem(id, title, selectedItems.contains(id)));
}
}
VBottomSheetBuilder.show(activity, new VBottomSheetBuilder.VBSContent(
AndroidUtils.getString("newsfeed_list_choose_to_hide"),
buildListOf(activity, list),
new VBottomSheetBuilder.VBSContent.VBSButton(
AndroidUtils.getString("save"),
() -> {
var newSelectedItems = "";
for (VBListItem item : list)
if (item.checked)
newSelectedItems += item.id + ",";
getDefaultPrefs().edit()
.putString("news_feed_selected_items", newSelectedItems)
.apply();
sendToast(AndroidUtils.getString("newsfeed_list_update_feed_to_work"));
}
)
));
}
public static void resetHideItems() {
getDefaultPrefs().edit()
.putString("news_feed_selected_items", "")
.apply();
sendToast(AndroidUtils.getString("newsfeed_list_hidden_reseted"));
}
}
@@ -2,11 +2,14 @@ package ru.vtosters.lite.ui.components;
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
import android.os.Build;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import ru.vtosters.lite.ui.items.DockBarTab;
import ru.vtosters.lite.ui.items.SuperAppItem;
import ru.vtosters.lite.utils.AndroidUtils;
@@ -40,15 +43,30 @@ public class SuperAppEditorManager {
mSelectedItems.add(getItemByTag(tag));
allTags.remove(tag);
}
allTags.forEach(tag -> mDisabledItems.add(getItemByTag(tag)));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
allTags.forEach(tag -> mDisabledItems.add(getItemByTag(tag)));
} else {
for (String tag : allTags) {
mDisabledItems.add(getItemByTag(tag));
}
}
}
public void save() {
if (mSelectedItems.size() > 0)
getPreferences().edit().putString("superapp_items", mSelectedItems.stream()
.map(item -> item.type)
.collect(Collectors.joining(",")))
.commit();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
getPreferences().edit().putString("superapp_items", mSelectedItems.stream()
.map(item -> item.type)
.collect(Collectors.joining(",")))
.commit();
} else {
StringBuilder sb = new StringBuilder();
for (SuperAppItem item : mSelectedItems) {
sb.append(item.type);
sb.append(",");
}
getPreferences().edit().putString("superapp_items", sb.toString()).commit();
}
else
reset();
}
@@ -71,33 +89,33 @@ public class SuperAppEditorManager {
private SuperAppItem getItemByTag(String tag) {
switch (tag) {
case "menu":
return SuperAppItem.valuesOf("menu", "Меню приложения");
return SuperAppItem.valuesOf("menu", AndroidUtils.getString("superapp_menu"));
case "miniapps":
return SuperAppItem.valuesOf("miniapps", "Mini Apps: виджет");
return SuperAppItem.valuesOf("miniapps", AndroidUtils.getString("superapp_miniapps"));
case "vkpay_slim":
return SuperAppItem.valuesOf("vkpay_slim", "VK Pay");
return SuperAppItem.valuesOf("vkpay_slim", AndroidUtils.getString("superapp_vkpay"));
case "greeting":
return SuperAppItem.valuesOf("greeting", "Приветствие");
return SuperAppItem.valuesOf("greeting", AndroidUtils.getString("superapp_greeting"));
case "promo":
return SuperAppItem.valuesOf("promo", "Mini Apps: промо");
return SuperAppItem.valuesOf("promo", AndroidUtils.getString("superapp_miniapps_promo"));
case "holiday":
return SuperAppItem.valuesOf("holiday", "Дни рождения у друзей");
return SuperAppItem.valuesOf("holiday", AndroidUtils.getString("superapp_holiday"));
case "weather":
return SuperAppItem.valuesOf("weather", "Погода");
return SuperAppItem.valuesOf("weather", AndroidUtils.getString("superapp_weather"));
case "sport":
return SuperAppItem.valuesOf("sport", "Спортивные события");
return SuperAppItem.valuesOf("sport", AndroidUtils.getString("superapp_sport"));
case "games":
return SuperAppItem.valuesOf("games", "Игры");
return SuperAppItem.valuesOf("games", AndroidUtils.getString("superapp_games"));
case "informer":
return SuperAppItem.valuesOf("informer", "Информер");
return SuperAppItem.valuesOf("informer", AndroidUtils.getString("superapp_informer"));
case "food":
return SuperAppItem.valuesOf("food", "Еда");
return SuperAppItem.valuesOf("food", AndroidUtils.getString("superapp_food"));
case "event":
return SuperAppItem.valuesOf("event", "Мероприятия");
return SuperAppItem.valuesOf("event", AndroidUtils.getString("superapp_event"));
case "music":
return SuperAppItem.valuesOf("music", "Музыка");
return SuperAppItem.valuesOf("music", AndroidUtils.getString("superapp_music"));
case "vk_run":
return SuperAppItem.valuesOf("vk_run", "VK Run");
return SuperAppItem.valuesOf("vk_run", AndroidUtils.getString("superapp_vk_run"));
default:
return null;
}
@@ -15,6 +15,7 @@ import androidx.appcompat.widget.SwitchCompat;
import com.vk.core.dialogs.alert.VkAlertDialog;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.LayoutUtils;
public class MessageSettings {
@@ -50,12 +51,12 @@ public class MessageSettings {
four.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
five.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
zero.setText("Отключить");
one.setText("15 секунд");
two.setText("1 минута");
three.setText("5 минут");
four.setText("1 час");
five.setText("24 часа");
zero.setText(AndroidUtils.getString("proxy_disable")); // Отключить
one.setText(AndroidUtils.getString("message_self_destruct_15sec"));
two.setText(AndroidUtils.getString("message_self_destruct_1min"));
three.setText(AndroidUtils.getString("message_self_destruct_5min"));
four.setText(AndroidUtils.getString("message_self_destruct_1hour"));
five.setText(AndroidUtils.getString("message_self_destruct_24hours"));
zero.setTextColor(getTextAttr());
one.setTextColor(getTextAttr());
@@ -87,7 +88,7 @@ public class MessageSettings {
@SuppressLint("UseSwitchCompatOrMaterialCode")
var silentSwitch = new SwitchCompat(new ContextThemeWrapper(context, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_Switch));
silentSwitch.setText("Бесшумные сообщения");
silentSwitch.setText(AndroidUtils.getString("silent_messages"));
silentSwitch.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
silentSwitch.setTextColor(getTextAttr());
silentSwitch.setChecked(isSilentEnabled);
@@ -104,12 +105,12 @@ public class MessageSettings {
mContainer.addView(silentSwitch, LayoutUtils.createLinear(-1, -2));
VkAlertDialog.Builder builder = new VkAlertDialog.Builder(context);
builder.setTitle("Настройки отправки");
builder.setMessage("Выберите время исчезновения сообщения");
builder.setTitle(AndroidUtils.getString("message_send_settings_title"));
builder.setMessage(AndroidUtils.getString("silent_messages_time_select"));
builder.setCancelable(true);
builder.setNegativeButton("Отмена", null);
builder.setNegativeButton(AndroidUtils.getString("cancel"), null);
builder.setView(mContainer);
builder.setPositiveButton("Применить", (dialog, which) -> {
builder.setPositiveButton(AndroidUtils.getString("vtl_confirm"), (dialog, which) -> { // Применить
var checked = rg.getCheckedRadioButtonId();
if (checked == zero.getId()) {
@@ -9,7 +9,6 @@ import ru.vtosters.lite.ui.vkui.ModalBottomSheetWrapper;
import ru.vtosters.lite.utils.OTAUtils;
public class OTADialog implements OTAUtils.OTAListener {
private final Activity mActivity;
private final OTAUtils mHelper;
@@ -21,8 +20,8 @@ public class OTADialog implements OTAUtils.OTAListener {
mHelper.loadData();
}
public static OTADialog checkUpdates(Activity activity) {
return new OTADialog(activity);
public static void checkUpdates(Activity activity) {
new OTADialog(activity);
}
@Override
@@ -0,0 +1,41 @@
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 ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.LayoutUtils;
public class RoundingSeekbarDialog{
public static void dialog(Context context) {
LinearLayout mContainer = new LinearLayout(context);
SeekBar seek = new SeekBar(context);
seek.setMax(10);
seek.setKeyProgressIncrement(0);
seek.setProgress(getPreferences().getInt("pic_rounding", 0));
seek.setPadding(dp2px(16f), dp2px(16f), dp2px(16f), dp2px(16f));
mContainer.addView(seek, LayoutUtils.createLinear(-1, -2));
VkAlertDialog.Builder builder = new VkAlertDialog.Builder(context);
builder.setTitle(AndroidUtils.getString("pic_rounding_title"));
builder.setMessage(AndroidUtils.getString("pic_rounding_info"));
builder.setCancelable(true);
builder.setNegativeButton(AndroidUtils.getString("cancel"), null);
builder.setView(mContainer);
builder.setPositiveButton(AndroidUtils.getString("vtl_confirm"), (dialog, which) -> {
edit().putInt("pic_rounding", seek.getProgress()).commit();
restartApplicationWithTimer();
});
builder.show();
}
}
@@ -77,8 +77,6 @@ public class ServerDialog {
private static void getResponse(String body) throws Exception {
JSONObject jSONObject = new JSONObject(body);
Log.d("VTLOG", "getResponse: " + jSONObject);
if (jSONObject.getString("title").equals("")) {
showAlert = false;
return;
@@ -10,6 +10,7 @@ import android.util.Log;
import com.vk.core.dialogs.alert.VkAlertDialog;
import ru.vtosters.lite.translators.BaseTranslator;
import ru.vtosters.lite.utils.AndroidUtils;
public class Translate {
public static void showTranslatedText(Context context, String text) {
@@ -27,16 +28,16 @@ public class Translate {
private static void showDialog(Context context, String text) {
VkAlertDialog.Builder alertDialog = new VkAlertDialog.Builder(context);
alertDialog.setTitle("Переводчик");
alertDialog.setTitle(AndroidUtils.getString("translator_title"));
alertDialog.setMessage(text);
alertDialog.setPositiveButton("Закрыть", (dialog, which) -> {
alertDialog.setPositiveButton(AndroidUtils.getString("close"), (dialog, which) -> {
dialog.cancel();
});
alertDialog.setNeutralButton("Скопировать", (dialog, which) -> {
alertDialog.setNeutralButton(AndroidUtils.getString("copy"), (dialog, which) -> {
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData.newPlainText("Copied Text", text);
clipboard.setPrimaryClip(clip);
sendToast("Скопировано в буфер обмена");
sendToast(AndroidUtils.getString("copied_to_clipboard"));
});
var alert = alertDialog.create();
alert.show();
@@ -22,6 +22,8 @@ import androidx.recyclerview.widget.RecyclerView;
import com.vtosters.lite.R;
import java.util.Objects;
import ru.vtosters.lite.ui.adapters.CategorizedAdapter;
import ru.vtosters.lite.ui.components.DockBarEditorManager;
import ru.vtosters.lite.ui.components.ItemMovingCallback;
@@ -83,7 +85,7 @@ public class DockBarEditorFragment extends BaseToolbarFragment {
});
adapter.setMinAndMaxCounts(DockBarEditorManager.MIN_SELECTED_TABS, DockBarEditorManager.MAX_SELECTED_TABS);
var recyclerView = new RecyclerView(getContext());
var recyclerView = new RecyclerView(requireContext());
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
recyclerView.setHasFixedSize(true);
@@ -1,12 +1,14 @@
package ru.vtosters.lite.ui.fragments;
import static ru.vtosters.lite.utils.AndroidUtils.getDefaultPrefs;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.Preferences.copyright_post;
import static ru.vtosters.lite.utils.Preferences.offline;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import androidx.preference.Preference;
@@ -14,6 +16,9 @@ import com.vk.navigation.Navigator;
import com.vk.newsfeed.NewsfeedSettingsFragment;
import com.vtosters.lite.general.fragments.MaterialPreferenceToolbarFragment;
import ru.vtosters.lite.ui.components.NewsfeedListManager;
import ru.vtosters.lite.utils.AndroidUtils;
public class FeedFragment extends MaterialPreferenceToolbarFragment {
@Override
public void onCreate(Bundle bundle) {
@@ -25,6 +30,33 @@ public class FeedFragment extends MaterialPreferenceToolbarFragment {
private void prefs() {
findPreference("officialnewssett").setOnPreferenceClickListener(new openofficialsett());
findPreference("cringecopyright").setEnabled(!copyright_post());
findPreference("spamfilters").setSummary(count(getPrefsValue("spamfilters")));
findPreference("sourcenamefilter").setSummary(count(getPrefsValue("sourcenamefilter")));
findPreference("linkfilter").setSummary(count(getPrefsValue("linkfilter")));
findPreference("newsfeedlistmanager").setOnPreferenceClickListener(preference -> {
NewsfeedListManager.callEditorPopup(getActivity());
return true;
});
var str = getDefaultPrefs().getString("news_feed_selected_items", "");
findPreference("newsfeedlistmanager").setSummary(
String.format(AndroidUtils.getString("feed_hidden"), (!TextUtils.isEmpty(str) ? str.split(",").length : 0))
);
findPreference("newsfeedlistmanager_reset").setOnPreferenceClickListener(preference -> {
NewsfeedListManager.resetHideItems();
return true;
});
}
private String count(String text) {
// count comma separated words in string
var count = text.split(", ").length;
if (count < 1 || text.isEmpty()) {
return AndroidUtils.getString("feed_no_elements");
} else {
return String.format(AndroidUtils.getString("feed_elements_count"), count);
}
}
@Override
@@ -15,7 +15,6 @@ import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Preferences.hasVerification;
import static ru.vtosters.lite.utils.Preferences.preferences;
import static ru.vtosters.lite.utils.ProxyUtils.isZaboronaEnabled;
import static ru.vtosters.lite.utils.ThemesUtils.getAccentColor;
import static ru.vtosters.lite.utils.ThemesUtils.getAlertStyle;
import static ru.vtosters.lite.utils.ThemesUtils.getTextAttr;
@@ -37,9 +36,14 @@ import androidx.core.content.res.ResourcesCompat;
import com.vtosters.lite.general.fragments.MaterialPreferenceToolbarFragment;
import ru.vtosters.lite.utils.AndroidUtils;
public class IconsFragment extends MaterialPreferenceToolbarFragment {
@SuppressLint("SetTextI18n")
public static void callSelectDialog(Context ctx, String appicon) {
var defname = preferences.getString("appname", "vt");
var deficon = preferences.getString("selectedicon", "vt");
RadioGroup rg = new RadioGroup(ctx);
RadioButton rgDefault = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
@@ -62,20 +66,17 @@ public class IconsFragment extends MaterialPreferenceToolbarFragment {
rgVK.setText("VK");
rgVK.setTextColor(getTextAttr());
rgVKontakte.setText("ВКонтакте");
rgVKontakte.setText(AndroidUtils.getString("app_name_alter"));
rgVKontakte.setTextColor(getTextAttr());
rgVKontakte.setChecked(isZaboronaEnabled());
rgVK.setChecked(isZaboronaEnabled());
rgDefault.setChecked(!isZaboronaEnabled());
rgVKontakte.setChecked(defname.contains("vkontakte"));
rgVK.setChecked(defname.contains("standard"));
rgDefault.setChecked(defname.contains("vt") || defname.isEmpty());
AlertDialog.Builder builder = new AlertDialog.Builder(ctx, getAlertStyle());
builder.setTitle("Выберите название приложения");
builder.setTitle(AndroidUtils.getString("app_name_select_title"));
builder.setView(rg);
builder.setPositiveButton("Применить", ((dialog, which) -> {
var defname = preferences.getString("appname", "vt");
var deficon = preferences.getString("selectedicon", "vt");
builder.setPositiveButton(AndroidUtils.getString("vtl_confirm"), ((dialog, which) -> {
if (rgDefault.isChecked()) {
edit().putString("appname", "vt").commit();
edit().putString("selectedicon", appicon).commit();
@@ -93,7 +94,7 @@ public class IconsFragment extends MaterialPreferenceToolbarFragment {
switchComponent(appicon, "vkontakte", deficon, defname);
}
}));
builder.setNegativeButton("Отмена", ((dialog, which) -> {
builder.setNegativeButton(AndroidUtils.getString("cancel"), ((dialog, which) -> {
dialog.dismiss();
}));
@@ -114,13 +115,13 @@ public class IconsFragment extends MaterialPreferenceToolbarFragment {
this.addPreferencesFromResource(vtosterXml);
if (!hasVerification() && !getBoolValue("dialogrecomm", false)) {
addPreference(this, "", "Доступны не все функции!", "Для разблокировки необходимо сделать пожертование от 99р", "ic_about_outline_28", preference -> {
getContext().startActivity(new Intent("android.intent.action.VIEW").setData(Uri.parse("https://vtosters.app")));
addPreference(this, "", AndroidUtils.getString("icons_warning"), AndroidUtils.getString("icons_warning_info"), "ic_about_outline_28", preference -> {
getContext().startActivity(new Intent("android.intent.action.VIEW").setData(Uri.parse("https://vtosters.app/donate/")));
return false;
});
}
addPreferenceCategory(this, "Иконки");
addPreferenceCategory(this, AndroidUtils.getString("icons_title"));
for (var i = 0; i < icons().size(); i++) {
if (icons().get(i) == null || iconsValues().get(i) == null) return;
@@ -151,7 +152,7 @@ public class IconsFragment extends MaterialPreferenceToolbarFragment {
}
if (!hasVerification() && !getBoolValue("dialogrecomm", false)) {
addPreferenceCategory(this, "Недоступные иконки");
addPreferenceCategory(this, AndroidUtils.getString("unavailable_icons"));
for (var i = 2; i < sIconsPlusNames.size(); i++) {
if (sIconsPlusNames.get(i) == null || sIconsPlus.get(i) == null) return;
@@ -176,7 +177,7 @@ public class IconsFragment extends MaterialPreferenceToolbarFragment {
}
addPreferenceDrawable(this, icon, iconname, "", drawable, preference -> {
sendToast("Иконка доступна только обладателям верификации");
sendToast(AndroidUtils.getString("unavailable_icon_warning"));
return false;
});
}
@@ -1,6 +1,7 @@
package ru.vtosters.lite.ui.fragments;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
import static ru.vtosters.lite.utils.LifecycleUtils.restartApplicationWithTimer;
import android.os.Bundle;
@@ -9,6 +10,9 @@ import androidx.preference.Preference;
import com.vtosters.lite.general.fragments.MaterialPreferenceToolbarFragment;
import ru.vtosters.lite.ui.dialogs.RoundingSeekbarDialog;
import ru.vtosters.lite.utils.AndroidUtils;
public class InterfaceFragment extends MaterialPreferenceToolbarFragment {
@Override
public void onCreate(Bundle bundle) {
@@ -20,6 +24,18 @@ public class InterfaceFragment extends MaterialPreferenceToolbarFragment {
private void prefs() {
findPreference("stories").setOnPreferenceClickListener(new restart());
findPreference("swipe").setOnPreferenceClickListener(new restart());
findPreference("is_likes_on_right").setOnPreferenceClickListener(new restart());
findPreference("customrounding").setOnPreferenceClickListener(preference -> {
RoundingSeekbarDialog.dialog(getContext());
return true;
});
if (getPreferences().getInt("pic_rounding", 0) == 0) {
findPreference("customrounding").setSummary(AndroidUtils.getString("disabled"));
} else {
findPreference("customrounding").setSummary(String.format(AndroidUtils.getString("rounding_size"), getPreferences().getInt("pic_rounding", 0)));
}
}
public boolean restart(Preference preference) {
@@ -13,8 +13,10 @@ import static ru.vtosters.lite.utils.ThemesUtils.getAlertStyle;
import static ru.vtosters.lite.utils.ThemesUtils.getSTextAttr;
import static ru.vtosters.lite.utils.ThemesUtils.getTextAttr;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.os.Bundle;
import android.util.Log;
@@ -40,104 +42,16 @@ import okhttp3.Request;
import ru.vtosters.lite.downloaders.VideoDownloader;
import ru.vtosters.lite.music.Scrobbler;
import ru.vtosters.lite.ui.adapters.ImagineArrayAdapter;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.FileUriUtils;
import ru.vtosters.lite.utils.Preferences;
public class MediaFragment extends MaterialPreferenceToolbarFragment {
public static void download(Context ctx) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(ctx, getAlertStyle());
alertDialog.setTitle("Введите ссылку на видео");
private final int REQUEST_CODE_SET_DOWNLOAD_DIRECTORY = 665;
private final int REQUEST_CODE_SET_MUSIC_DIRECTORY = 666;
private final int REQUEST_CODE_SET_PHOTOS_DIRECTORY = 667;
private final int REQUEST_CODE_SET_VIDEOS_DIRECTORY = 668;
final EditText input = new EditText(ctx);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
input.setLayoutParams(lp);
input.setTextColor(getTextAttr());
input.setBackgroundTintList(ColorStateList.valueOf(getAccentColor()));
alertDialog.setView(input);
alertDialog.setPositiveButton("Скачать", (dialog, which) -> VideoDownloader.parseVideoLink(input.getText().toString(), ctx));
var alert = alertDialog.create();
alert.show();
alert.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(getAccentColor());
}
private void logout(Context ctx) {
VkAlertDialog.Builder alertDialog = new VkAlertDialog.Builder(ctx);
alertDialog.setTitle("Вы уверены?");
alertDialog.setMessage("Вы действительно хотите выйти из аккаунта?");
alertDialog.setPositiveButton("Да", (dialog, which) -> {
Scrobbler.logout();
});
alertDialog.setNeutralButton("Нет", (dialog, which) -> {
dialog.cancel();
});
var alert = alertDialog.create();
alert.show();
alert.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(getAccentColor());
alert.getButton(DialogInterface.BUTTON_NEUTRAL).setTextColor(getResources().getColor(com.vtosters.lite.R.color.red));
}
private void lastfmAuth(Context ctx) {
LinearLayout linearLayout = new LinearLayout(ctx);
linearLayout.setOrientation(LinearLayout.VERTICAL);
final EditText fn = new EditText(ctx);
fn.setHint("Логин");
fn.setTextColor(getTextAttr());
fn.setHintTextColor(getSTextAttr());
fn.setBackgroundTintList(ColorStateList.valueOf(getAccentColor()));
linearLayout.addView(fn);
fn.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
ViewGroup.MarginLayoutParams margin = ((ViewGroup.MarginLayoutParams) fn.getLayoutParams());
margin.setMargins(dp2px(20f), 0, dp2px(20f), 0);
fn.setLayoutParams(margin);
final EditText ln = new EditText(ctx);
ln.setHint("Пароль");
ln.setTextColor(getTextAttr());
ln.setHintTextColor(getSTextAttr());
ln.setBackgroundTintList(ColorStateList.valueOf(getAccentColor()));
linearLayout.addView(ln);
ln.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
ln.setLayoutParams(margin);
AlertDialog.Builder alertDialog = new AlertDialog.Builder(ctx, getAlertStyle());
alertDialog.setTitle("Введите логин и пароль");
alertDialog.setView(linearLayout);
alertDialog.setPositiveButton("Войти", (dialog, which) -> {
String login = fn.getText().toString();
String pass = ln.getText().toString();
Scrobbler.auth(login, pass);
});
var alert = alertDialog.create();
alert.show();
alert.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(getAccentColor());
}
public static void deleteVideoHistory() {
Thread thread = new Thread(() -> {
try {
var request = new Request.a()
.b("https://api.vk.com/method/" + "video.clearViewingHistoryRecords" + "?https=1" + "&access_token=" + getUserToken() + "&v=5.187")
.a(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8"))
.a();
try {
var response = new OkHttpClient().a(request).execute().a().g();
Log.d("VideoHistory", response);
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
});
thread.start();
sendToast("История просмотра видео очищена");
}
@Override
public void onCreate(Bundle bundle) {
@@ -146,6 +60,41 @@ public class MediaFragment extends MaterialPreferenceToolbarFragment {
prefs();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
var path = data.getData();
if (path != null) {
var prefs = getPreferences();
var editor = prefs.edit();
var actualPath = FileUriUtils.getFullPathFromTreeUri(path, getContext());
switch (requestCode) {
case REQUEST_CODE_SET_DOWNLOAD_DIRECTORY:
editor.putString("downloads_directory", actualPath);
break;
case REQUEST_CODE_SET_MUSIC_DIRECTORY:
editor.putString("music_directory", actualPath);
break;
case REQUEST_CODE_SET_PHOTOS_DIRECTORY:
editor.putString("photos_directory", actualPath);
break;
case REQUEST_CODE_SET_VIDEOS_DIRECTORY:
editor.putString("videos_directory", actualPath);
break;
default:
return;
}
editor.apply();
}
}
}
@Override
public void onResume() {
super.onResume();
prefs();
}
private void prefs() {
findPreference("download_video").setOnPreferenceClickListener(new MediaFragment.download());
findPreference("clearvideohistory").setOnPreferenceClickListener(preference -> {
@@ -162,8 +111,52 @@ public class MediaFragment extends MaterialPreferenceToolbarFragment {
return true;
});
findPreference("downloads_directory").setSummary(
AndroidUtils.getString("current_download_folder") + " " + Preferences.getDownloadsDir()
);
findPreference("photos_directory").setSummary(
AndroidUtils.getString("current_download_folder") + " " + Preferences.getPhotosDir()
);
findPreference("videos_directory").setSummary(
AndroidUtils.getString("current_download_folder") + " " + Preferences.getVideosDir()
);
findPreference("music_directory").setSummary(
AndroidUtils.getString("current_download_folder") + " " + Preferences.getMusicDir()
);
findPreference("downloads_directory").setOnPreferenceClickListener(preference -> {
var intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivityForResult(intent, REQUEST_CODE_SET_DOWNLOAD_DIRECTORY);
return true;
});
findPreference("photos_directory").setOnPreferenceClickListener(preference -> {
var intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivityForResult(intent, REQUEST_CODE_SET_PHOTOS_DIRECTORY);
return true;
});
findPreference("videos_directory").setOnPreferenceClickListener(preference -> {
var intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivityForResult(intent, REQUEST_CODE_SET_VIDEOS_DIRECTORY);
return true;
});
findPreference("music_directory").setOnPreferenceClickListener(preference -> {
var intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivityForResult(intent, REQUEST_CODE_SET_MUSIC_DIRECTORY);
return true;
});
if (isLoggedIn()) {
findPreference("lastfm_auth").setSummary("Вы авторизованы как " + Scrobbler.getUserName());
findPreference("lastfm_auth").setSummary(AndroidUtils.getString("lastfm_authorized_as") + " " + Scrobbler.getUserName());
} else {
findPreference("lastfm_enabled").setEnabled(false);
}
@@ -192,6 +185,103 @@ public class MediaFragment extends MaterialPreferenceToolbarFragment {
});
}
private void lastfmAuth(Context ctx) {
LinearLayout linearLayout = new LinearLayout(ctx);
linearLayout.setOrientation(LinearLayout.VERTICAL);
final EditText fn = new EditText(ctx);
fn.setHint(AndroidUtils.getString("lastfm_login"));
fn.setTextColor(getTextAttr());
fn.setHintTextColor(getSTextAttr());
fn.setBackgroundTintList(ColorStateList.valueOf(getAccentColor()));
linearLayout.addView(fn);
fn.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
ViewGroup.MarginLayoutParams margin = ((ViewGroup.MarginLayoutParams) fn.getLayoutParams());
margin.setMargins(dp2px(20f), 0, dp2px(20f), 0);
fn.setLayoutParams(margin);
final EditText ln = new EditText(ctx);
ln.setHint(AndroidUtils.getString("lastfm_password"));
ln.setTextColor(getTextAttr());
ln.setHintTextColor(getSTextAttr());
ln.setBackgroundTintList(ColorStateList.valueOf(getAccentColor()));
linearLayout.addView(ln);
ln.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
ln.setLayoutParams(margin);
AlertDialog.Builder alertDialog = new AlertDialog.Builder(ctx, getAlertStyle());
alertDialog.setTitle(AndroidUtils.getString("lastfm_enter_credentials"));
alertDialog.setView(linearLayout);
alertDialog.setPositiveButton(AndroidUtils.getString("lastfm_enter"), (dialog, which) -> {
String login = fn.getText().toString();
String pass = ln.getText().toString();
Scrobbler.auth(login, pass);
});
var alert = alertDialog.create();
alert.show();
alert.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(getAccentColor());
}
private void logout(Context ctx) {
VkAlertDialog.Builder alertDialog = new VkAlertDialog.Builder(ctx);
alertDialog.setTitle(AndroidUtils.getString("lastfm_logout_title"));
alertDialog.setMessage(AndroidUtils.getString("lastfm_logout_confirm"));
alertDialog.setPositiveButton(AndroidUtils.getString("vkim_yes"), (dialog, which) -> {
Scrobbler.logout();
});
alertDialog.setNeutralButton(AndroidUtils.getString("vkim_no"), (dialog, which) -> {
dialog.cancel();
});
var alert = alertDialog.create();
alert.show();
alert.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(getAccentColor());
alert.getButton(DialogInterface.BUTTON_NEUTRAL).setTextColor(getResources().getColor(com.vtosters.lite.R.color.red));
}
public static void deleteVideoHistory() {
Thread thread = new Thread(() -> {
try {
var request = new Request.a()
.b("https://api.vk.com/method/" + "video.clearViewingHistoryRecords" + "?https=1" + "&access_token=" + getUserToken() + "&v=5.187")
.a(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8"))
.a();
try {
var response = new OkHttpClient().a(request).execute().a().g();
Log.d("VideoHistory", response);
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
});
thread.start();
sendToast(AndroidUtils.getString("video_history_cleaned"));
}
public static void download(Context ctx) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(ctx, getAlertStyle());
alertDialog.setTitle(AndroidUtils.getString("video_dl_enter_link"));
final EditText input = new EditText(ctx);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
input.setLayoutParams(lp);
input.setTextColor(getTextAttr());
input.setBackgroundTintList(ColorStateList.valueOf(getAccentColor()));
alertDialog.setView(input);
alertDialog.setPositiveButton(AndroidUtils.getString("download"), (dialog, which) -> VideoDownloader.parseVideoLink(input.getText().toString(), ctx));
var alert = alertDialog.create();
alert.show();
alert.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(getAccentColor());
}
private class download implements Preference.OnPreferenceClickListener {
@Override // android.support.v7.preference.Preference.c
public boolean onPreferenceClick(Preference preference) {
@@ -1,11 +1,14 @@
package ru.vtosters.lite.ui.fragments;
import static ru.vtosters.lite.utils.AndroidUtils.*;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
import static ru.vtosters.lite.utils.LifecycleUtils.restartApplicationWithTimer;
import static ru.vtosters.lite.utils.Preferences.autoalltranslate;
import static ru.vtosters.lite.utils.Preferences.offline;
import static ru.vtosters.lite.utils.Preferences.vkme;
import static ru.vtosters.lite.utils.ThemesUtils.*;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@@ -19,9 +22,12 @@ import com.vk.navigation.Navigator;
import com.vtosters.lite.general.fragments.MaterialPreferenceToolbarFragment;
import java.util.Arrays;
import java.util.Objects;
import ru.vtosters.lite.ui.adapters.ImagineArrayAdapter;
import ru.vtosters.lite.ui.wallpapers.WallpaperMenuFragment;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.ThemesUtils;
public class MessagesFragment extends MaterialPreferenceToolbarFragment {
@Override
@@ -31,6 +37,7 @@ public class MessagesFragment extends MaterialPreferenceToolbarFragment {
prefs();
}
@SuppressLint("UseCompatLoadingForDrawables")
private void prefs() {
findPreference("vkme").setOnPreferenceClickListener(new MessagesFragment.restart());
findPreference("vkme_notifs").setOnPreferenceClickListener(new MessagesFragment.restart());
@@ -50,7 +57,7 @@ public class MessagesFragment extends MaterialPreferenceToolbarFragment {
.create();
var listView = (ListView) LayoutInflater.from(getContext()).inflate(com.vtosters.lite.R.layout.abc_select_dialog_material, null, false);
var adapter = new ImagineArrayAdapter(getContext(), items, i -> {
var adapter = new ImagineArrayAdapter(requireContext(), items, i -> {
getPreferences().edit().putInt("translator", i).apply();
alert.dismiss();
});
@@ -61,15 +68,20 @@ public class MessagesFragment extends MaterialPreferenceToolbarFragment {
return true;
});
findPreference("vkme_notifs").setEnabled(vkme());
findPreference("wallpapers").setIcon(recolorDrawable(getGlobalContext().getDrawable(getIdentifier("ic_media_outline_28", "drawable"))));
findPreference("vkme").setIcon(getIdentifier("ic_vkme_28", "drawable"));
}
@Override
public boolean onPreferenceTreeClick(Preference preference) {
findPreference("autotranslate").setEnabled(!autoalltranslate());
findPreference("vkme_notifs").setEnabled(vkme());
return super.onPreferenceTreeClick(preference);
}
public boolean restart(Preference preference) {
public boolean restart() {
restartApplicationWithTimer();
return true;
}
@@ -77,14 +89,14 @@ public class MessagesFragment extends MaterialPreferenceToolbarFragment {
public class restart implements Preference.OnPreferenceClickListener {
@Override
public boolean onPreferenceClick(Preference preference) {
return MessagesFragment.this.restart(preference);
return MessagesFragment.this.restart();
}
}
public class clearCache implements Preference.OnPreferenceClickListener {
@Override
public boolean onPreferenceClick(Preference preference) {
return MessagesFragment.this.restart(preference);
return MessagesFragment.this.restart();
}
}
@@ -9,6 +9,7 @@ import static ru.vtosters.lite.ui.components.BackupManager.deletePrefs;
import static ru.vtosters.lite.ui.components.BackupManager.restoreBackup;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.AndroidUtils.getDefaultPrefs;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.CacheUtils.deleteCache;
@@ -76,7 +77,7 @@ public class OtherFragment extends MaterialPreferenceToolbarFragment {
String token = data.getStringExtra("token");
AndroidUtils.getPreferences().edit().putString("vk_admin_token", token).apply();
Log.d("VkAdminToken", token);
Toast.makeText(getContext(), "Токен успешно сохранён", LENGTH_SHORT).show();
Toast.makeText(getContext(), AndroidUtils.getString("token_saved"), LENGTH_SHORT).show();
}
}
}
@@ -95,25 +96,31 @@ public class OtherFragment extends MaterialPreferenceToolbarFragment {
return true;
});
findPreference("resetfolders").setOnPreferenceClickListener(preference -> {
edit().remove("photos_directory").remove("videos_directory").remove("audios_directory").remove("downloads_directory").apply();
Toast.makeText(getContext(), AndroidUtils.getString("download_folders_reseted"), LENGTH_SHORT).show();
return true;
});
var pref = getDefaultPrefs().getString("autoclearcache", "Default");
switch (pref) {
case "Default":
findPreference("autoclearcache").setSummary("Не включено");
findPreference("autoclearcache").setSummary(AndroidUtils.getString("cache_disabled"));
break;
case "100mb":
findPreference("autoclearcache").setSummary("Очищать кеш при не менее 100 Мб");
findPreference("autoclearcache").setSummary(AndroidUtils.getString("cache_100mb"));
break;
case "500mb":
findPreference("autoclearcache").setSummary("Очищать кеш при не менее 500 Мб");
findPreference("autoclearcache").setSummary(AndroidUtils.getString("cache_500mb"));
break;
case "1gb":
findPreference("autoclearcache").setSummary("Очищать кеш при не менее 1 Гб");
findPreference("autoclearcache").setSummary(AndroidUtils.getString("cache_1gb"));
break;
case "2gb":
findPreference("autoclearcache").setSummary("Очищать кеш при не менее 2 Гб");
findPreference("autoclearcache").setSummary(AndroidUtils.getString("cache_2gb"));
break;
case "5gb":
findPreference("autoclearcache").setSummary("Очищать кеш при не менее 5 Гб");
findPreference("autoclearcache").setSummary(AndroidUtils.getString("cache_5gb"));
break;
}
@@ -185,12 +192,12 @@ public class OtherFragment extends MaterialPreferenceToolbarFragment {
five.setChecked(val == 5);
VkAlertDialog.Builder builder = new VkAlertDialog.Builder(getContext());
builder.setTitle("Очистка кеша");
builder.setMessage("Выберите объём кеша для очистки");
builder.setTitle(AndroidUtils.getString("cache_clean_title"));
builder.setMessage(AndroidUtils.getString("cache_select_size"));
builder.setCancelable(true);
builder.setNegativeButton("Отмена", null);
builder.setNegativeButton(AndroidUtils.getString("cancel"), null);
builder.setView(rg);
builder.setPositiveButton("Сохранить", (dialog, which) -> {
builder.setPositiveButton(AndroidUtils.getString("save"), (dialog, which) -> {
var pref = getDefaultPrefs().edit();
var checked = rg.getCheckedRadioButtonId();
@@ -221,8 +228,8 @@ public class OtherFragment extends MaterialPreferenceToolbarFragment {
private void cacheCleanDialog() {
VkAlertDialog.Builder builder = new VkAlertDialog.Builder(getContext());
builder.setTitle("Выберите что вы хотите очистить");
builder.setItems(new String[]{"Очистить весь кеш", "Очистить кеш стикеров", "Очистить кеш изображений", "Очистить кеш видео", "Очистить кеш сообщений", "Очистить кеш WebView"}, (dialog, which) -> {
builder.setTitle(AndroidUtils.getString("select_which_clean"));
builder.setItems(AndroidUtils.getArray("cache_cleaner"), (dialog, which) -> {
switch (which) {
case 0: {
SharedPreferences prefs2 = getContext().getSharedPreferences("stickers_storage", Context.MODE_PRIVATE);
@@ -237,7 +244,6 @@ public class OtherFragment extends MaterialPreferenceToolbarFragment {
ImEngineExt.a(ImEngine1.a());
AutoPlayCacheHolder.d.a();
MediaStorage.a();
deleteCache();
break;
}
case 1: {
@@ -264,7 +270,7 @@ public class OtherFragment extends MaterialPreferenceToolbarFragment {
break;
}
Toast.makeText(getContext(), "Кеш очищен", LENGTH_SHORT).show();
Toast.makeText(getContext(), AndroidUtils.getString("cache_cleaned"), LENGTH_SHORT).show();
});
builder.create().show();
}
@@ -283,7 +289,7 @@ public class OtherFragment extends MaterialPreferenceToolbarFragment {
try {
backupOnlines();
} catch (IOException e) {
Toast.makeText(getContext(), "Нет данных для резервного копирования", LENGTH_SHORT).show();
Toast.makeText(getContext(), AndroidUtils.getString("no_data_to_backup"), LENGTH_SHORT).show();
}
return true;
}
@@ -353,14 +359,14 @@ public class OtherFragment extends MaterialPreferenceToolbarFragment {
var arr = BackupManager.getBackupsNames();
var adapter = new ArrayAdapter(getContext(), android.R.layout.simple_list_item_1, arr);
new VkAlertDialog.Builder(getContext())
.setTitle("Выберите бэкап")
.setTitle(AndroidUtils.getString("select_backup"))
.setAdapter(adapter, (dialog, which) -> {
try {
restoreBackup(arr[which]);
Toast.makeText(getContext(), "Настройки восстановлены", LENGTH_LONG).show();
Toast.makeText(getContext(), AndroidUtils.getString("backup_success"), LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getContext(), "Ошибка, Настройки не восстановлены", LENGTH_LONG).show();
Toast.makeText(getContext(), AndroidUtils.getString("backup_error"), LENGTH_LONG).show();
}
}).create().show();
return true;
@@ -1,15 +1,30 @@
package ru.vtosters.lite.ui.fragments;
import static ru.vtosters.lite.proxy.RandomProxy.setupNewProxy;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
import android.os.Bundle;
import com.vtosters.lite.general.fragments.MaterialPreferenceToolbarFragment;
import java.io.IOException;
import ru.vtosters.lite.proxy.RandomProxy;
public class ProxySettingsFragment extends MaterialPreferenceToolbarFragment {
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
addPreferencesFromResource(getIdentifier("preferences_proxy", "xml"));
findPreference("random_proxy").setOnPreferenceClickListener(preference -> {
try {
setupNewProxy();
} catch (IOException e) {
sendToast("Ошибка при получении прокси");
}
return true;
});
}
}
@@ -4,6 +4,7 @@ import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.LifecycleUtils.restartApplication;
import android.os.Build;
import android.os.Bundle;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
@@ -46,9 +47,9 @@ public class SuperAppEditorFragment extends BaseToolbarFragment {
message.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
message.setTextColor(ThemesUtils.getTextAttr());
message.setPadding(
AndroidUtils.dp2px(10),
AndroidUtils.dp2px(10),
AndroidUtils.dp2px(10),
dp2px(10),
dp2px(10),
dp2px(10),
0
);
container.addView(message, LayoutUtils.createLinear(-1, -2));
@@ -94,16 +95,29 @@ public class SuperAppEditorFragment extends BaseToolbarFragment {
: manager.getDisabledTabs().get(pos - manager.getSelectedTabs().size() - 2);
holder.bindMovingItem(item.title);
});
manager.getSelectedTabs().forEach(item -> {
if (item.type.equals("menu"))
adapter.addUnmovedItem(item);
});
manager.getDisabledTabs().forEach(item -> {
if (item.type.equals("menu"))
adapter.addUnmovedItem(item);
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
manager.getSelectedTabs().forEach(item -> {
if (item.type.equals("menu"))
adapter.addUnmovedItem(item);
});
var recyclerView = new RecyclerView(getContext());
manager.getDisabledTabs().forEach(item -> {
if (item.type.equals("menu"))
adapter.addUnmovedItem(item);
});
} else {
for (var item : manager.getSelectedTabs()) {
if (item.type.equals("menu"))
adapter.addUnmovedItem(item);
}
for (var item : manager.getDisabledTabs()) {
if (item.type.equals("menu"))
adapter.addUnmovedItem(item);
}
}
var recyclerView = new RecyclerView(requireContext());
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
recyclerView.setHasFixedSize(true);
@@ -65,8 +65,6 @@ import ru.vtosters.lite.utils.CacheUtils;
import ru.vtosters.lite.utils.SSFSUtils;
public class VTSettings extends MaterialPreferenceToolbarFragment {
public int hideitems = 0;
public static String getValAsString(String stringid, Boolean value) {
if (disableSettingsSumms()) return null;
@@ -116,7 +114,7 @@ public class VTSettings extends MaterialPreferenceToolbarFragment {
public static String getSuperappsumm() {
if (disableSettingsSumms()) return null;
return "Скрыто элементов" + ": " + SuperAppEditorManager.getInstance().getDisabledTabs().size();
return AndroidUtils.getString("elements_hidden_count") + ": " + SuperAppEditorManager.getInstance().getDisabledTabs().size();
}
public static String getCachesumm() {
@@ -332,7 +330,7 @@ public class VTSettings extends MaterialPreferenceToolbarFragment {
});
}
} else {
addPreference(this, "", "Внимание!", "Некоторые пункты настроек были скрыты из-за режима VK Me \n\nДля отключения режима перейдите в настройки Сообщений", "ic_about_outline_28", preference -> false);
addPreference(this, "", AndroidUtils.getString("debug_warning"), AndroidUtils.getString("vkme_mode_info"), "ic_about_outline_28", preference -> false);
}
addPreference(this, "", AndroidUtils.getString("vtlmedia"), mediasumm, "ic_media_outline_28", preference -> {
@@ -40,6 +40,7 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.vk.navigation.Navigator;
import java.io.File;
import java.util.Objects;
import ru.vtosters.lite.tgs.TGPref;
import ru.vtosters.lite.ui.adapters.StickerPackAdapter;
@@ -47,7 +48,6 @@ import ru.vtosters.lite.ui.fragments.BaseToolbarFragment;
import ru.vtosters.lite.utils.AndroidUtils;
public class StickersFragment extends BaseToolbarFragment {
public final static String ACTION_RELOAD = "com.vtosters.lite.action.RELOAD_TGS_LIST";
private final static int TYPE_DIRECT = 0, TYPE_SOCKS = 2;
@@ -147,7 +147,7 @@ public class StickersFragment extends BaseToolbarFragment {
@Override
public void onDestroyView() {
super.onDestroyView();
getContext().unregisterReceiver(mReceiver);
requireContext().unregisterReceiver(mReceiver);
}
private void fabClick() {
@@ -24,6 +24,7 @@ import java.util.Objects;
import kotlin.Unit;
import kotlin.jvm.b.Functions;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.RenameTool;
public class MenuBuilder {
@@ -55,17 +56,17 @@ public class MenuBuilder {
final ExtendedUserProfile eup = (ExtendedUserProfile) pfambObject.get(mb);
final Context ctx = ((View) Objects.requireNonNull(apView.get(builder))).getContext();
addItem(builder, "Скопировать ID", () -> {
addItem(builder, AndroidUtils.getString("menu_copy_id"), () -> {
copy(ctx, String.valueOf(getUserID(eup)));
return Unit.a;
});
addItem(builder, "Дополнительная информация", () -> {
addItem(builder, AndroidUtils.getString("menu_addon_info"), () -> {
loadAndShow(ctx, getUserID(eup));
return Unit.a;
});
addItem(builder, "Изменить имя", () -> {
addItem(builder, AndroidUtils.getString("menu_change_name"), () -> {
RenameTool.createDialog(eup, ctx);
return Unit.a;
});
@@ -80,12 +81,12 @@ public class MenuBuilder {
final ExtendedCommunityProfile ecp = (ExtendedCommunityProfile) cfambObject.get(mb);
final Context ctx = ((View) apView.get(builder)).getContext();
addItem(builder, "Скопировать ID", () -> {
addItem(builder, AndroidUtils.getString("menu_copy_id"), () -> {
copy(ctx, String.valueOf(getUserID(ecp)));
return Unit.a;
});
addItem(builder, "Изменить имя", () -> {
addItem(builder, AndroidUtils.getString("menu_change_name"), () -> {
RenameTool.createDialogGroup(ecp, ctx);
return Unit.a;
});
@@ -100,7 +101,7 @@ public class MenuBuilder {
ClipData clip = ClipData.newPlainText("MBH-ST", txt);
clipboard.setPrimaryClip(clip);
sendToast("Скопировано!");
sendToast(AndroidUtils.getString("menu_copied"));
}
public static void addItem(final ActionsPopup.b builder, final String title, final Functions onClick) throws InvocationTargetException, IllegalAccessException {
@@ -0,0 +1,50 @@
package ru.vtosters.lite.ui.vkui;
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
import static ru.vtosters.lite.utils.ThemesUtils.getTextAttr;
import android.content.Context;
import android.util.TypedValue;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import java.util.List;
public class VBListBuilder{
public static ViewGroup buildListOf(Context ctx, List<VBListItem> items){
LinearLayout mainView = new LinearLayout(ctx);
mainView.setOrientation(LinearLayout.VERTICAL);
mainView.setPadding(dp2px(8f), 0, dp2px(8f), 0);
for (VBListItem item : items) {
CheckBox mcb = new CheckBox(ctx, null);
mcb.setPadding(0, dp2px(8f), 0, dp2px(8f));
mcb.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14f);
mcb.setTextColor(getTextAttr());
mcb.setChecked(item.checked);
mcb.setText(item.title);
mcb.setOnCheckedChangeListener((buttonView, isChecked) -> {
item.checked = isChecked;
});
mainView.addView(mcb);
}
return mainView;
}
public static class VBListItem{
public String id;
public String title;
public boolean checked;
public VBListItem(String id, String title, boolean checked){
this.id = id;
this.title = title;
this.checked = checked;
}
}
}
@@ -31,6 +31,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import ru.vtosters.lite.ui.PreferencesUtil;
import ru.vtosters.lite.utils.AndroidUtils;
public class WallpaperMenuFragment extends MaterialPreferenceToolbarFragment {
@@ -56,20 +57,20 @@ public class WallpaperMenuFragment extends MaterialPreferenceToolbarFragment {
int vtosterXml = getIdentifier("empty", "xml");
addPreferencesFromResource(vtosterXml);
PreferencesUtil.addPreferenceCategory(this, "Предпросмотр");
PreferencesUtil.addPreferenceCategory(this, AndroidUtils.getString("vkim_settings_appearance_chat_preview_title"));
mWPPreviewPref = new WallpaperPreferences(getContext());
mWPPreviewPref.setIcon(null);
mWPPreviewPref.setIconSpaceReserved(false);
getPreferenceScreen().addPreference(mWPPreviewPref);
PreferencesUtil.addPreference(this, "wp_set", "Выбрать обои", "из галереи", "ic_picture_outline_28", preference -> {
PreferencesUtil.addPreference(this, "wp_set", AndroidUtils.getString("wallpaper_select"), AndroidUtils.getString("wallpaper_from_gallery"), "ic_picture_outline_28", preference -> {
startActivityForResult(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI), 1488);
removeStickCache();
return true;
});
PreferencesUtil.addPreference(this, "wp_clear", "Удалить обои", "", "ic_delete_outline_28", preference -> {
PreferencesUtil.addPreference(this, "wp_clear", AndroidUtils.getString("wallpaper_remove"), "", "ic_delete_outline_28", preference -> {
removeWallpaper();
requestUpdateWallpaper();
mWPPreviewPref.redraw();
@@ -77,36 +78,30 @@ public class WallpaperMenuFragment extends MaterialPreferenceToolbarFragment {
return true;
});
PreferencesUtil.addPreferenceCategory(this, "Фильтры");
PreferencesUtil.addPreferenceCategory(this, AndroidUtils.getString("vtlfilters"));
if (!hasVerification() && !getBoolValue("dialogrecomm", false)) {
PreferencesUtil.addPreference(this, "", "Доступны не все фильтры!", "Для разблокировки необходимо сделать пожертование от 99р", null, preference -> {
getContext().startActivity(new Intent("android.intent.action.VIEW").setData(Uri.parse("https://vtosters.app")));
PreferencesUtil.addPreference(this, "", AndroidUtils.getString("filters_warning"), AndroidUtils.getString("icons_warning_info"), null, preference -> {
getContext().startActivity(new Intent("android.intent.action.VIEW").setData(Uri.parse("https://vtosters.app/donate/")));
return false;
});
}
PreferencesUtil.addListPreference(this, "msg_blur_radius", "disabled", "Размытие фона сообщений", new CharSequence[]{
"Отключено", "Низкое (15px)", "Среднее (25px)", "Высокое (50px)"
}, new String[]{
PreferencesUtil.addListPreference(this, "msg_blur_radius", "disabled", AndroidUtils.getString("filter_blur"), AndroidUtils.getArray("filter_types"), new String[]{
"disabled", "low", "med", "high"
});
PreferencesUtil.addListPreference(this, "msg_dim", "off", "Затемнение изображения", new CharSequence[]{
"Отключено", "Затемнить", "Осветлить"
}, new String[]{
PreferencesUtil.addListPreference(this, "msg_dim", "off", AndroidUtils.getString("filter_dim"), AndroidUtils.getArray("filter_dim_types"), new String[]{
"off", "dim_black", "dim_white"
});
PreferencesUtil.addListPreference(this, "msg_mosaic", "disabled", "Мозаика", new CharSequence[]{
"Отключено", "Низкое", "Среднее", "Высокое"
}, new String[]{
PreferencesUtil.addListPreference(this, "msg_mosaic", "disabled", AndroidUtils.getString("filter_mosaic"), AndroidUtils.getArray("filter_types"), new String[]{
"disabled", "low", "med", "high"
});
if (hasVerification()) {
PreferencesUtil.addMaterialSwitchPreference(this, "msg_monochrome", "Черно-белый фон", "", null, false, (preference, o) -> {
PreferencesUtil.addMaterialSwitchPreference(this, "msg_monochrome", AndroidUtils.getString("filter_monochrome"), "", null, false, (preference, o) -> {
boolean value = (boolean) o;
edit().putBoolean("msg_monochrome", value).commit();
requestUpdateWallpaper();
@@ -114,7 +109,7 @@ public class WallpaperMenuFragment extends MaterialPreferenceToolbarFragment {
return true;
});
PreferencesUtil.addMaterialSwitchPreference(this, "msg_invert", "Инвертировать цвета", "", null, false, (preference, o) -> {
PreferencesUtil.addMaterialSwitchPreference(this, "msg_invert", AndroidUtils.getString("filter_invert_colors"), "", null, false, (preference, o) -> {
boolean value = (boolean) o;
edit().putBoolean("msg_invert", value).commit();
requestUpdateWallpaper();
@@ -122,7 +117,7 @@ public class WallpaperMenuFragment extends MaterialPreferenceToolbarFragment {
return true;
});
PreferencesUtil.addMaterialSwitchPreference(this, "msg_sepia", "Эффект сепии", "", null, false, (preference, o) -> {
PreferencesUtil.addMaterialSwitchPreference(this, "msg_sepia", AndroidUtils.getString("filter_sepia"), "", null, false, (preference, o) -> {
boolean value = (boolean) o;
edit().putBoolean("msg_sepia", value).commit();
requestUpdateWallpaper();
@@ -130,7 +125,7 @@ public class WallpaperMenuFragment extends MaterialPreferenceToolbarFragment {
return true;
});
PreferencesUtil.addMaterialSwitchPreference(this, "msg_emboss", "Emboss фильтр", "Возможна нагрузка на устройство", null, false, (preference, o) -> {
PreferencesUtil.addMaterialSwitchPreference(this, "msg_emboss", AndroidUtils.getString("filter_emboss"), AndroidUtils.getString("filter_maybe_lag"), null, false, (preference, o) -> {
boolean value = (boolean) o;
edit().putBoolean("msg_emboss", value).commit();
requestUpdateWallpaper();
@@ -138,7 +133,7 @@ public class WallpaperMenuFragment extends MaterialPreferenceToolbarFragment {
return true;
});
PreferencesUtil.addMaterialSwitchPreference(this, "msg_engrave", "Engrave фильтр", "Возможна нагрузка на устройство", null, false, (preference, o) -> {
PreferencesUtil.addMaterialSwitchPreference(this, "msg_engrave", AndroidUtils.getString("filter_engrave"), AndroidUtils.getString("filter_maybe_lag"), null, false, (preference, o) -> {
boolean value = (boolean) o;
edit().putBoolean("msg_engrave", value).commit();
requestUpdateWallpaper();
@@ -146,7 +141,7 @@ public class WallpaperMenuFragment extends MaterialPreferenceToolbarFragment {
return true;
});
PreferencesUtil.addMaterialSwitchPreference(this, "msg_flea", "Flea фильтр", "", null, false, (preference, o) -> {
PreferencesUtil.addMaterialSwitchPreference(this, "msg_flea", AndroidUtils.getString("filter_flea"), "", null, false, (preference, o) -> {
boolean value = (boolean) o;
edit().putBoolean("msg_flea", value).commit();
requestUpdateWallpaper();
@@ -154,7 +149,7 @@ public class WallpaperMenuFragment extends MaterialPreferenceToolbarFragment {
return true;
});
PreferencesUtil.addMaterialSwitchPreference(this, "msg_snow", "Эффект снега", "", null, false, (preference, o) -> {
PreferencesUtil.addMaterialSwitchPreference(this, "msg_snow", AndroidUtils.getString("filter_flea"), "", null, false, (preference, o) -> {
boolean value = (boolean) o;
edit().putBoolean("msg_snow", value).commit();
requestUpdateWallpaper();
@@ -223,7 +218,6 @@ public class WallpaperMenuFragment extends MaterialPreferenceToolbarFragment {
private void removeStickCache() {
SharedPreferences prefs2 = getContext().getSharedPreferences("stickers_storage", Context.MODE_PRIVATE);
prefs2.edit().clear().apply();
deleteCache();
ImEngineProvider.b().a();
}
@@ -5,6 +5,7 @@ import static ru.vtosters.lite.ui.wallpapers.WallpapersHooks.getWallpaperFile;
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
@@ -64,6 +65,7 @@ public class WallpaperPreferences extends Preference {
mChatBackground.setImageDrawable(null);
}
@SuppressLint("NotifyDataSetChanged")
void redraw() {
mAdapter.notifyDataSetChanged();
requestBg();

Some files were not shown because too many files have changed in this diff Show More