Compare commits

...
Author SHA1 Message Date
gdlbo e2775db4e5 fixed english translation 2023-10-12 20:19:17 +03:00
gdlbo 589e8928a0 Bitrate upgrade (#1498)
libvkmedia.so armv7/arm64
2023-10-12 19:57:00 +03:00
gdlbo cd189b1dda fixed id3v2 meta 2023-10-10 23:15:11 +03:00
gdlbo 14c111a3e6 some music fixes 2023-10-10 22:53:16 +03:00
gdlbo b506c56346 fixed compiling issue 2023-10-07 03:13:24 +03:00
gdlbo bbbc94e510 added facebook graph disabler 2023-10-07 03:07:31 +03:00
gdlbo 8cb2c380e7 fixed adding "null" to track name 2023-10-06 12:44:55 +03:00
gdlbo b9879f9ed7 updated appcenter 2023-10-04 19:44:24 +03:00
gdlbo cf05e051e8 added summary for advanced online info 2023-10-04 13:47:47 +03:00
gdlbo 963c4d81ba upped ver 2023-10-04 13:37:20 +03:00
gdlbo 099c699702 added vkn online fix disabler 2023-10-04 13:37:07 +03:00
gdlbo 1117fc19d4 added force tablet mode 2023-10-02 16:28:08 +03:00
gdlbo 78dca26063 fix #1489 2023-10-02 14:52:52 +03:00
gdlbo f5180f61d5 fixed empty text from ssfs 2023-09-30 14:37:49 +03:00
gdlbo 540fffdcc9 fixed download issue 2023-09-30 03:15:14 +03:00
gdlbo 5357c60eaa Update TelegramStickersGrabber.java 2023-09-30 02:33:52 +03:00
gdlbo c59f29121f Refactoted Telegram Stickers downloader and settings (#1485) 2023-09-29 19:58:33 +03:00
gdlbo bd38cab377 autoupdated disabler 2023-09-28 17:40:49 +03:00
gdlbo 0058431590 deleted useless summ and updated translation 2023-09-28 17:01:38 +03:00
gdlbo bf4cf2be53 adfree + free from server connection (#1481) 2023-09-28 16:10:30 +03:00
gdlbo aac86a9952 Update InstallGMSFragment.java
added inotia00 microg information
2023-09-28 11:09:40 +03:00
gdlbo ae00e72bac added more microg instructions 2023-09-27 23:55:56 +03:00
gdlbo fea984f6fd fixed null foaf crash app 2023-09-27 23:34:37 +03:00
gdlbo d870c2f984 Update VTSettings.java 2023-09-27 22:12:12 +03:00
50 changed files with 639 additions and 1071 deletions
+2 -2
View File
@@ -91,8 +91,8 @@ task testClasses {
}
dependencies {
implementation 'com.microsoft.appcenter:appcenter-analytics:5.0.1'
implementation 'com.microsoft.appcenter:appcenter-crashes:5.0.1'
implementation 'com.microsoft.appcenter:appcenter-analytics:5.0.2'
implementation 'com.microsoft.appcenter:appcenter-crashes:5.0.2'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
implementation 'net.sourceforge.streamsupport:streamsupport-minifuture:1.7.4'
implementation 'com.google.guava:guava:23.3-android'
@@ -36,8 +36,8 @@ public class TelegramStickersPack extends CustomStickersPack {
public HashMap<String, List<Integer>> emojis = new HashMap<>();
public TelegramStickersPack(String id) {
this.id=this.title=id;
this.hash=id.hashCode();
this.id = this.title = id;
this.hash = id.hashCode();
}
public JSONObject encodeEmojis() throws JSONException {
@@ -26,19 +26,13 @@ import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
public class TelegramStickersService {
private static final String TAG = "TGStickersService";
private static TelegramStickersService instance;
private final Context c;
private final ArrayList<TelegramStickersPack> packs;
private final ArrayList<TelegramStickersPack> activePacks;
private final ArrayList<TelegramStickersPack> inactivePacks;
private final ArrayList<StickersEventsListener> listeners;
private final HashSet<String> currentlyDownloading;
private final Handler uiThreadHandler;
private final TelegramStickersGrabber grabber;
private final TelegramStickersDbHelper dbHelper;
private final ArrayList<Runnable> queuedTasks;
private final ThreadPoolExecutor executor;
@@ -48,16 +42,14 @@ public class TelegramStickersService {
private TelegramStickersService(Context context) {
instance = this;
this.c = context.getApplicationContext();
listeners = new ArrayList<>();
currentlyDownloading = new HashSet<>();
uiThreadHandler = new Handler(Looper.getMainLooper());
grabber = new TelegramStickersGrabber(null);
dbHelper = new TelegramStickersDbHelper(c);
dbHelper = new TelegramStickersDbHelper(context);
queuedTasks = new ArrayList<>();
executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
notificationsHelper = new NotificationsHelper(c);
notificationsHelper = new NotificationsHelper(context);
packs = new ArrayList<>();
activePacks = new ArrayList<>();
@@ -70,11 +62,11 @@ public class TelegramStickersService {
return instance == null ? new TelegramStickersService(c) : instance;
}
private void updatePacks(final boolean notify) {
private void updatePacks(boolean notify) {
packs.clear();
dbHelper.getAllPacks(new TelegramStickersDbHelper.PacksLoadingListener() {
@Override
public void onPackLoaded(final TelegramStickersPack pack) {
public void onPackLoaded(TelegramStickersPack pack) {
runOnUiThread(() -> {
packs.add(pack);
@@ -103,14 +95,6 @@ public class TelegramStickersService {
});
}
public void addStickersEventsListener(StickersEventsListener listener) {
listeners.add(listener);
}
public void removeStickersEventsListener(StickersEventsListener listener) {
listeners.remove(listener);
}
private void notifyPackAdded(TelegramStickersPack pack, int atIndex) {
getGlobalContext().sendBroadcast(new Intent(StickersFragment.ACTION_RELOAD));
if (listeners.isEmpty())
@@ -188,20 +172,16 @@ public class TelegramStickersService {
return inactivePacks;
}
public boolean isDoneLoading() {
return ready;
}
public boolean requestPackDownload(final String id, File packFolder) {
public void requestPackDownload(String id, File packFolder) {
if (currentlyDownloading.contains(id)) {
Log.e(TAG, String.format("Got request to download pack %s which is already downloading", id));
return false;
return;
}
if (!ready) {
final File folder = packFolder;
File folder = packFolder;
queuedTasks.add(() -> requestPackDownload(id, folder));
return true;
return;
}
TelegramStickersPack pack = new TelegramStickersPack(id);
@@ -221,85 +201,86 @@ public class TelegramStickersService {
notifyPackAdded(pack, packs.size() - 1);
}
final TelegramStickersPack newPack = pack;
final boolean isUpdate = update;
TelegramStickersPack newPack = pack;
boolean isUpdate = update;
currentlyDownloading.add(id);
notificationsHelper.packStartedDownloading(newPack);
grabber.enableProxy();
grabber.grabPack(id, packFolder, pack.version, new TelegramStickersGrabber.PackDownloadListener() {
@Override
public void onPackDownloaded(TelegramStickersPackInfo packInfo, boolean newVersionFound) {
runOnUiThread(() -> {
newPack.state = TelegramStickersPack.DOWNLOADED;
notifyPackChanged(newPack, packs.indexOf(newPack));
currentlyDownloading.remove(newPack.id);
syncPack(newPack);
if (isUpdate) {
if (newPack.enabled)
notifyActivePacksListChanged();
} else {
activePacks.add(newPack);
notifyActivePacksListChanged();
}
});
notificationsHelper.packDoneDownloading(newPack, true, isUpdate, null);
}
@Override
public void onPackDownloadError(final Exception e) {
runOnUiThread(() -> {
Log.e(TAG, "Error while downloading pack " + newPack.id);
e.printStackTrace();
if (!isUpdate) {
int index = packs.indexOf(newPack);
packs.remove(index);
notifyPackRemoved(newPack, index);
} else {
// try-catch block to handle possible timeout exception
try {
grabber.grabPack(id, packFolder, pack.version, new TelegramStickersGrabber.PackDownloadListener() {
@Override
public void onPackDownloaded(TelegramStickersPackInfo packInfo, boolean newVersionFound) {
runOnUiThread(() -> {
newPack.state = TelegramStickersPack.DOWNLOADED;
notifyPackChanged(newPack, packs.indexOf(newPack));
}
currentlyDownloading.remove(newPack.id);
syncPack(newPack);
notifyPackDownloadError(newPack, e);
currentlyDownloading.remove(newPack.id);
});
notificationsHelper.packDoneDownloading(newPack, false, isUpdate, e);
}
if (isUpdate) {
if (newPack.enabled)
notifyActivePacksListChanged();
} else {
activePacks.add(newPack);
notifyActivePacksListChanged();
}
});
notificationsHelper.packDoneDownloading(newPack, true, isUpdate, null);
}
@Override
public void onGotPackInfo(final TelegramStickersPackInfo packInfo) {
runOnUiThread(() -> {
newPack.title = packInfo.title;
newPack.stickersCount = packInfo.stickersCount;
newPack.version = packInfo.version;
notifyPackChanged(newPack, packs.indexOf(newPack));
});
@Override
public void onPackDownloadError(Exception e) {
runOnUiThread(() -> {
Log.e(TAG, "Error while downloading pack " + newPack.id);
e.printStackTrace();
notificationsHelper.packDownloadUpdated(newPack, 0);
}
if (!isUpdate) {
int index = packs.indexOf(newPack);
packs.remove(index);
notifyPackRemoved(newPack, index);
} else {
newPack.state = TelegramStickersPack.DOWNLOADED;
notifyPackChanged(newPack, packs.indexOf(newPack));
}
@Override
public void onStickerDownloaded(String pack, File sticker, String boundEmoji, int stickerIndex, int downloadedStickersCount, int totalStickersCount) {
stickerIndex--;
notifyPackDownloadError(newPack, e);
currentlyDownloading.remove(newPack.id);
});
notificationsHelper.packDoneDownloading(newPack, false, isUpdate, e);
}
List<Integer> list = newPack.emojis.get(boundEmoji);
if (list == null) list = new ArrayList<>();
list.add(stickerIndex);
newPack.emojis.put(boundEmoji, list);
@Override
public void onGotPackInfo(TelegramStickersPackInfo packInfo) {
runOnUiThread(() -> {
newPack.title = packInfo.title;
newPack.stickersCount = packInfo.stickersCount;
newPack.version = packInfo.version;
notifyPackChanged(newPack, packs.indexOf(newPack));
});
notificationsHelper.packDownloadUpdated(newPack, downloadedStickersCount);
}
});
notificationsHelper.packDownloadUpdated(newPack, 0);
}
return true;
@Override
public void onStickerDownloaded(String pack, File sticker, String boundEmoji, int stickerIndex, int downloadedStickersCount, int totalStickersCount) {
stickerIndex--;
List<Integer> list = newPack.emojis.get(boundEmoji);
if (list == null) list = new ArrayList<>();
list.add(stickerIndex);
newPack.emojis.put(boundEmoji, list);
notificationsHelper.packDownloadUpdated(newPack, downloadedStickersCount);
}
});
} catch (Exception e) {
// handle other possible exceptions
e.printStackTrace();
}
}
public void setPackEnabled(final TelegramStickersPack pack, final boolean enabled, final boolean notify) {
public void setPackEnabled(TelegramStickersPack pack, boolean enabled, boolean notify) {
if (!ready) {
queuedTasks.add(() -> setPackEnabled(pack, enabled, notify));
return;
@@ -325,7 +306,7 @@ public class TelegramStickersService {
}
}
public void deletePack(final TelegramStickersPack pack) {
public void deletePack(TelegramStickersPack pack) {
if (!ready) {
queuedTasks.add(() -> deletePack(pack));
return;
@@ -334,7 +315,6 @@ public class TelegramStickersService {
boolean d = dbHelper.deletePack(pack);
Log.d(TAG, "Delete from DB=" + d);
int index = packs.indexOf(pack);
packs.remove(index);
notifyPackRemoved(pack, index);
@@ -355,7 +335,7 @@ public class TelegramStickersService {
uiThreadHandler.post(r);
}
private void syncPack(final TelegramStickersPack pack) {
private void syncPack(TelegramStickersPack pack) {
if (!ready) {
queuedTasks.add(() -> syncPack(pack));
return;
@@ -397,6 +377,4 @@ public class TelegramStickersService {
void onInactivePacksListChanged();
}
}
@@ -7,23 +7,20 @@ import android.os.Looper;
import android.util.Log;
import com.aefyr.tsg.g2.stickersgrabber.util.Flag;
import com.aefyr.tsg.g2.stickersgrabber.util.GoalCounter;
import okhttp3.*;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import ru.vtosters.lite.net.*;
import ru.vtosters.lite.di.singleton.VtOkHttpClient;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -31,14 +28,19 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
public class TelegramStickersGrabber {
private static final String TAG = "TSG";
public static String REAL_TG_IP = null;
public static String PROXY_IP = null;
public static int PROXY_PORT = -1;
public static String PROXY_USER = null;
public static String PROXY_PASS = null;
public static boolean PROXY_SOCKS = true;
public static boolean HAS_PASS = false;
public static boolean USE_PROXY = false;
private static final OkHttpClient sClient = VtOkHttpClient.getInstance();
private static final int MAX_RETRIES = 2;
private static final AtomicInteger retryCount = new AtomicInteger();
private static final int STICKER_QUALITY = 100;
private static final String STICKER_FILE_NAME_FORMAT = "%03d.png";
private static final String STICKERS_KEY = "stickers";
private static final String FILE_ID_KEY = "file_id";
private static final String EMOJI_KEY = "emoji";
private static final String IS_ANIMATED_KEY = "is_animated";
private static final String IS_VIDEO_KEY = "is_video";
private static final String THUMB_KEY = "thumb";
private static final String NAME_KEY = "name";
private static final String TITLE_KEY = "title";
private static String BOT_API_BASE_URL;
private static String GET_STICKER_SET_URL;
private static String GET_FILE_URL;
@@ -50,12 +52,10 @@ public class TelegramStickersGrabber {
private final MessageDigest sha256;
private final Handler uiThreadHandler;
private String botApiKey = "";
private NetClient httpClient;
private String botApiKey;
public TelegramStickersGrabber(String botApiKey) {
this.botApiKey = botApiKey;
httpClient = new NetClient.Builder().connectTimeout(5, TimeUnit.SECONDS).build();
uiThreadHandler = new Handler(Looper.getMainLooper());
try {
sha256 = MessageDigest.getInstance("SHA-256");
@@ -69,81 +69,12 @@ public class TelegramStickersGrabber {
public static void updateURLs() {
BOT_API_BASE_FILE_URL = "https://api.telegram.org/file/bot%s/%s";
BOT_API_BASE_URL = REAL_TG_IP != null ? "https://" + REAL_TG_IP + "/bot%s/" : "https://api.telegram.org/bot%s/";
BOT_API_BASE_URL = "https://api.telegram.org/bot%s/";
GET_STICKER_SET_URL = BOT_API_BASE_URL + "getStickerSet?name=%s";
GET_FILE_URL = BOT_API_BASE_URL + "getFile?file_id=%s";
}
public static boolean isTelegramBlocked() {
NetClient client = new NetClient.Builder().connectTimeout(5, TimeUnit.SECONDS).build();
try {
if (PROXY_IP != null) {
Socket socket = new Socket(PROXY_IP, PROXY_PORT);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, socket.getRemoteSocketAddress());
NetClient.Builder b = new NetClient.Builder().proxy(proxy);
if (PROXY_USER != null) {
b = b.proxyAuthenticator(new PasswordAuthentication(PROXY_USER, PROXY_PASS.toCharArray()));
}
client = b.build();
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
NetRequest req = new NetRequest.Builder().url(REAL_TG_IP != null ? "https://" + REAL_TG_IP + "/test/" : "https://api.telegram.org/test/").build();
try {
NetResponse res = client.newCall(req).execute();
String s = res.getDataString();
if (!s.equals("{\"ok\":false,\"error_code\":404,\"description\":\"Not Found\"}"))
return true;
} catch (Exception e) {
return true;
}
return false;
}
public void resetProxy() {
httpClient = new NetClient.Builder().connectTimeout(5, TimeUnit.SECONDS).build();
}
public void enableProxy() {
Thread kostil = new Thread() {
@Override
public void run() {
try {
if (PROXY_IP != null) {
Socket socket = new Socket(PROXY_IP, PROXY_PORT);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, socket.getRemoteSocketAddress());
NetClient.Builder b = httpClient.newBuilder().proxy(proxy);
if (PROXY_USER != null) {
httpClient = b.proxyAuthenticator(new PasswordAuthentication(PROXY_USER, PROXY_PASS.toCharArray())).build();
}
httpClient = b.build();
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
kostil.start();
try {
kostil.join();
Log.d(TAG, "Proxy set");
} catch (InterruptedException e) {
Log.e(TAG, "Unable to set proxy:");
e.printStackTrace();
}
}
public void grabPack(String id, File packFolder, String installedVersion, final PackDownloadListener listener) {
public void grabPack(String id, File packFolder, String installedVersion, PackDownloadListener listener) {
getPackInfo(id, packFolder, installedVersion, listener);
}
@@ -151,264 +82,247 @@ public class TelegramStickersGrabber {
botApiKey = key;
}
public void checkKey(final KeyCheckListener listener) {
public void checkKey(KeyCheckListener listener) {
Log.d(TAG, "Checking key: " + botApiKey);
NetRequest request = new NetRequest.Builder().get().url(String.format(BOT_API_BASE_URL + "getMe", botApiKey)).build();
httpClient.newCall(request).enqueue(new NetCallback() {
// Create a request object with the URL and bot API key
Request request = new Request.a()
.b(String.format(BOT_API_BASE_URL + "getMe", botApiKey))
.a();
// Create a new call object and enqueue it to run asynchronously
sClient.a(request).a(new Callback() {
@Override
public void onFailure(NetCall call, IOException e) {
e.printStackTrace();
public void a(Call call, IOException e) {
// Handle the failure case
Log.d(TAG, e.getMessage());
runOnUiThread(listener::onNetError);
}
@Override
public void onResponse(NetCall call, final NetResponse response) throws IOException {
runOnUiThread(() -> listener.onKeyChecked(response.code() == 200));
public void a(Call call, Response response) {
Log.d(TAG, response.toString());
runOnUiThread(() -> listener.onKeyChecked(response.h()));
}
});
}
private void getPackInfo(final String packName, final File packFolder, final String installedVersion, final PackDownloadListener listener) {
NetRequest packInfoRequest = new NetRequest.Builder().get().url(String.format(GET_STICKER_SET_URL, botApiKey, packName)).build();
httpClient.newCall(packInfoRequest).enqueue(new NetCallback() {
private void getPack(StickerSet set, File packFolder, TelegramStickersPackInfo packInfo, PackDownloadListener listener) {
GoalCounter downloadedStickers = new GoalCounter(set.stickers.size(), () -> {
Log.d(TAG, String.format("Pack %s has been downloaded to %s", set.id, packFolder.getAbsolutePath()));
listener.onPackDownloaded(packInfo, true);
});
Flag deathFlag = new Flag();
for (int i = 0; i < set.stickers.size(); i++) {
Sticker sticker = set.stickers.get(i);
String getFileUrl = String.format(GET_FILE_URL, botApiKey, sticker.fileId);
Request fileInfoRequest = new Request.a()
.b(getFileUrl)
.a();
int stickerIndex = i + 1;
sClient.a(fileInfoRequest).a(new Callback() {
@Override
public void a(Call call, IOException e) {
handleFailure(deathFlag, listener, e, downloadedStickers, call, fileInfoRequest, this);
}
@Override
public void a(Call call, Response response) {
if (deathFlag.up())
return;
if (!response.h()) {
retryRequest(call, fileInfoRequest, this);
return;
}
try (ResponseBody responseBody = response.a()) {
JSONObject fileInfoResponse = new JSONObject(responseBody.g()).getJSONObject("result");
String filePath = fileInfoResponse.getString("file_path");
if (botApiKey == null) botApiKey = "";
String fileDownloadUrl = String.format(BOT_API_BASE_FILE_URL, botApiKey, filePath);
Request fileDownloadRequest = new Request.a()
.b(fileDownloadUrl)
.a();
sClient.a(fileDownloadRequest).a(new Callback() {
@Override
public void a(Call call, IOException e) {
handleFailure(deathFlag, listener, e, downloadedStickers, call, fileDownloadRequest, this);
}
@Override
public void a(Call call, Response response) {
if (deathFlag.up())
return;
if (!response.h()) {
retryRequest(call, fileDownloadRequest, this);
return;
}
try (ResponseBody responseBody = response.a()) {
if (responseBody == null) {
handleFailure(deathFlag, listener, new TSGException("Response body for a sticker is null :/"), downloadedStickers, call, fileDownloadRequest, this);
return;
}
InputStream stickerInputStream = responseBody.a();
Bitmap stickerImage = BitmapFactory.decodeStream(stickerInputStream);
if (stickerImage == null) {
handleFailure(deathFlag, listener, new TSGException("Unable to decode sticker image"), downloadedStickers, call, fileDownloadRequest, this);
return;
}
File stickerFile = new File(packFolder, String.format(STICKER_FILE_NAME_FORMAT, stickerIndex));
try {
saveStickerImage(stickerImage, stickerFile);
} catch (TSGException e) {
throw new RuntimeException(e);
}
listener.onStickerDownloaded(set.name, stickerFile, sticker.emoji, stickerIndex,
downloadedStickers.value() + 1, set.stickers.size());
downloadedStickers.increase();
}
}
});
} catch (Exception e) {
handleFailure(deathFlag, listener, e, downloadedStickers, call, fileInfoRequest, this);
}
}
});
}
}
private void handleFailure(Flag deathFlag, PackDownloadListener listener, Exception e, GoalCounter downloadedStickers, Call call, Request request, Callback callback) {
if ((e instanceof IOException || e instanceof TSGException) && retryCount.get() > MAX_RETRIES) {
Log.e(TAG, "Unable to download sticker: " + e.getMessage());
downloadedStickers.increase();
return;
} else if (retryCount.get() < MAX_RETRIES) {
retryRequest(call, request, callback);
return;
}
if (deathFlag.up()) {
return;
}
deathFlag.raise();
listener.onPackDownloadError(e);
}
private void retryRequest(Call call, Request request, Callback callback) {
retryCount.incrementAndGet();
if (retryCount.get() > MAX_RETRIES) {
Log.e(TAG, "retryRequest: max retries");
callback.a(call, new IOException());
} else {
Log.e(TAG, "retryRequest");
sClient.a(request).a(callback);
}
}
private void saveStickerImage(Bitmap image, File file) throws TSGException {
try (FileOutputStream fos = new FileOutputStream(file)) {
image.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (IOException e) {
throw new TSGException("Unable to save sticker image");
}
}
private void getPackInfo(String packName, File packFolder, String installedVersion, PackDownloadListener listener) {
String getStickerSetUrl = String.format(GET_STICKER_SET_URL, botApiKey, packName);
Request packInfoRequest = new Request.a()
.b(getStickerSetUrl)
.a();
sClient.a(packInfoRequest).a(new Callback() {
@Override
public void onFailure(NetCall call, IOException e) {
public void a(Call call, IOException e) {
Log.d(TAG, e.getMessage());
listener.onPackDownloadError(e);
}
@Override
public void onResponse(NetCall call, NetResponse response) {
if (!response.isSuccessful()) {
if (response.getData() != null)
listener.onPackDownloadError(new TSGException(response.getDataString() + "\nURL: " + call.request().url()));
else
listener.onPackDownloadError(new TSGException("Unknown Exception, no response body"));
public void a(Call call, Response response) throws IOException {
Log.d(TAG, response.toString());
if (!response.h()) {
String errorMessage = response.a() != null ? response.a().g() + "\nURL: " + call.m0().g() : "Unknown Exception, no response body";
listener.onPackDownloadError(new TSGException(errorMessage));
return;
}
StickerSet set;
try {
JSONObject jPackInfo = new JSONObject(response.getDataString()).getJSONObject("result");
String packVersion = new String(sha256.digest(jPackInfo.toString().getBytes(StandardCharsets.UTF_8)));
try (ResponseBody responseBody = response.a()) {
JSONObject packInfoResponse = new JSONObject(responseBody.g()).getJSONObject("result");
String packVersion = new String(sha256.digest(packInfoResponse.toString().getBytes(StandardCharsets.UTF_8)));
if (packVersion.equals(installedVersion)) {
listener.onPackDownloaded(null, false);
return;
}
JSONArray jStickers = jPackInfo.getJSONArray("stickers");
JSONArray stickersArray = packInfoResponse.getJSONArray(STICKERS_KEY);
if (jStickers.length() == 0) {
if (stickersArray.length() == 0) {
listener.onPackDownloadError(new TSGException("No stickers in pack"));
return;
}
ArrayList<Sticker> stickers = new ArrayList<>(jStickers.length());
ArrayList<Sticker> stickers = parseStickers(stickersArray);
Log.d(TAG, String.format("Parsing stickers in pack %s", packName));
StickerSet set = new StickerSet(packInfoResponse.getString(NAME_KEY), packInfoResponse.getString(TITLE_KEY), packVersion, stickers);
for (int i = 0; i < jStickers.length(); i++) {
JSONObject jSticker = jStickers.getJSONObject(i);
if (jSticker.optBoolean("is_animated") || jSticker.optBoolean("is_video")) {
if (jSticker.has("thumb")) {
stickers.add(new Sticker(jSticker.getJSONObject("thumb").getString("file_id"), jSticker.getString("emoji")));
} else {
listener.onPackDownloadError(new TSGException("Animated and video stickerpacks without thumbs are not supported!"));
return;
}
} else {
stickers.add(new Sticker(jSticker.getString("file_id"), jSticker.getString("emoji")));
}
if (!packFolder.exists() && !packFolder.mkdirs()) {
// Handle the folder creation failure case
listener.onPackDownloadError(new IOException("Can't create folder for the pack!"));
return;
}
set = new StickerSet(jPackInfo.getString("name"), jPackInfo.getString("title"), packVersion, stickers);
Log.d(TAG, String.format("Got info for pack %s, now downloading stickers to %s", packName, packFolder.getAbsolutePath()));
TelegramStickersPackInfo packInfo = new TelegramStickersPackInfo(packName, set.name, set.stickers.size(), set.version);
listener.onGotPackInfo(packInfo);
getPack(set, packFolder, packInfo, listener);
} catch (Exception e) {
listener.onPackDownloadError(e);
return;
}
if (!packFolder.exists() && !packFolder.mkdirs()) {
listener.onPackDownloadError(new IOException("Can't create folder for the pack!"));
return;
}
Log.d(TAG, String.format("Got info for pack %s, now downloading stickers to %s", packName, packFolder.getAbsolutePath()));
TelegramStickersPackInfo packInfo = new TelegramStickersPackInfo(packName, set.name, set.stickers.size(), set.version);
listener.onGotPackInfo(packInfo);
getPack(set, packFolder, packInfo, listener);
}
});
}
private void getPack(final StickerSet set, final File packFolder, final TelegramStickersPackInfo packInfo, final PackDownloadListener listener) {
final GoalCounter downloadedStickers = new GoalCounter(set.stickers.size(), () -> {
Log.d(TAG, String.format("Pack %s has been downloaded to %s", set.id, packFolder.getAbsolutePath()));
private ArrayList<Sticker> parseStickers(JSONArray stickersArray) throws JSONException, TSGException {
ArrayList<Sticker> stickers = new ArrayList<>(stickersArray.length());
listener.onPackDownloaded(packInfo, true);
});
final Flag deathFlag = new Flag();
for (int i = 0; i < stickersArray.length(); i++) {
JSONObject stickerObject = stickersArray.getJSONObject(i);
boolean isAnimated = stickerObject.optBoolean(IS_ANIMATED_KEY);
boolean isVideo = stickerObject.optBoolean(IS_VIDEO_KEY);
String fileId = stickerObject.getString(FILE_ID_KEY);
String emoji = stickerObject.getString(EMOJI_KEY);
AtomicInteger retryed = new AtomicInteger();
for (int i = 0; i < set.stickers.size(); i++) {
final Sticker sticker = set.stickers.get(i);
NetRequest fileInfoRequest = new NetRequest.Builder().get().url(String.format(GET_FILE_URL, botApiKey, sticker.fileId)).build();
final int stickerIndex = i + 1;
AtomicBoolean sync = new AtomicBoolean();
httpClient.newCall(fileInfoRequest).enqueue(new NetCallback() {
@Override
public void onFailure(NetCall call, IOException e) {
if (deathFlag.up())
return;
deathFlag.raise();
listener.onPackDownloadError(e);
sync.set(true);
if (isAnimated || isVideo) {
if (stickerObject.has(THUMB_KEY)) {
fileId = stickerObject.getJSONObject(THUMB_KEY).getString(FILE_ID_KEY);
} else {
throw new TSGException("Animated and video stickerpacks without thumbs are not supported!");
}
}
@Override
public void onResponse(NetCall call, NetResponse response) throws IOException {
if (deathFlag.up())
return;
if (response.code() != 200) {
retryed.incrementAndGet();
if (retryed.get() > 5)
onFailure(call, new IOException());
else httpClient.newCall(fileInfoRequest)
.enqueue(this);
return;
}
String filePath;
try {
JSONObject jFileInfo = new JSONObject(response.getDataString()).getJSONObject("result");
filePath = jFileInfo.getString("file_path");
} catch (Exception e) {
deathFlag.raise();
listener.onPackDownloadError(e);
sync.set(true);
return;
}
if (botApiKey == null) botApiKey = "";
NetRequest fileDownloadRequest = new NetRequest.Builder().get().url(String.format(BOT_API_BASE_FILE_URL, botApiKey, filePath)).build();
httpClient.newCall(fileDownloadRequest).enqueue(new NetCallback() {
@Override
public void onFailure(NetCall call, IOException e) {
if (deathFlag.up())
return;
deathFlag.raise();
listener.onPackDownloadError(e);
sync.set(true);
}
@Override
public void onResponse(NetCall call, NetResponse response) throws IOException {
if (deathFlag.up())
return;
if (response.code() != 200) {
retryed.incrementAndGet();
if (retryed.get() > 5)
onFailure(call, new IOException());
else httpClient.newCall(fileDownloadRequest)
.enqueue(this);
return;
}
if (response.getData() == null) {
deathFlag.raise();
listener.onPackDownloadError(new TSGException("Response body for a sticker is null :/"));
sync.set(true);
return;
}
InputStream stickerInputStream = response.getDataStream();
Bitmap stickerImage = BitmapFactory.decodeStream(stickerInputStream);
try {
stickerInputStream.close();
} catch (IOException e) {
e.printStackTrace();
deathFlag.raise();
listener.onPackDownloadError(e);
sync.set(true);
return;
}
if (stickerImage == null) {
deathFlag.raise();
listener.onPackDownloadError(new TSGException("Unable to decode sticker image"));
sync.set(true);
return;
}
File stickerFile = new File(packFolder, String.format("%03d.png", stickerIndex));
FileOutputStream fileOutputStream;
try {
fileOutputStream = new FileOutputStream(stickerFile);
} catch (Exception e) {
e.printStackTrace();
deathFlag.raise();
listener.onPackDownloadError(e);
sync.set(true);
return;
}
if (!stickerImage.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)) {
stickerImage.recycle();
deathFlag.raise();
listener.onPackDownloadError(new TSGException("Unable to compress sticker to a png file at path: " + stickerFile.getAbsolutePath()));
sync.set(true);
return;
}
stickerImage.recycle();
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
deathFlag.raise();
listener.onPackDownloadError(e);
sync.set(true);
return;
}
listener.onStickerDownloaded(set.name, stickerFile, sticker.emoji, stickerIndex, downloadedStickers.value() + 1, set.stickers.size());
downloadedStickers.increase();
sync.set(true);
}
});
}
});
while (!sync.get())
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
}
stickers.add(new Sticker(fileId, emoji));
}
return stickers;
}
private void runOnUiThread(Runnable r) {
@@ -431,15 +345,13 @@ public class TelegramStickersGrabber {
void onNetError();
}
public class TSGException extends Exception {
private static final long serialVersionUID = 7866915509988422944L;
public static class TSGException extends Exception {
private TSGException(String message) {
super(message);
}
}
private class StickerSet {
private static class StickerSet {
String id;
String name;
String version;
@@ -453,7 +365,7 @@ public class TelegramStickersGrabber {
}
}
private class Sticker {
private static class Sticker {
String emoji;
String fileId;
@@ -23,14 +23,12 @@ import ru.vtosters.lite.utils.NavigatorUtils;
import ru.vtosters.lite.utils.VTVerifications;
import static ru.vtosters.hooks.other.Preferences.checkupdates;
import static ru.vtosters.lite.ui.dialogs.ServerDialog.sendRequest;
import static ru.vtosters.lite.utils.CacheUtils.getInstance;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.setupFilters;
public class MainActivityInjector {
public static void inject(Activity activity) {
SystemThemeChangerHook.themeOnStart(activity);
sendRequest();
UsersList.getUsersList();
VTVerifications.load(activity);
@@ -5,6 +5,7 @@ import com.vtosters.lite.R;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.utils.AndroidUtils;
import java.io.IOException;
@@ -115,14 +116,20 @@ public class OnlineFormatterHook {
return AndroidUtils.getString(R.string.custom_online) + " " + appname;
}
public static JSONObject onlineHook(JSONObject json) throws ParseException, IOException, JSONException {
if (getBoolValue("onlinefix", false)) JsonInjectors.setOnlineInfo(json);
public static JSONObject onlineHook(JSONObject json) {
if (!getBoolValue("onlinefix", false) || Preferences.serverFeaturesDisable()) return json;
try {
JsonInjectors.setOnlineInfo(json);
} catch (JSONException e) {
Log.e("onlineHook", e.getMessage());
}
return json;
}
public static JSONArray onlineHookList(JSONArray jsonArr) throws ParseException, IOException, JSONException {
if (!getBoolValue("onlinefix", false)) return jsonArr;
public static JSONArray onlineHookList(JSONArray jsonArr) {
if (!getBoolValue("onlinefix", false) || Preferences.serverFeaturesDisable()) return jsonArr;
try {
JsonInjectors.setOnlineInfoUsers(jsonArr);
@@ -134,7 +141,7 @@ public class OnlineFormatterHook {
}
public static JSONObject onlineHookProfiles(JSONObject json) {
if (!getBoolValue("onlinefix", false)) return json;
if (!getBoolValue("onlinefix", false) || Preferences.serverFeaturesDisable()) return json;
try {
JsonInjectors.setOnlineInfoUsers(json.optJSONArray("profiles"));
@@ -146,7 +153,7 @@ public class OnlineFormatterHook {
}
public static JSONObject onlineHookItems(JSONObject json) {
if (!getBoolValue("onlinefix", false)) return json;
if (!getBoolValue("onlinefix", false) || Preferences.serverFeaturesDisable()) return json;
try {
JsonInjectors.setOnlineInfoUsers(json.optJSONArray("items"));
@@ -157,8 +164,8 @@ public class OnlineFormatterHook {
return json;
}
public static JSONObject onlineHookRequestsAndRecommendations(JSONObject json) throws ParseException, IOException, JSONException {
if (!getBoolValue("onlinefix", false)) return json;
public static JSONObject onlineHookRequestsAndRecommendations(JSONObject json) {
if (!getBoolValue("onlinefix", false) || Preferences.serverFeaturesDisable()) return json;
try {
JsonInjectors.setOnlineInfoUsers(json.optJSONObject("read_requests").optJSONArray("items"));
@@ -0,0 +1,10 @@
package ru.vtosters.hooks;
import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.utils.AndroidUtils;
public class TabletHook {
public static boolean hook() {
return AndroidUtils.isTablet() && !Preferences.getBoolValue("disableForceTabletMode", false);
}
}
@@ -2,6 +2,7 @@ package ru.vtosters.hooks;
import com.vk.dto.common.VerifyInfo;
import org.json.JSONObject;
import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.utils.VTVerifications;
import static ru.vtosters.hooks.other.Preferences.getBoolValue;
@@ -20,7 +21,7 @@ public class VerificationsHook {
return true;
}
if (!getBoolValue("VT_Verification", true)) {
if (!getBoolValue("VT_Verification", true) || Preferences.serverFeaturesDisable()) {
return false;
}
@@ -32,7 +33,7 @@ public class VerificationsHook {
return true;
}
if (!getBoolValue("VT_Fire", true)) {
if (!getBoolValue("VT_Fire", true) || Preferences.serverFeaturesDisable()) {
return false;
}
@@ -40,10 +41,6 @@ public class VerificationsHook {
}
public static boolean hasDeveloper(JSONObject jSONObject) {
if (!getBoolValue("VT_Dev", true)) {
return false;
}
return VTVerifications.isDeveloper(VTVerifications.getId(jSONObject));
}
@@ -242,6 +242,10 @@ public class Preferences {
return getBoolValue("autoalltranslate", false);
}
public static boolean serverFeaturesDisable() {
return getBoolValue("serverFeaturesDisable", false);
}
public static boolean shortinfo() {
return getBoolValue("shortinfo", true);
}
@@ -288,7 +292,7 @@ public class Preferences {
@SuppressWarnings("ConstantConditions")
public static boolean checkupdates() {
return !getBoolValue("isRoamingState", false) && isValidSignature() && BuildConfig.BUILD_TYPE.equals("release");
return !getBoolValue("isRoamingState", false) && isValidSignature() && BuildConfig.BUILD_TYPE.equals("release") && getBoolValue("autoupdates", true);
}
public static boolean isNewBuild() {
@@ -24,7 +24,10 @@ public class ProfileHook {
if (UsersList.hasDescription(userID)) {
try {
extendedUserProfile.z2 = Handler.getDescription(userID);
String description = Handler.getDescription(userID);
if (!TextUtils.isEmpty(description)) {
extendedUserProfile.z2 = description;
}
} catch (NullPointerException e) {
Log.e(TAG, "null \"profiles\" node\n" + e);
}
@@ -1,13 +1,10 @@
package ru.vtosters.lite.foaf;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Context;
import android.util.Log;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vk.core.network.Network;
import com.vtosters.lite.R;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
@@ -15,13 +12,9 @@ import ru.vtosters.lite.di.singleton.VtOkHttpClient;
import ru.vtosters.lite.net.Request;
import ru.vtosters.lite.utils.LifecycleUtils;
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;
import java.util.regex.Pattern;
@@ -34,43 +27,15 @@ import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
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 String API_VKNEXT = "https://api.vtosters.app/v1/getBypassedOnlineInfo?json=1&ids=";
private static final OkHttpClient client = VtOkHttpClient.getInstance();
public static long getLastSeen(long origtime, int id) throws ParseException {
var request = new okhttp3.Request.a()
.b(getLink(id))
.a(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8")).a();
String response = null;
try {
response = client.a(request).execute().a().g();
} catch (IOException e) {
Log.e("FoafBase", e.getMessage());
}
Matcher matcher = FOAF_REGEX_LAST_SEEN.matcher(response);
if (!matcher.find()) {
return origtime;
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Moscow"));
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 + id)
.a();
String response = null;
String response;
var dummy = new JSONObject();
dummy.put("last_seen", 0);
@@ -86,7 +51,6 @@ public class FoafBase {
}
public static JSONObject getBypassedOnlineInfo(String ids) {
var request = new okhttp3.Request.a()
.b(API_VKNEXT + ids)
.a();
@@ -135,7 +99,15 @@ public class FoafBase {
progressDialog.cancel();
Matcher matcher = FOAF_REGEX.matcher(str);
matcher.find();
String normalHumanDate = getNormalHumanDate(Objects.requireNonNull(matcher.group(1)));
String m = matcher.group(1);
if (m == null) {
LifecycleUtils.getCurrentActivity().runOnUiThread(() -> makeText(getGlobalContext(), context.getString(R.string.foaferr), LENGTH_SHORT).show());
return;
}
String normalHumanDate = getNormalHumanDate(m);
LifecycleUtils.getCurrentActivity().runOnUiThread(() -> new VkAlertDialog.Builder(context)
.setTitle(R.string.addinf)
@@ -147,17 +119,14 @@ public class FoafBase {
.show());
} catch (Exception e) {
LifecycleUtils.getCurrentActivity().runOnUiThread(() -> makeText(getGlobalContext(), context.getString(R.string.foaferr), LENGTH_SHORT).show());
e.printStackTrace();
}
}
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) {
e.printStackTrace();
return -1;
}
}
@@ -1,6 +1,7 @@
package ru.vtosters.lite.music.cache;
import android.os.RemoteException;
import android.text.TextUtils;
import bruhcollective.itaysonlab.libvkx.ILibVkxService;
import bruhcollective.itaysonlab.libvkx.client.LibVKXClient;
import bruhcollective.itaysonlab.libvkx.client.LibVKXClientImpl;
@@ -17,7 +18,7 @@ public class MusicCacheImpl {
track.y1(),
track.I != null ? track.I.getId() + "" : "-1",
track.f,
track.g,
!TextUtils.isEmpty(track.g) ? track.g : "",
track.C,
track.I != null ? track.I.getTitle() : "",
track.K,
@@ -1,9 +1,14 @@
package ru.vtosters.lite.music.converter.ts;
import com.arthenica.ffmpegkit.FFmpegKit;
import com.vk.dto.music.Artist;
import com.vk.dto.music.MusicTrack;
import ru.vtosters.lite.music.downloader.M3UDownloader;
import ru.vtosters.lite.utils.IOUtils;
import java.io.File;
import java.text.Normalizer;
import java.util.stream.Collectors;
public class FFMpeg {
@@ -13,47 +18,22 @@ public class FFMpeg {
* @param track Track to be converted
* @return True if success, else false
*/
public static void convert(File in, String out, MusicTrack track) throws Throwable {
public static void convert(File in, String out, MusicTrack track) {
// convert .ts file to .mp3 file via ffmpeg
var cmd = " -y -i \"" + in.getAbsolutePath() + '"'
+ " -map 0 -dn"
+ " -loglevel error"
+ " -hide_banner"
+ " -write_id3v2 1"
// +" -metadata title=\""+IOUtils.getValidFileName(M3UDownloader.getTitle(track))+'"'
// +" -metadata artist=\""+normalizeMetadata(track.L.stream().map(Artist::w1).collect(Collectors.joining(", ")))+'"'
// +" -metadata album=\""+normalizeMetadata(track.I.getTitle())+'"'
+ " -metadata title=\"" + IOUtils.getValidFileName(M3UDownloader.getTitle(track)) + '"'
+ " -metadata artist=\"" + normalizeMetadata(track.L.stream().map(Artist::w1).collect(Collectors.joining(", "))) + '"'
+ " -metadata album=\"" + normalizeMetadata(track.I.getTitle()) + '"'
+ " -c copy \"" + out + '"';
var ses = FFmpegKit.execute(cmd);
if (ses.getReturnCode().isValueCancel()) throw new RuntimeException(ses.getLogsAsString());
}
private static String normalizeMetadata(String in) {
return in.replace('"', '‟');
return in.replaceAll("[\\\\/:*?\"<>|]", "");
}
// private static void copyAssets()
// throws IOException
// {
// try
// {
// for (var filename:AndroidUtils.getGlobalContext().getAssets().list("ffmpeg"))
// if(filename.endsWith(".so"))
// IOUtils.writeToFile(
// new File(AndroidUtils.getGlobalContext().getFilesDir(),filename),
// IOUtils.readFully(AndroidUtils.getGlobalContext().getAssets().open("ffmpeg"+File.separator+filename)));
// }
// catch(IOException e)
// { throw e; }
// }
//
// private static void checkFFMpegLibs()
// {
// var lib=new File(AndroidUtils.getGlobalContext().getFilesDir(),"libffmpegkit_abidetect.so");
// if(!lib.exists())
// {
// ToastUtils.a(R.string.ffmpegkit_copy);
// copyAssets();
// }
// }
}
@@ -48,25 +48,23 @@ public class M3UDownloader
var resultMp3 = getResultMp3File(outDir, cache, track);
try {
CompletableFuture.allOf(createFutures(baseUri, segments, progress, callback, track))
.thenRun(() ->
{
if (cache)
.thenRun(() -> {
if (cache) {
try {
ThumbnailDownloader.downloadThumbnails(track);
} catch (IOException e) {
throw new RuntimeException("Failed to download thumbs", e);
}
}
})
.thenRun(() ->
{
.thenRun(() -> {
try {
TSMerger.merge(getTsesDir(track), resultTs);
} catch (Throwable e) {
throw new RuntimeException("Failed to merge ts files", e);
}
})
.thenRun(() ->
{
.thenRun(() -> {
try {
FFMpeg.convert(resultTs, resultMp3.getAbsolutePath(), track);
} catch (Throwable e) {
@@ -74,12 +72,18 @@ public class M3UDownloader
}
})
.thenRun(() -> callback.onProgress(10 + Math.round(80.0f * progress.addAndGet(1) / segments.size())))
.thenRun(() -> MusicCacheImpl.addTrack(track))
.thenRun(() -> {
if (cache) {
MusicCacheImpl.addTrack(track);
}
})
.whenComplete((unused, tr) -> {
if (tr != null) {
IOUtils.deleteRecursive(MusicCacheStorageUtils.getTrackDirById(track.y1()));
callback.onFailure();
} else callback.onSuccess();
} else {
callback.onSuccess();
}
IOUtils.deleteRecursive(getTsesDir(track));
})
.join();
@@ -132,7 +136,7 @@ public class M3UDownloader
}
public static String getTitle(MusicTrack track) {
return track.f + (!TextUtils.isEmpty(track.g) ? +'(' + track.g + ')' : null);
return track.f + (!TextUtils.isEmpty(track.g) ? + '(' + track.g + ')' : "");
}
static File getTsesDir(MusicTrack track) {
@@ -3,16 +3,19 @@ package ru.vtosters.lite.net;
import android.util.Base64;
import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.TreeMap;
public final class NetCall {
// Constants for the request methods, content types, and encoding
private static final String GET = "GET";
private static final String POST = "POST";
private static final String FORM = "application/x-www-form-urlencoded";
private static final String UTF_8 = "UTF-8";
private final NetRequest req;
private final NetClient cl;
@@ -22,13 +25,17 @@ public final class NetCall {
}
private static String constructArgs(Map<String, String> args) throws UnsupportedEncodingException {
// Use a TreeMap to sort the arguments by key
args = new TreeMap<>(args);
String str = "";
for (Map.Entry<String, String> en : args.entrySet()) {
if (!str.isEmpty()) str += "&";
str += URLEncoder.encode(en.getKey(), "UTF-8") + "=" + URLEncoder.encode(en.getValue(), "UTF-8");
// Use a StringBuilder to append the arguments
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : args.entrySet()) {
if (sb.length() > 0) sb.append("&");
sb.append(URLEncoder.encode(entry.getKey(), UTF_8))
.append("=")
.append(URLEncoder.encode(entry.getValue(), UTF_8));
}
return str;
return sb.toString();
}
public NetRequest request() {
@@ -38,38 +45,52 @@ public final class NetCall {
public NetResponse execute() throws IOException {
Proxy proxy = cl.getProxy();
PasswordAuthentication auth = cl.getAuthenticator();
HttpURLConnection con = (HttpURLConnection) new URL(req.url()).openConnection(proxy != null ? proxy : Proxy.NO_PROXY);
HttpURLConnection connection = (HttpURLConnection) new URL(req.url()).openConnection(proxy != null ? proxy : Proxy.NO_PROXY);
if (proxy != null && auth != null) {
// Set the proxy authentication header
String authStr = "Basic " + Base64.encodeToString((auth.getUserName() + new String(auth.getPassword())).getBytes(), Base64.NO_WRAP);
con.setRequestProperty("Proxy-Connection", "Keep-Alive");
con.setRequestProperty("Proxy-Authorization", authStr);
connection.setRequestProperty("Proxy-Connection", "Keep-Alive");
connection.setRequestProperty("Proxy-Authorization", authStr);
}
con.setConnectTimeout((int) cl.getTimeout());
con.setRequestMethod(req.getRequestMethod());
if (req.getRequestMethod().equals("POST")) {
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setConnectTimeout((int) cl.getTimeout());
connection.setRequestMethod(req.getRequestMethod());
if (req.getRequestMethod().equals(POST)) {
// Set the content type for POST requests
connection.setRequestProperty("Content-Type", FORM);
}
Map<String, String> params = req.getRequestParams();
if (params != null) {
String strArgs = constructArgs(params);
con.setRequestProperty("Content-Length", String.valueOf(strArgs.getBytes(StandardCharsets.UTF_8).length));
con.setDoOutput(true);
con.getOutputStream().write(strArgs.getBytes(StandardCharsets.UTF_8));
con.getOutputStream().close();
// Write the request parameters to the output stream
writeParams(connection, params);
}
connection.connect();
InputStream input;
if (connection.getResponseCode() == 200) input = connection.getInputStream();
else input = connection.getErrorStream();
// Use try-with-resources to close the streams automatically
try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024 * 1024];
int count;
while ((count = input.read(buffer)) != -1) output.write(buffer, 0, count);
input.close();
NetResponse response = new NetResponse(output.toByteArray());
response.setCode(connection.getResponseCode());
return response;
}
}
private void writeParams(HttpURLConnection connection, Map<String, String> params) throws IOException {
// Get the encoded arguments string
String args = constructArgs(params);
// Set the content length header
connection.setRequestProperty("Content-Length", String.valueOf(args.getBytes(StandardCharsets.UTF_8).length));
// Enable output mode
connection.setDoOutput(true);
// Write the arguments to the output stream
try (OutputStream output = connection.getOutputStream()) {
output.write(args.getBytes(StandardCharsets.UTF_8));
output.flush();
}
con.connect();
InputStream in;
if (con.getResponseCode() == 200) in = con.getInputStream();
else in = con.getErrorStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024 * 1024];
int c;
while ((c = in.read(buffer)) != -1) bos.write(buffer, 0, c);
in.close();
bos.close();
NetResponse r = new NetResponse(bos.toByteArray());
r.setCode(con.getResponseCode());
return r;
}
public void enqueue(NetCallback cb) {
@@ -82,12 +103,16 @@ public final class NetCall {
} catch (IOException e) {
cb.onFailure(NetCall.this, e);
}
// try {
//// interrupt();
try {
interrupt();
join();
} catch (Exception e) {
Log.e("NetCall", "Failed to interrupt and join thread", e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
// } catch (Exception e) {
// Log.e("NetCall", "Failed to interrupt and join thread", e);
// }
}
}.start();
}
@@ -8,11 +8,11 @@ public final class NetResponse {
private final byte[] data;
private int code;
NetResponse(byte[] data) {
public NetResponse(byte[] data) {
this.data = data;
}
void setCode(int code) {
public void setCode(int code) {
this.code = code;
}
@@ -51,7 +51,7 @@ public class Request {
httpURLConnection.setRequestProperty("Content-Type", mIsVTostersRequest ? "Content-Type" : "application/x-www-form-urlencoded");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
StringBuffer stringBuffer = new StringBuffer();
StringBuilder stringBuffer = new StringBuilder();
while (true) {
String readLine = bufferedReader.readLine();
if (readLine != null) {
@@ -26,20 +26,20 @@ public class ProfileButtons {
newItem = orig.getJSONArray("buttons");
}
if (!VTVerifications.haveDonateButton() && id == AccountManagerUtils.getUserId()) {
var map = new HashMap<>();
map.put("20", "https://raw.githubusercontent.com/vtosters/lite/main/.github/images/donate_icon/20.png");
map.put("40", "https://raw.githubusercontent.com/vtosters/lite/main/.github/images/donate_icon/40.png");
map.put("80", "https://raw.githubusercontent.com/vtosters/lite/main/.github/images/donate_icon/80.png");
newItem.put(generateJsonObject(
AndroidUtils.getString(com.vtosters.lite.R.string.donate_to_vtl),
"https://vk.com/vtosters_official",
"2D81E0",
"open_url",
map
));
}
// if (!VTVerifications.haveDonateButton() && id == AccountManagerUtils.getUserId()) {
// var map = new HashMap<>();
// map.put("20", "https://raw.githubusercontent.com/vtosters/lite/main/.github/images/donate_icon/20.png");
// map.put("40", "https://raw.githubusercontent.com/vtosters/lite/main/.github/images/donate_icon/40.png");
// map.put("80", "https://raw.githubusercontent.com/vtosters/lite/main/.github/images/donate_icon/80.png");
//
// newItem.put(generateJsonObject(
// AndroidUtils.getString(com.vtosters.lite.R.string.donate_to_vtl),
// "https://vk.com/vtosters_official",
// "2D81E0",
// "open_url",
// map
// ));
// }
if (!orig.has("type") && AccountManagerUtils.isVKTester()) {
var map = new HashMap<>();
@@ -8,6 +8,7 @@ import okhttp3.Response;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.di.singleton.VtOkHttpClient;
import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils;
@@ -17,6 +18,8 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static ru.vtosters.hooks.other.Preferences.getBoolValue;
public class UsersList {
private static final String TAG = "UsersList";
private static final List<Integer> descriptionsList = new ArrayList<>();
@@ -25,7 +28,7 @@ public class UsersList {
public static void getUsersList() {
var prefs = AndroidUtils.getGlobalContext().getSharedPreferences("vt_another_data", 0);
if ((!NetworkUtils.isNetworkConnected() || NetworkUtils.isInternetSlow()) && prefs.contains("ids")) {
if ((!NetworkUtils.isNetworkConnected() || NetworkUtils.isInternetSlow()) && prefs.contains("ids") || Preferences.serverFeaturesDisable()) {
return;
}
@@ -7,22 +7,7 @@ import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
public class TGPref {
private static final SharedPreferences Prefs = PreferenceManager.getDefaultSharedPreferences(getGlobalContext());
private static final String CNCT_METHOD = "VTGS:CM";
private static final String TG_BOTKEY = "VTGS:BKey";
private static final String TG_PROXYIP = "VTGS:PIP";
private static final String TG_PROXYPORT = "VTGS:PPT";
private static final String TG_PROXYPASS = "VTGS:PPS";
private static final String TG_PROXYUSER = "VTGS:PUS";
private static final String TG_PROXYUSEPASS = "VTGS:PUsePassword";
public static int getTGConnectMethod() {
return Integer.parseInt(Prefs.getString(CNCT_METHOD, "0"));
}
public static void setTGConnectMethod(int method) {
Prefs.edit().putString(CNCT_METHOD, String.valueOf(method)).apply();
}
public static String getTGBotKey() {
return Prefs.getString(TG_BOTKEY, null);
@@ -31,40 +16,4 @@ public class TGPref {
public static void setTGBotKey(String key) {
Prefs.edit().putString(TG_BOTKEY, key).apply();
}
public static String getTGProxyIP() {
return Prefs.getString(TG_PROXYIP, null);
}
public static void setTGProxyIP(String ip) {
Prefs.edit().putString(TG_PROXYIP, ip).apply();
}
public static int getTGProxyPort() {
return Prefs.getInt(TG_PROXYPORT, 0);
}
public static void setTGProxyPort(int port) {
Prefs.edit().putInt(TG_PROXYPORT, port).apply();
}
public static String getTGProxyPass() {
return Prefs.getString(TG_PROXYPASS, "");
}
public static String getTGProxyUser() {
return Prefs.getString(TG_PROXYUSER, "");
}
public static void setTGProxyUserPass(String user, String pass) {
Prefs.edit().putString(TG_PROXYUSER, user).putString(TG_PROXYPASS, pass).apply();
}
public static boolean isTGProxyPassEnabled() {
return Prefs.getBoolean(TG_PROXYUSEPASS, false);
}
public static void setTGProxyPassEnabled(boolean en) {
Prefs.edit().putBoolean(TG_PROXYUSEPASS, en).apply();
}
}
@@ -2,11 +2,9 @@ package ru.vtosters.lite.tgs;
import com.aefyr.tsg.g2.TelegramStickersPack;
import com.vk.dto.stickers.StickerStockItem;
import com.vtosters.lite.R;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import ru.vtosters.lite.utils.AndroidUtils;
import java.util.Stack;
@@ -15,14 +13,6 @@ public class TGRoot {
public static final int X = 976820000;
public final static Stack<Integer> pendingStickers = new Stack<>();
public static String getSummary() {
return switch (TGPref.getTGConnectMethod()) {
case 0 -> AndroidUtils.getString(R.string.ctypedirect);
case 2 -> AndroidUtils.getString(R.string.ctypesocks);
default -> AndroidUtils.getString(R.string.ctypedisabled);
};
}
public static StickerStockItem toStickerPack(TelegramStickersPack p) throws JSONException {
JSONArray arr = new JSONArray();
@@ -39,11 +39,11 @@ public class IconManager {
);
public static List<String> icons() {
return Preferences.hasVerification() && Preferences.isValidSignature() ? sIconsPlusNames : sIconsNames; // delete later sdk check
return sIconsPlusNames; // delete later sdk check
}
public static List<String> iconsValues() {
return Preferences.hasVerification() && Preferences.isValidSignature() ? sIconsPlus : sIcons; // delete later sdk check
return sIconsPlus; // delete later sdk check
}
public static void switchComponent(String icon, String appName) {
@@ -55,7 +55,7 @@ public class IconManager {
Log.d("IconManager", "iconSwitcher: icon = " + icon + ", appname = " + appName);
List<String> iconsList = (Preferences.hasVerification() && Preferences.isValidSignature()) ? sIconsPlus : sIcons;
List<String> iconsList = sIconsPlus;
List<String> labelsList = sLabels;
// check if icon is exist
@@ -1,108 +0,0 @@
package ru.vtosters.lite.ui.dialogs;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import com.vk.core.dialogs.alert.VkAlertDialog;
import okhttp3.*;
import org.json.JSONObject;
import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.di.singleton.VtOkHttpClient;
import ru.vtosters.lite.utils.LifecycleUtils;
import java.io.IOException;
import java.util.Random;
import static android.content.ContentValues.TAG;
import static ru.vtosters.hooks.other.Preferences.getBoolValue;
import static ru.vtosters.hooks.other.Preferences.hasVerification;
public class ServerDialog {
private static final OkHttpClient client = VtOkHttpClient.getInstance();
public static Boolean showAlert;
private static String title;
private static String message;
private static String positiveButton;
private static String neutralButton;
private static String link;
private static String key;
private static Boolean cancelable;
private static Boolean isNotForVerified;
public static void sendRequest() {
if (getBoolValue("dialogrecomm", false)) return;
if (!getBoolValue("isRoamingState", false)) {
Request request = new Request.a()
.b("https://vtosters.app/dialog.json")
.a();
client.a(request).a(new Callback() {
@Override
public void a(Call call, IOException e) {
Log.d(TAG, e.getMessage());
showAlert = false;
}
@Override
public void a(Call call, Response response) {
try {
getResponse(response.a().g());
} catch (Exception e) {
showAlert = false;
}
}
});
}
}
private static Boolean showForNotVerified() {
int random = new Random().nextInt(6);
if (isNotForVerified) {
return !hasVerification() && random != 0;
}
return true;
}
private static void getResponse(String body) throws Exception {
JSONObject jSONObject = new JSONObject(body);
if (jSONObject.getString("title").equals("")) {
showAlert = false;
return;
}
title = jSONObject.getString("title");
message = jSONObject.getString("message");
positiveButton = jSONObject.getString("positiveButton");
neutralButton = jSONObject.getString("neutralButton");
link = jSONObject.getString("link");
key = jSONObject.getString("key");
cancelable = jSONObject.getBoolean("cancelable");
isNotForVerified = jSONObject.getBoolean("isNotForVerified");
showAlert = true;
Activity activity = LifecycleUtils.getCurrentActivity();
if (getBoolValue(key, true) && showForNotVerified() && showAlert) {
activity.runOnUiThread(() -> {
new VkAlertDialog.Builder(activity)
.setTitle(title)
.setMessage(message)
.setCancelable(cancelable)
.setPositiveButton(positiveButton,
(dialogInterface, i) -> Preferences.getPreferences().edit().putBoolean(key, false).apply())
.setNeutralButton(neutralButton, (dialogInterface, i) -> {
Preferences.getPreferences().edit().putBoolean(key, false).apply();
Intent intent = new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse(link));
activity.startActivity(intent);
})
.show();
});
}
}
}
@@ -3,7 +3,9 @@ package ru.vtosters.lite.ui.fragments;
import android.os.Bundle;
import androidx.preference.Preference;
import com.vtosters.lite.R;
import ru.vtosters.hooks.other.Preferences;
import static ru.vtosters.hooks.other.Preferences.getBoolValue;
import static ru.vtosters.hooks.other.Preferences.offline;
public class ActivityFragment extends TrackedMaterialPreferenceToolbarFragment {
@@ -12,6 +14,7 @@ public class ActivityFragment extends TrackedMaterialPreferenceToolbarFragment {
super.onCreate(bundle);
addPreferencesFromResource(R.xml.preferences_activity);
findPreference("setoffline").setEnabled(offline());
findPreference("onlinefixcategory").setVisible(!Preferences.serverFeaturesDisable());
}
@Override
@@ -301,6 +301,20 @@ public class DataSettingsFragment extends TrackedMaterialPreferenceToolbarFragme
}
);
PreferenceFragmentUtils.addMaterialSwitchPreference(
getPreferenceScreen(),
"serverFeaturesDisable",
"Отключить всю работу с сервером",
"Отключает галочки и все дополнительные функции связанные с получением данных с сервера ВТостерс",
null,
false,
(preference, o) -> {
Preferences.getPreferences().edit().putBoolean("serverFeaturesDisable", (boolean) o).apply();
LifecycleUtils.restartApplicationWithTimer();
return true;
}
);
findPreference("analyticsDisabled").setVisible(Preferences.isValidSignature());
}
@@ -92,13 +92,6 @@ public class IconsFragment extends TrackedMaterialPreferenceToolbarFragment {
this.addPreferencesFromResource(R.xml.empty);
if (!Preferences.hasVerification() && !Preferences.getBoolValue("dialogrecomm", false)) {
PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", requireContext().getString(R.string.icons_warning), requireContext().getString(R.string.icons_warning_info), R.drawable.ic_about_outline_28, preference -> {
getContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://vtosters.app/donate/")));
return false;
});
}
PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), requireContext().getString(R.string.icons_title));
for (var i = 0; i < IconManager.icons().size(); i++) {
@@ -128,37 +121,5 @@ public class IconsFragment extends TrackedMaterialPreferenceToolbarFragment {
return false;
});
}
if (!Preferences.hasVerification() && !Preferences.getBoolValue("dialogrecomm", false)) {
PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), requireContext().getString(R.string.unavailable_icons));
for (var i = 2; i < IconManager.sIconsPlusNames.size(); i++) {
if (IconManager.sIconsPlusNames.get(i) == null || IconManager.sIconsPlus.get(i) == null) return;
String iconname = IconManager.sIconsPlusNames.get(i);
String icon = IconManager.sIconsPlus.get(i);
int iconRes;
if (icon.equals("vt")) {
iconRes = R.mipmap.vt_launcher_round;
} else if (icon.contains("standard")) {
iconRes = R.mipmap.ic_launcher_round;
} else {
iconRes = AndroidUtils.getIdentifier("ic_launcher_" + icon, "mipmap");
}
Drawable drawable = ResourcesCompat.getDrawable(getResources(), iconRes, null);
if (drawable == null) {
drawable = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_bug_outline_28, null);
}
PreferenceFragmentUtils.addPreference(getPreferenceScreen(), icon, iconname, "", drawable, preference -> {
AndroidUtils.sendToast(requireContext().getString(R.string.unavailable_icon_warning));
return false;
});
}
}
}
}
@@ -13,13 +13,15 @@ public class InstallGMSFragment extends TrackedMaterialPreferenceToolbarFragment
addPreferencesFromResource(R.xml.preferences_gms);
findPreference("microg").setOnPreferenceClickListener((preference) -> {
String[] items = {"Уменьшенный MicroG (Vanced MicroG)", "Полноценный MicroG (Замена GMS)"};
String[] items = {"Уменьшенный MicroG (ReVanced)", "Альтернативный MicroG (ReVanced)", "Полноценный MicroG (Замена GMS)"};
new VkAlertDialog.Builder(requireActivity()).setItems(items, (dialog, which) -> {
switch (which) {
case 0 ->
requireContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://github.com/TeamVanced/VancedMicroG/releases/latest/download/microg.apk")));
case 1 ->
requireContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://github.com/inotia00/mMicroG/releases/latest/download/microg.apk")));
case 2 ->
requireContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://github.com/microg/GmsCore/releases")));
}
dismiss();
@@ -67,6 +67,13 @@ public class InterfaceFragment extends TrackedMaterialPreferenceToolbarFragment
findPreference("showmenu").setVisible(false);
}
var tablet = findPreference("disableForceTabletMode");
tablet.setVisible(AndroidUtils.isTablet());
tablet.setOnPreferenceClickListener(preference -> {
LifecycleUtils.restartApplicationWithTimer();
return true;
});
findPreference("customrounding").setOnPreferenceClickListener(preference -> {
RoundingSeekbarDialog.dialog(getContext());
return true;
@@ -16,6 +16,8 @@ import ru.vtosters.lite.ssfs.UsersList;
import ru.vtosters.lite.ui.activities.VKAdminTokenActivity;
import ru.vtosters.lite.utils.*;
import static ru.vtosters.hooks.other.Preferences.getBoolValue;
public class OtherFragment extends TrackedMaterialPreferenceToolbarFragment {
private static final int VK_ADMIN_TOKEN_REQUEST_CODE = 1;
@@ -110,6 +112,10 @@ public class OtherFragment extends TrackedMaterialPreferenceToolbarFragment {
return true;
});
findPreference("VT_Verification").setVisible(!Preferences.serverFeaturesDisable());
findPreference("VT_Fire").setVisible(!Preferences.serverFeaturesDisable());
findPreference("updateverifdata").setVisible(!Preferences.serverFeaturesDisable());
var vkAdminTokenPref = findPreference("vk_admin_token");
vkAdminTokenPref.setVisible(Preferences.getPreferences().getBoolean("new_music_downloading_way", false));
if (vkAdminTokenPref.isVisible()) {
@@ -108,7 +108,7 @@ public class VTSettings extends TrackedMaterialPreferenceToolbarFragment {
PowerManager manager = (PowerManager) requireActivity().getSystemService(Context.POWER_SERVICE);
boolean isLinksUnverified = AndroidUtils.isLinksUnverified(requireActivity());
boolean isDozingAvailable = Build.VERSION.SDK_INT >= 23 && !manager.isIgnoringBatteryOptimizations(AndroidUtils.getPackageName());
boolean areNotificationsDisabled = !AndroidUtils.areNotificationsEnabled();
boolean areNotificationsDisabled = !AndroidUtils.areNotificationsEnabled() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
boolean isGMSNotInstalled = !GmsHook.isAnyServicesInstalled();
if (AccountManagerUtils.isLogin()) {
@@ -142,18 +142,20 @@ public class VTSettings extends TrackedMaterialPreferenceToolbarFragment {
});
});
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"",
requireContext().getString(R.string.vtssfs),
getSSFSsumm(),
R.drawable.ic_link_circle_outline_28,
preference -> {
VKUIwrapper.setLink(Utils.getVKUILink());
NavigatorUtils.switchFragment(requireContext(), VKUIwrapper.class);
return false;
}
);
if (Preferences.hasSpecialVerif()) {
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"",
requireContext().getString(R.string.vtssfs),
"",
R.drawable.ic_link_circle_outline_28,
preference -> {
VKUIwrapper.setLink(Utils.getVKUILink());
NavigatorUtils.switchFragment(requireContext(), VKUIwrapper.class);
return false;
}
);
}
}
PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), R.string.appearance_theme_use_system);
@@ -649,20 +651,6 @@ public class VTSettings extends TrackedMaterialPreferenceToolbarFragment {
}
);
if (!Preferences.hasVerification() && !Preferences.getBoolValue("dialogrecomm", false)) {
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"",
"Помочь проекту",
"За донат можно получить приятные бонусы на аккаунт",
R.drawable.ic_money_circle_outline_28,
preference -> {
requireContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://vtosters.app/donate")));
return false;
}
);
}
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"",
@@ -701,6 +689,19 @@ public class VTSettings extends TrackedMaterialPreferenceToolbarFragment {
return false;
}
);
PreferenceFragmentUtils.addMaterialSwitchPreference(
getPreferenceScreen(),
"autoupdates",
"Автоматическое обновление",
"Получать уведомление о выходе новой версии приложения",
R.drawable.ic_history_outline_28,
true,
(preference, o) -> {
Preferences.getPreferences().edit().putBoolean("autoupdates", (boolean) o).apply();
return true;
}
);
}
}
@@ -28,21 +28,16 @@ import ru.vtosters.lite.ui.adapters.StickerPackAdapter;
import ru.vtosters.lite.ui.components.StickerTouchHelperCallback;
import ru.vtosters.lite.ui.fragments.BaseToolbarFragment;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.NavigatorUtils;
import java.io.File;
public class StickersFragment extends BaseToolbarFragment {
public final static String ACTION_RELOAD = "com.vtosters.lite.action.RELOAD_TGS_LIST";
final static int TYPE_DIRECT = 0;
final static int TYPE_SOCKS = 2;
public static String ACTION_RELOAD = "com.vtosters.lite.action.RELOAD_TGS_LIST";
TelegramStickersGrabber mGrabber;
StickerPackAdapter mAdapter;
boolean movePending = false;
int from, to;
final BroadcastReceiver mReceiver = new BroadcastReceiver() {
BroadcastReceiver mReceiver = new BroadcastReceiver() {
@SuppressLint("NotifyDataSetChanged")
@Override
public void onReceive(Context context, Intent intent) {
@@ -59,13 +54,28 @@ public class StickersFragment extends BaseToolbarFragment {
}
};
private static void resetToken(Context ctx) {
if (TGPref.getTGBotKey() == null) AndroidUtils.sendToast("Токен отсутствует");
new VkAlertDialog.Builder(ctx)
.setTitle("Сбросить токен бота?")
.setNegativeButton(R.string.cancel, (dialog, which) -> {
dialog.cancel();
})
.setPositiveButton(R.string.ok, (dialog, which) -> {
TGPref.setTGBotKey(null);
AndroidUtils.sendToast("Токен бота сброшен");
})
.show();
}
@Override
protected void onCreateMenu(Menu menu) {
menu.add(0, 0, 0, "")
.setIcon(ThemesUtils.recolorDrawable(requireContext().getDrawable(R.drawable.ic_add_outline_28)))
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
menu.add(0, 1, 0, "")
.setIcon(R.drawable.ic_settings_outline_28)
.setIcon(ThemesUtils.recolorDrawable(requireContext().getDrawable(R.drawable.ic_refresh_outline_28)))
.setTitle("Сбросить токен бота")
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
super.onCreateMenu(menu);
}
@@ -74,16 +84,11 @@ public class StickersFragment extends BaseToolbarFragment {
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 0 -> addTgsPack();
case 1 -> openMenu(null);
case 1 -> resetToken(requireContext());
}
return true;
}
private void openMenu(String toast) {
if (toast != null) Toast.makeText(requireContext(), toast, Toast.LENGTH_SHORT).show();
NavigatorUtils.switchFragment(requireContext(), StickersPreferencesFragment.class);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -96,14 +101,14 @@ public class StickersFragment extends BaseToolbarFragment {
public View onCreateContent(@NonNull LayoutInflater inflater, @Nullable Bundle bundle) {
setTitle(R.string.vtltgs);
final var container = new FrameLayout(requireContext());
final var recycler = new RecyclerView(requireContext());
var container = new FrameLayout(requireContext());
var recycler = new RecyclerView(requireContext());
mAdapter = new StickerPackAdapter();
recycler.setAdapter(mAdapter);
final var callback = new StickerTouchHelperCallback(mAdapter);
final var touchHelper = new ItemTouchHelper(callback);
var callback = new StickerTouchHelperCallback(mAdapter);
var touchHelper = new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(recycler);
recycler.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
@@ -124,80 +129,50 @@ public class StickersFragment extends BaseToolbarFragment {
}
private void addTgsPack() {
final var method = TGPref.getTGConnectMethod();
if (method != -1) {
initGrabber();
switch (method) {
case TYPE_SOCKS -> {
if (TGPref.getTGProxyIP() == null) openMenu(requireContext().getString(R.string.stickersproxy1));
}
case TYPE_DIRECT -> {
initGrabber();
final Runnable lambda = () ->
initGrabber();
Runnable lambda = () -> {
var container = new LinearLayout(requireContext());
var input = new EditText(requireContext());
var inputLP = new ViewGroup.MarginLayoutParams(-1, -2);
inputLP.setMargins(
AndroidUtils.dp2px(24.f),
0,
AndroidUtils.dp2px(24.f),
0);
container.addView(input, inputLP);
new VkAlertDialog.Builder(requireContext())
.setTitle(R.string.stickershelp1)
// .setMessage(R.string.stickershelp2)
.setView(container)
.setPositiveButton(android.R.string.ok, (dialog, which) ->
{
final var container = new LinearLayout(requireContext());
var packId = input.getText().toString();
if (packId.startsWith("https://"))
packId = packId.substring(packId.lastIndexOf('/') + 1);
TelegramStickersService.getInstance(requireContext())
.requestPackDownload(
packId,
new File(requireContext().getFilesDir(), "VT-Stickers/" + packId));
})
.setNeutralButton(android.R.string.cancel, (dialog, which) -> dialog.dismiss())
.show();
};
final var input = new EditText(requireContext());
final var inputLP = new ViewGroup.MarginLayoutParams(-1, -2);
inputLP.setMargins(
AndroidUtils.dp2px(24.f),
0,
AndroidUtils.dp2px(24.f),
0);
container.addView(input, inputLP);
new VkAlertDialog.Builder(requireContext())
.setTitle(R.string.stickershelp1)
// .setMessage(R.string.stickershelp2)
.setView(container)
.setPositiveButton(android.R.string.ok, (dialog, which) ->
{
var packId = input.getText().toString();
if (packId.startsWith("https://"))
packId = packId.substring(packId.lastIndexOf('/') + 1);
TelegramStickersService.getInstance(requireContext())
.requestPackDownload(
packId,
new File(requireContext().getFilesDir(), "VT-Stickers/" + packId));
})
.setNeutralButton(android.R.string.cancel, (dialog, which) -> dialog.dismiss())
.show();
};
if (TGPref.getTGBotKey() == null) enterBotKey(() -> checkApiKey(lambda));
else checkApiKey(lambda);
}
}
} else openMenu(requireContext().getString(R.string.stickersconnection));
if (TGPref.getTGBotKey() == null) enterBotKey(() -> checkApiKey(lambda));
else checkApiKey(lambda);
}
private void initGrabber() {
switch (TGPref.getTGConnectMethod()) {
case TYPE_DIRECT -> {
TelegramStickersGrabber.USE_PROXY = false;
mGrabber.resetProxy();
}
case TYPE_SOCKS -> {
if (TGPref.getTGProxyIP() == null) break;
TelegramStickersGrabber.USE_PROXY = true;
TelegramStickersGrabber.PROXY_IP = TGPref.getTGProxyIP();
TelegramStickersGrabber.PROXY_PORT = TGPref.getTGProxyPort();
if (TGPref.isTGProxyPassEnabled()) {
TelegramStickersGrabber.HAS_PASS = true;
TelegramStickersGrabber.PROXY_USER = TGPref.getTGProxyUser();
TelegramStickersGrabber.PROXY_PASS = TGPref.getTGProxyPass();
}
mGrabber.enableProxy();
}
}
TelegramStickersGrabber.updateURLs();
}
private void enterBotKey(Runnable callback) {
final var container = new LinearLayout(requireContext());
var container = new LinearLayout(requireContext());
final var input = new EditText(requireContext());
final var inputLP = new ViewGroup.MarginLayoutParams(-1, -2);
var input = new EditText(requireContext());
var inputLP = new ViewGroup.MarginLayoutParams(-1, -2);
inputLP.setMargins(
AndroidUtils.dp2px(24.f),
0,
@@ -222,7 +197,7 @@ public class StickersFragment extends BaseToolbarFragment {
.setMessage(requireContext().getString(R.string.stickersapi9) +
requireContext().getString(R.string.stickersapi10))
.setNeutralButton(AndroidUtils.getString("open_bot"), (dl, i) -> {
final var intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://t.me/botfather"))
var intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://t.me/botfather"))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
requireActivity().startActivity(intent);
})
@@ -235,7 +210,7 @@ public class StickersFragment extends BaseToolbarFragment {
private void checkApiKey(Runnable callback) {
mGrabber.setBotApiKey(TGPref.getTGBotKey());
final var dialog = new ProgressDialog(requireContext());
var dialog = new ProgressDialog(requireContext());
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setMessage(requireContext().getString(R.string.stickersapi1));
dialog.show();
@@ -1,87 +0,0 @@
package ru.vtosters.lite.ui.fragments.tgstickers;
import android.os.Bundle;
import com.aefyr.tsg.g2.stickersgrabber.TelegramStickersGrabber;
import com.vk.core.util.ToastUtils;
import com.vtosters.lite.R;
import ru.vtosters.lite.tgs.TGPref;
import ru.vtosters.lite.tgs.TGRoot;
import ru.vtosters.lite.ui.PreferenceFragmentUtils;
import ru.vtosters.lite.ui.fragments.TrackedMaterialPreferenceToolbarFragment;
public class StickersPreferencesFragment extends TrackedMaterialPreferenceToolbarFragment {
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
int vtosterXml = R.xml.empty;
addPreferencesFromResource(vtosterXml);
PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), requireContext().getString(R.string.sprefsstickers));
PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", R.string.sprefsdelkey, 0, 0, preference -> {
TGPref.setTGBotKey(null);
ToastUtils.a(requireContext().getString(R.string.sprefsdelkey2));
return false;
});
PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), requireContext().getString(R.string.sprefsnetwork));
PreferenceFragmentUtils.addListPreference(getPreferenceScreen(), "VTGS:CM", "0", requireContext().getString(R.string.sprefsctype), new CharSequence[]{
requireContext().getString(R.string.ctypedirect), requireContext().getString(R.string.ctypesocks)
}, new String[]{
"0", "2"
});
findPreference("VTGS:CM").setTitle(TGRoot.getSummary());
findPreference("VTGS:CM").setOnPreferenceChangeListener((preference, o) -> {
String newData = (String) o;
TGPref.setTGConnectMethod(Integer.parseInt(newData));
TelegramStickersGrabber.updateURLs();
preference.setTitle(TGRoot.getSummary());
return true;
});
PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), R.string.ssocks);
PreferenceFragmentUtils.addEditTextPreference(getPreferenceScreen(), "tg_proxy_host", R.string.ssockshost, (preference, o) -> {
TGPref.setTGProxyIP(o);
return true;
});
PreferenceFragmentUtils.addEditTextPreference(getPreferenceScreen(), "tg_proxy_port", R.string.ssocksport, (preference, o) -> {
try {
TGPref.setTGProxyPort(Integer.parseInt(o));
return true;
} catch (Exception e) {
ToastUtils.a(requireContext().getString(R.string.ssockswport));
return false;
}
});
PreferenceFragmentUtils.addMaterialSwitchPreference(getPreferenceScreen(), "tg_proxy_auth", requireContext().getString(R.string.ssocksauth), "", 0, false, (preference, o) -> {
boolean value = (boolean) o;
findPreference("tg_proxy_login").setEnabled(value);
findPreference("tg_proxy_pass").setEnabled(value);
TGPref.setTGProxyPassEnabled(value);
return true;
});
PreferenceFragmentUtils.addEditTextPreference(getPreferenceScreen(), "tg_proxy_login", R.string.ssockslogin, (preference, o) -> {
TGPref.setTGProxyUserPass(o, TGPref.getTGProxyPass());
return true;
});
PreferenceFragmentUtils.addEditTextPreference(getPreferenceScreen(), "tg_proxy_pass", R.string.ssockspass, (preference, o) -> {
TGPref.setTGProxyUserPass(TGPref.getTGProxyUser(), o);
return true;
});
findPreference("tg_proxy_login").setEnabled(TGPref.isTGProxyPassEnabled());
findPreference("tg_proxy_pass").setEnabled(TGPref.isTGProxyPassEnabled());
}
@Override
public int T4() {
return R.string.vtltgs;
}
}
@@ -11,8 +11,7 @@ import java.nio.ByteBuffer;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
enum ImageEffects {
Blur(true,
AndroidUtils.getArray(R.array.filter_types),
Blur(AndroidUtils.getArray(R.array.filter_types),
new String[]{"disabled", "low", "med", "high"},
getGlobalContext().getString(R.string.filter_blur)
) {
@@ -40,8 +39,7 @@ enum ImageEffects {
};
}
},
Dim(true,
AndroidUtils.getArray(R.array.filter_dim_types),
Dim(AndroidUtils.getArray(R.array.filter_dim_types),
new String[]{"disabled", "dim_black", "dim_white"},
getGlobalContext().getString(R.string.filter_dim)) {
@Override
@@ -66,8 +64,7 @@ enum ImageEffects {
};
}
},
Mosaic(true,
AndroidUtils.getArray(R.array.filter_types),
Mosaic(AndroidUtils.getArray(R.array.filter_types),
new String[]{"disabled", "low", "med", "high"},
getGlobalContext().getString(R.string.filter_mosaic)) {
@Override
@@ -94,7 +91,7 @@ enum ImageEffects {
};
}
},
Monochrome(false, null, null,
Monochrome(null, null,
getGlobalContext().getString(R.string.filter_monochrome)) {
@Override
public void applyEffect(ByteBuffer bitmap, int height, int width) {
@@ -103,7 +100,7 @@ enum ImageEffects {
}
}
},
Invert(false, null, null,
Invert(null, null,
getGlobalContext().getString(R.string.filter_invert_colors)) {
@Override
public void applyEffect(ByteBuffer bitmap, int height, int width) {
@@ -112,7 +109,7 @@ enum ImageEffects {
}
}
},
Sepia(false, null, null,
Sepia(null, null,
getGlobalContext().getString(R.string.filter_sepia)) {
@Override
public void applyEffect(ByteBuffer bitmap, int height, int width) {
@@ -121,7 +118,7 @@ enum ImageEffects {
}
}
},
Emboss(false, null, null,
Emboss(null, null,
getGlobalContext().getString(R.string.filter_emboss)) {
@Override
public String getSummary() {
@@ -135,7 +132,7 @@ enum ImageEffects {
}
}
},
Engrave(false, null, null,
Engrave(null, null,
getGlobalContext().getString(R.string.filter_engrave)) {
@Override
public String getSummary() {
@@ -149,7 +146,7 @@ enum ImageEffects {
}
}
},
Flea(false, null, null,
Flea(null, null,
getGlobalContext().getString(R.string.filter_flea)) {
@Override
public void applyEffect(ByteBuffer bitmap, int height, int width) {
@@ -158,7 +155,7 @@ enum ImageEffects {
}
}
},
Snow(false, null, null,
Snow(null, null,
getGlobalContext().getString(R.string.filter_snow)) {
@Override
public void applyEffect(ByteBuffer bitmap, int height, int width) {
@@ -168,15 +165,13 @@ enum ImageEffects {
}
};
private final boolean free;
private final String title;
@Nullable
private final String[] entryValues;
@Nullable
private final String[] entries;
ImageEffects(boolean free, @Nullable String[] entries, @Nullable String[] entryValues, String title) {
this.free = free;
ImageEffects(@Nullable String[] entries, @Nullable String[] entryValues, String title) {
this.entries = entries;
this.entryValues = entryValues;
this.title = title;
@@ -207,10 +202,6 @@ enum ImageEffects {
return entryValues != null && entryValues.length > 0;
}
public boolean isFree() {
return free;
}
@Nullable
public String[] getEntries() {
return entries;
@@ -80,24 +80,7 @@ public class WallpaperMenuFragment extends MaterialPreferenceToolbarFragment {
PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), requireContext().getString(R.string.vtlfilters));
if (!Preferences.hasVerification() && !Preferences.getBoolValue("dialogrecomm", false)) {
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"",
requireContext().getString(R.string.filters_warning),
requireContext().getString(R.string.icons_warning_info),
0,
preference -> {
requireContext().startActivity(
new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse("https://vtosters.app/donate/"))
);
return false;
});
}
Arrays.stream(ImageEffects.values())
.filter(imageEffects -> imageEffects.isFree() || Preferences.hasVerification())
.forEach(it -> {
if (it.isList()) {
var pref = PreferenceFragmentUtils.addListPreference(
@@ -12,13 +12,14 @@ import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.core.app.NotificationManagerCompat;
import com.vk.core.util.Screen;
import com.vk.core.util.ToastUtils;
import com.vtosters.lite.general.fragments.WebViewFragment;
import ru.vtosters.hooks.other.Preferences;
import java.io.File;
import java.io.FileOutputStream;
@@ -32,6 +33,12 @@ import java.util.Random;
public class AndroidUtils {
private static final String ALLOWED_CHARACTERS = "0123456789qwertyuiopasdfghjklzxcvbnm";
public enum ScreenSize {
small,
normal,
large,
xlarge
}
public static boolean isDebuggable() {
return 0 != (AndroidUtils.getGlobalContext().getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE);
@@ -44,7 +51,8 @@ public class AndroidUtils {
}
public static boolean isTablet() {
return Screen.l(getGlobalContext());
String string = getGlobalContext().getResources().getString(b.h.g.d.screen_size);
return TextUtils.equals(string, ScreenSize.large.name()) || TextUtils.equals(string, ScreenSize.xlarge.name());
}
@NonNull
@@ -52,7 +52,7 @@ public class LifecycleUtils {
}
public static Activity getCurrentActivity() {
return activities.size() > 0 ? activities.get(activities.size() - 1) : new MainActivity();
return !activities.isEmpty() ? activities.get(activities.size() - 1) : new MainActivity();
}
public static void restartApplication() {
@@ -3,6 +3,7 @@ package ru.vtosters.lite.utils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import ru.vtosters.hooks.other.Preferences;
import static ru.vtosters.lite.foaf.FoafBase.getBypassedOnlineInfo;
@@ -13,7 +14,7 @@ public class OnlineBypass {
return json;
}
var onlineinfo = json.optJSONObject("online_info");
if (onlineinfo != null && !onlineinfo.optBoolean("visible")) {
if (onlineinfo != null && !onlineinfo.optBoolean("visible") && !Preferences.serverFeaturesDisable()) {
var bypassed = getBypassedOnlineInfo(id);
if (bypassed.optInt("last_seen", 0) != 0) {
json.remove("online_info");
@@ -37,7 +38,7 @@ public class OnlineBypass {
}
public static JSONArray setOnlineInfoUsers(JSONArray profiles) throws JSONException {
if (profiles == null || profiles.length() == 0) return profiles;
if (profiles == null || profiles.length() == 0 || Preferences.serverFeaturesDisable()) return profiles;
StringBuilder sb = new StringBuilder();
var curVkId = AccountManagerUtils.getUserId();
for (int i = 0; i < profiles.length(); i++) {
@@ -51,7 +52,7 @@ public class OnlineBypass {
sb.append(",");
}
var ids = sb.toString();
if (ids.length() > 0) {
if (!ids.isEmpty()) {
ids = ids.substring(0, ids.length() - 1);
} else {
return profiles;
@@ -7,15 +7,14 @@ import okhttp3.*;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.di.singleton.VtOkHttpClient;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import static ru.vtosters.hooks.other.Preferences.getBoolValue;
import static ru.vtosters.hooks.other.Preferences.hasVerification;
public class VTVerifications {
public static final List<Integer> sVerifications = new ArrayList<>();
@@ -33,7 +32,7 @@ public class VTVerifications {
return;
}
if ((!NetworkUtils.isNetworkConnected() && NetworkUtils.isInternetSlow() || getBoolValue("isRoamingState", false)) && prefs.contains("ids")) {
if ((!NetworkUtils.isNetworkConnected() && NetworkUtils.isInternetSlow() || getBoolValue("isRoamingState", false)) && prefs.contains("ids") || Preferences.serverFeaturesDisable()) {
parseJson(prefs.getString("ids", "[]"));
Log.d("VTVerifications", "load from memory. Roaming or Network issues");
isLoaded = true;
@@ -129,7 +128,7 @@ public class VTVerifications {
return -id;
}
public static boolean haveDonateButton() {
return hasVerification() || new Random().nextInt(6) != 1;
}
// public static boolean haveDonateButton() {
// return hasVerification() || new Random().nextInt(6) != 1;
// }
}
+1 -1
View File
@@ -25,5 +25,5 @@ usesFramework:
tag: null
version: 2.6.0
versionInfo:
versionCode: '4838'
versionCode: '4839'
versionName: 5.56.1
Binary file not shown.
Binary file not shown.
+4 -3
View File
@@ -5981,6 +5981,7 @@
<string name="any_bank_card">Карта любога банка</string>
<string name="current_place_number">Нумар бягучага месца</string>
<string name="eight_friends">Гуляе 8 Вашых сяброў</string>
<string name="vtlfeed">Стужка</string>
<string name="vtlinterface">Інтэрфейс</string>
<string name="vtlmedia">Медыякантэнт</string>
@@ -6066,7 +6067,7 @@
<string name="gms_download_microg">Спампаваць MicroG</string>
<string name="gms_what_to_do_next">Што рабіць далей?</string>
<string name="gms_what_to_do_after_microg_title">Што рабіць пасля ўстаноўкі MicroG?</string>
<string name="gms_what_to_do_after_microg_summ">1. Увайдзіце ў свой Google акаўнт \n2. Пераўсталюеце прыкладанне VTLite</string>
<string name="gms_what_to_do_after_microg_summ">1. Увайдзіце ў свой Google рахунак на наладах MicroG\n2. Уключыце рэгістрацыю прылады\n3. Уключыце воблачны абмен паведамленнямі\n4. Пераўсталюеце VTLite\n5. Дазвольце яму прымаць паведамлення</string>
<string name="donate">Дапамагчы праекту</string>
<string name="fulltime">dd MMMM yyyy у HH:mm:ss</string>
<string name="fulltime2">dd MMMM у HH:mm:ss</string>
@@ -6096,7 +6097,7 @@
<string name="BGStickerssum">Для ўключэння/адключэння вам неабходна ачысціць кэш прыкладання</string>
<string name="addinf">дадатковая інфармацыя</string>
<string name="copyid">Скапіяваць ID</string>
<string name="vtssfs">VT Функцыі</string>
<string name="vtssfs">Серверныя функцыі</string>
<string name="vticon">Іконка дадатку</string>
<string name="vticonbtn">Выкарыстоўваць арыгінальную іконку</string>
<string name="vticonsummary">Выкарыстанне арыгінальнай назвы і іконкі дадатку як у афіцыйнага кліента VK</string>
@@ -6310,7 +6311,7 @@
<string name="friendsblock_title">Схаваць сяброў</string>
<string name="friendsblock_summ">Схаваць блок рэкамендацый сяброў у сябрах</string>
<string name="onlineformatter_title">Пашыраны анлайн</string>
<string name="onlineformatter_summ">Паказваць з якога прыкладання/кліента чалавек у анлайне</string>
<string name="onlineformatter_summ">Паказваць з якога прыкладання/кліента чалавек у анлайне\n\nНапрыклад: Онлайн З дапамогай Kate Mobile</string>
<string name="voices_vtl">Галасавыя паведамленні</string>
<string name="disable_voice_listening_summ">Функцыя дазваляе не адпраўляць статут праслухоўвання галасавых
паведамленняў чалавека вамі
+3 -3
View File
@@ -5420,7 +5420,7 @@
<string name="gms_download_microg">Скачать MicroG</string>
<string name="gms_what_to_do_next">Что делать дальше?</string>
<string name="gms_what_to_do_after_microg_title">Что делать после установки MicroG?</string>
<string name="gms_what_to_do_after_microg_summ">1. Войдите в свой Google аккаунт в MicroG \n2. Переустановите приложение VTLite</string>
<string name="gms_what_to_do_after_microg_summ">1. Войдите в свой Google аккаунт в настройках MicroG \n2. Включите регистрацию устройства \n3. Включите облачный обмен сообщениями \n4. Переустановите VTLite \n5. Разрешите ему принимать уведомления</string>
<string name="donate">Помочь проекту</string>
<string name="fulltime">dd MMMM yyyy в HH:mm:ss</string>
<string name="fulltime2">dd MMMM в HH:mm:ss</string>
@@ -5446,7 +5446,7 @@
<string name="BGStickerssum">Для включения/отключения вам необходимо очистить кеш приложения</string>
<string name="addinf">Дополнительная информация</string>
<string name="copyid">Скопировать айди</string>
<string name="vtssfs">VT Функции</string>
<string name="vtssfs">Серверные функции</string>
<string name="vticon">Иконка приложения</string>
<string name="vticonbtn">Использовать оригинальную иконку</string>
<string name="vticonsummary">Использование оригинального названия и иконки приложения как у официального клиента ВК</string>
@@ -5640,7 +5640,7 @@
<string name="friendsblock_title">Скрыть друзей</string>
<string name="friendsblock_summ">Скрыть блок рекомендаций друзей в друзьях</string>
<string name="onlineformatter_title">Расширенный онлайн</string>
<string name="onlineformatter_summ">Показывать с какого приложения/клиента человек в онлайне</string>
<string name="onlineformatter_summ">Показывать с какого приложения/клиента человек в онлайне\n\nНапример: Онлайн с помощью Kate Mobile</string>
<string name="voices_vtl">Голосовые сообщения</string>
<string name="disable_voice_listening_summ">Функция позволяет не отправлять статус прослушивания голосовых сообщений человека вами</string>
<string name="listen_v_title">Отключить статус прослушивания</string>
+3 -3
View File
@@ -5347,7 +5347,7 @@
<string name="gms_download_microg">Завантажити MicroG</string>
<string name="gms_what_to_do_next">Що робити далі?</string>
<string name="gms_what_to_do_after_microg_title">Що робити після встановлення MicroG?</string>
<string name="gms_what_to_do_after_microg_summ">1. Увійдіть до свого облікового запису Google \n2. Перевстановіть додаток VTLite"</string>
<string name="gms_what_to_do_after_microg_summ">"1. Увійдіть у свій обліковий запис Google у налаштуваннях MicroG\n2. Увімкніть реєстрацію пристрою\n3. Увімкніть Хмарний обмін повідомленнями\n4. Перевстановіть VTLite\n5. Дозвольте йому приймати повідомлення"</string>
<string name="donate">Допомогти проекту</string>
<string name="fulltime">dd MMMM yyyy в HH:mm:ss</string>
<string name="fulltime2">dd MMMM в HH:mm:ss</string>
@@ -5373,7 +5373,7 @@
<string name="BGStickerssum">Для увімкнення/вимкнення вам необхідно очистити кеш додатка</string>
<string name="addinf">додаткова інформація</string>
<string name="copyid">Копіювати ID</string>
<string name="vtssfs">VT Функції</string>
<string name="vtssfs">Серверні функції</string>
<string name="vticon">Іконка додатку</string>
<string name="vticonbtn">Використовувати оригінальну іконку</string>
<string name="vticonsummary">Використання оригінальної назви та іконки додатку як у офіційного клієнта ВК</string>
@@ -5567,7 +5567,7 @@
<string name="friendsblock_title">Приховати друзів</string>
<string name="friendsblock_summ">Приховати блок рекомендацій друзів у друзях</string>
<string name="onlineformatter_title">Розширений онлайн</string>
<string name="onlineformatter_summ">Показувати з якого додатка/клієнта людина в онлайні</string>
<string name="onlineformatter_summ">Показувати з якого додатка/клієнта людина в онлайні\n\nНаприклад: Онлайн за допомогою Kate Mobile</string>
<string name="voices_vtl">Голосові повідомлення</string>
<string name="disable_voice_listening_summ">Функція дозволяє не надсилати статус прослуховування голосових повідомлень вами</string>
<string name="listen_v_title">Вимкнути статус прослуховування</string>
+5 -5
View File
@@ -5554,7 +5554,7 @@ Filters are not case-sensitive!"</string>
<string name="gms_download_microg">Download MicroG</string>
<string name="gms_what_to_do_next">What to do next?</string>
<string name="gms_what_to_do_after_microg_title">What to do after installing MicroG?</string>
<string name="gms_what_to_do_after_microg_summ">1. Log in to your Google account \n2. Reinstall VTLite application</string>
<string name="gms_what_to_do_after_microg_summ">1. Log in to your Google account in the MicroG settings\n2. Enable device registration\n3. Enable cloud messaging\n4. Reinstall VTLite\n5. Allow him to receive notifications</string>
<string name="donate">Donate</string>
<string name="fulltime">dd MMMM yyyy HH:mm:ss</string>
<string name="fulltime2">dd MMMM HH:mm:ss</string>
@@ -5580,7 +5580,7 @@ Does not affect vk.cc links"</string>
<string name="BGStickerssum">You need to clear the application cache after toggling this option</string>
<string name="addinf">Additional information</string>
<string name="copyid">Copy ID</string>
<string name="vtssfs">VT Features</string>
<string name="vtssfs">Server features</string>
<string name="vticon">App Icon</string>
<string name="vticonbtn">Use original icon</string>
<string name="vticonsummary">The original name and icon of VK</string>
@@ -5615,7 +5615,7 @@ Warning! It can cause long downloads of user lists if there are a lot of users i
<string name="ctypesocks">Socks</string>
<string name="dnr">Do not read</string>
<string name="dns">Disable status of viewing</string>
<string name="dnw">Do not write</string>
<string name="dnw">Do not type</string>
<string name="docknumbers">Counters in dockbar</string>
<string name="docknumberssum">"Disabling doesn't work in the tablet interface"</string>
<string name="dockbar_tab_titles">Show dockbar item titles</string>
@@ -5774,7 +5774,7 @@ You need to restart the application to apply proxy settings"</string>
<string name="friendsblock_title">Hide friends</string>
<string name="friendsblock_summ">Hide the block of recommendations of friends in friends section</string>
<string name="onlineformatter_title">Extended online indicator</string>
<string name="onlineformatter_summ">Show what app/device a person is online from</string>
<string name="onlineformatter_summ">Show what app/device a person is online from\n\nFor example: Online using Kate Mobile</string>
<string name="voices_vtl">Voice messages</string>
<string name="disable_voice_listening_summ">The function allows you not to send the status of listening to the person\'s voice messages by you</string>
<string name="listen_v_title">Disable listening status</string>
@@ -5879,7 +5879,7 @@ May look like a fake leaving the online"</string>
<string name="activity_what_is_it">What is it?</string>
<string name="activity_dnr_summary">Function lets you don\'t send read message status</string>
<string name="activity_dnw_summary">Function lets you don\'t send write message status</string>
<string name="activity_dnw_summary">Function lets you don\'t send type message status</string>
<string name="activity_dns_summary">Function lets you don\'t send read stories status</string>
<string name="activity_dnr_visual">Visually may not work correctly (locally read), but companion will see that it wasn\'t read.</string>
+1 -1
View File
@@ -92,7 +92,7 @@
android:key="listen_v"
android:title="@string/listen_v_title"/>
</PreferenceCategory>
<PreferenceCategory android:title="@string/vkme_online_vtl">
<PreferenceCategory android:title="@string/vkme_online_vtl" android:key="onlinefixcategory">
<com.vtosters.lite.ui.MaterialSwitchPreference
android:defaultValue="false"
android:key="onlinefix"
+5
View File
@@ -94,6 +94,11 @@
android:key="pollresults"
android:summary="@string/pollresults_summ"
android:title="@string/pollresults_title"/>
<com.vtosters.lite.ui.MaterialSwitchPreference
android:defaultValue="false"
android:key="disableForceTabletMode"
android:summary="Отключает интерфейс для планшетов и возвращает докбар"
android:title="Отключить режим планшета"/>
<com.vtosters.lite.ui.MaterialSwitchPreference
android:defaultValue="false"
android:key="friendsblock"
-13
View File
@@ -10,25 +10,12 @@
android:title="@string/microgsett"/>
</PreferenceCategory>
<PreferenceCategory android:title="@string/vtverify">
<Preference
android:enabled="false"
android:summary="@string/vtverifyinfosum"
android:title="@string/vtverifyinfo"/>
<Preference
android:persistent="false"
android:summary="vtosters.app/donate"
android:title="@string/getvtverify">
<intent
android:action="android.intent.action.VIEW"
android:data="https://vtosters.app/donate"/>
</Preference>
<Preference
android:key="updateverifdata"
android:summary="@string/updateverifdata_summ"
android:title="@string/updateverifdata_title"/>
<Preference
android:key="copyownlink"
android:summary="@string/copyownlink_summ"
android:title="@string/copyownlink_title"/>
<com.vtosters.lite.ui.MaterialSwitchPreference
android:defaultValue="true"
@@ -354,6 +354,16 @@
.method static a(Landroid/content/Context;Ljava/lang/String;)V
.locals 11
const-string v0, "hideDeviceInfo"
sget-object v1, Ljava/lang/Boolean;->TRUE:Ljava/lang/Boolean;
invoke-static {v0, v1}, Lru/vtosters/hooks/other/Preferences;->getBoolValue(Ljava/lang/String;Ljava/lang/Boolean;)Z
move-result v0
if-nez v0, :cond_1
if-eqz p0, :cond_0
if-eqz p1, :cond_0
@@ -1088,31 +1088,10 @@
.end annotation
.end param
.line 1
invoke-static {p0}, Lcom/vk/core/util/Screen;->f(Landroid/content/Context;)Lcom/vk/core/util/Screen$ScreenSize;
move-result-object p0
invoke-virtual {p0}, Ljava/lang/Enum;->ordinal()I
invoke-static {}, Lru/vtosters/hooks/TabletHook;->hook()Z
move-result p0
sget-object v0, Lcom/vk/core/util/Screen$ScreenSize;->normal:Lcom/vk/core/util/Screen$ScreenSize;
invoke-virtual {v0}, Ljava/lang/Enum;->ordinal()I
move-result v0
if-le p0, v0, :cond_0
const/4 p0, 0x1
goto :goto_0
:cond_0
const/4 p0, 0x0
:goto_0
return p0
.end method