Compare commits

...
142 Commits
Author SHA1 Message Date
gdlbo 0cdccd6a54 TargetImageView 2022-08-06 17:39:34 +03:00
gdlbo 829a333d7f disabled pinned msg buttons 2022-08-06 15:26:29 +03:00
gdlbo 42984efe25 max dp 10 2022-08-06 14:00:24 +03:00
gdlbo 7656468636 rounding hook fixes 2022-08-06 13:40:40 +03:00
gdlbo 448a169bc3 code imp 2022-08-06 12:49:56 +03:00
gdlbo 27cacc03a2 code imp 2022-08-05 23:13:35 +03:00
gdlbo 2002db57d9 DownloadUtils fixes 2022-08-05 22:24:29 +03:00
gdlbo 0aad1ef358 DownloadUtils 2022-08-05 21:41:34 +03:00
gdlbo d8f5b5e910 dir fixes 2022-08-05 21:21:18 +03:00
aliveoutside 3d5c832cec use different request codes for different download types 2022-08-05 21:07:30 +03:00
gdlbo bc467ac335 more folders picker 2022-08-05 20:49:09 +03:00
gdlbo aee5f38fb5 more folders picker 2022-08-05 20:39:24 +03:00
aliveoutside a4612a127d implement download folder picker 2022-08-05 19:53:02 +03:00
gdlbo 7a21f11b64 some code imp 2022-08-05 19:48:31 +03:00
gdlbo 4775715b66 some code imp 2022-08-05 19:47:53 +03:00
gdlbo c481d5fca9 some code imp 2022-08-05 19:28:27 +03:00
aliveoutside be65e6816d fix #571
also get rid of java reflection
2022-08-05 03:03:40 +03:00
gdlbo 1f2200c584 come imp 2022-08-04 15:49:48 +03:00
gdlbo 52b58dc79b some code imp 2022-08-04 14:47:36 +03:00
gdlbo de92e4670c DialogItemView converted to java
i am dead inside tbh
2022-08-04 14:30:29 +03:00
gdlbo 4806bb89eb Merge pull request #566 from k1zn/vtl-remaster 2022-08-04 01:24:22 +03:00
Erik Kiznov 0cdbf9ce99 another renaming 2022-08-04 02:02:44 +05:00
Erik Kiznov a7bde644a4 Merge branch 'vtl-remaster' of https://github.com/k1zn/lite into vtl-remaster 2022-08-04 02:01:18 +05:00
Erik Kiznov e461b4654e edit some strings about filters 2022-08-04 01:59:47 +05:00
k1zn 8d7f2dfee8 Fix lower case bug 2022-08-04 01:55:18 +05:00
k1zn bf5bc08671 Renaming 2022-08-04 01:22:06 +05:00
Erik Kiznov 437bef3d03 Add filter for source name 2022-08-04 01:08:30 +05:00
gdlbo 024079c4bc fixed def catalog music 2022-08-01 22:34:14 +03:00
gdlbo ed53f509ee ads_tracking_disabled true 2022-08-01 22:17:38 +03:00
gdlbo 6b90aedae8 adblock lmao 2022-08-01 21:36:47 +03:00
gdlbo 4db73ff3d1 Reducing the size of news traffic by disabling the ad request 2022-08-01 21:09:08 +03:00
aliveoutside 4a092f0920 fix #465
added a check for "Music" folder existence
2022-08-01 16:50:29 +03:00
Vologhat 186c1f80e6 added "likes on right" displaying mode for posts and viewers 2022-08-01 13:33:58 +03:00
gdlbo 59c8be9ac2 some vkui improvements 2022-08-01 01:53:50 +03:00
gdlbo eb2c4c02d2 some fixes 2022-08-01 00:48:58 +03:00
gdlbo fe2fd354fd read to feature 2022-08-01 00:39:02 +03:00
k1zn 16fd8925ff Add translate function to catch 2022-07-31 23:01:30 +03:00
k1zn 661302d90f Remove %
The percentage in the text breaks the translation process, so I remove it.
2022-07-31 23:01:30 +03:00
Erik Kiznov 2c8dd6e89a Another refactoring... 2022-07-31 23:01:30 +03:00
Erik Kiznov 91fe8a8fb4 Add @ support 2022-07-31 23:01:30 +03:00
Erik Kiznov cc3456758e Fix bug 2022-07-31 23:01:30 +03:00
Erik Kiznov c2dc772905 Refactoring 2022-07-31 23:01:30 +03:00
Erik Kiznov 9915e8d2df Don't translate mentions
Don't translate mentions in MessagesHook
2022-07-31 23:01:30 +03:00
gdlbo 5c79dbe1c2 req dumper 2022-07-31 22:26:36 +03:00
gdlbo f83e97404a video history delete 2022-07-31 18:33:37 +03:00
aliveoutside f704d54178 fix #450 / #547 and speed up logout 2022-07-31 18:10:30 +03:00
gdlbo 3577e3b70c about debug activation 2022-07-31 16:58:39 +03:00
gdlbo 000bd5e7d3 settings moment 2022-07-31 14:04:23 +03:00
gdlbo 4d3e8d4354 cache moment 2022-07-31 13:42:50 +03:00
gdlbo 0d51b40676 deepl ded 2022-07-31 13:34:24 +03:00
Erik Kiznov 054f03480e Fix strings about bombs 2022-07-31 13:34:24 +03:00
Vologhat 114b46ccee added translation language as argument 2022-07-31 13:34:24 +03:00
gdlbo 0715c0cfcf some imp 2022-07-31 13:34:24 +03:00
gdlbo a51a146780 fixed gtranslate + added reply’s translate 2022-07-31 13:34:24 +03:00
gdlbo c2c3ea68fa some imp 2022-07-31 13:34:24 +03:00
gdlbo 8e40da9fb4 compiling fix 2022-07-31 13:34:23 +03:00
gdlbo d6b744533b compiling fix 2022-07-31 13:34:23 +03:00
Vologhat df1d411ae0 added new translators and choicing of that 2022-07-31 13:34:23 +03:00
gdlbo 2904616d67 Update MessagesSendApiCmd.smali 2022-07-31 13:34:23 +03:00
gdlbo 61eac6feca some fixes 2022-07-31 13:34:23 +03:00
gdlbo 1f29f2ddc5 fixed dialog 2022-07-31 13:34:23 +03:00
gdlbo fbff3eadde dialog fixes 2022-07-31 13:34:23 +03:00
gdlbo 7c8a76616c added bombs 2022-07-31 13:34:23 +03:00
gdlbo 465d52df67 updated icons 2022-07-31 13:34:23 +03:00
gdlbo 57e69b0d98 Create ic_deepl_logo_icon.xml 2022-07-31 13:34:22 +03:00
gdlbo a799828de0 some icons 2022-07-31 13:34:22 +03:00
gdlbo e6ad306e24 migrated to vkalertdialog 2022-07-31 13:34:22 +03:00
gdlbo 5ff1e0a0a6 Update DNRInjector.java 2022-07-31 13:34:22 +03:00
gdlbo 09048a7a21 china number one 2022-07-31 13:34:22 +03:00
gdlbo 2e2e890875 updated translate dialog 2022-07-31 13:34:22 +03:00
gdlbo 271b1cdfee Update Translate.java 2022-07-31 13:34:08 +03:00
gdlbo bc06512250 fixed onclick 2022-07-31 13:34:08 +03:00
gdlbo a94af3a4db message hook 2022-07-31 13:34:08 +03:00
gdlbo 924a34b458 code imp 2022-07-31 13:34:07 +03:00
Vologhat f73b880b6d added messages hook and base class for translators 2022-07-31 13:34:07 +03:00
Vologhat a53a9eaeaa fixed errors 2022-07-31 13:34:07 +03:00
gdlbo 88390f0fc9 dialog 2022-07-31 13:33:42 +03:00
gdlbo c6721841ac rebase 2022-07-31 13:33:31 +03:00
Vologhat dfa77311f2 removed deepl and added yandex 2022-07-31 13:32:49 +03:00
Vologhat 57e241ab7d replace net to okhttp 2022-07-31 13:32:48 +03:00
gdlbo 50b97aac8a DeepLApi test 2022-07-31 13:32:48 +03:00
k1zn 6166b29b29 Update README.md 2022-07-30 18:32:54 +03:00
gdlbo 7ee1331263 fixed msg 2022-07-30 17:54:26 +03:00
gdlbo 0cc0299215 deviceinfo and geodata hide feature 2022-07-30 17:37:28 +03:00
iNotFlying a7e0f2ae2b Update README.md 2022-07-30 15:48:05 +03:00
gdlbo c38e0aa61e fixed adding music catalog bug 2022-07-30 13:59:54 +03:00
iNotFlying 9496da151a Refactoring 2022-07-30 02:33:23 +03:00
gdlbo 5cec11c6dd dialog pin/unpin system (api) 2022-07-30 01:13:52 +03:00
gdlbo a285bf4270 updated stock icon 2022-07-29 23:54:37 +03:00
aliveoutside 344c418412 Merge pull request #539 from ricoshett/vtl-remaster
добавлена быстрая навигация
размер изображений в блоке Линукса и Винды теперь одинаков
2022-07-29 18:30:14 +03:00
gdlbo 5464053fa0 code beautifying 2022-07-29 16:28:49 +03:00
ricoshett 8036fc332b update README.md 2022-07-29 16:23:44 +03:00
aliveoutside c1cb5c23ae update ffmpeg-kit 2022-07-29 18:39:39 +03:00
gdlbo dbb25fbabd some java moments 2022-07-29 16:14:24 +03:00
k1zn d75a339a02 Fix README.md 2022-07-29 15:20:07 +03:00
aliveoutside 6fd15a05ff Merge pull request #536 from k1zn/vtl-remaster
<!> Ignore *.md files in Github Actions
2022-07-29 14:49:54 +03:00
aliveoutside 0d991138c0 Update README.md (Update README.md)
Update README.md (Update README.md) (Update README.md)
2022-07-29 14:49:44 +03:00
k1zn 5264a397a0 Update build.yml 2022-07-29 16:41:30 +05:00
iNotFlying c2fe5e6c3c Update README.md 2022-07-29 12:52:35 +04:00
iNotFlying 7c232b70ed Update README.md 2022-07-29 12:50:27 +04:00
iNotFlying 8761d23bda Update README.md 2022-07-29 12:30:41 +04:00
iNotFlying 81203ef531 Update README.md 2022-07-29 12:29:31 +04:00
iNotFlying 743356af01 Update README.md 2022-07-29 12:17:27 +04:00
iNotFlying 036cf4846c Update README.md 2022-07-29 12:15:21 +04:00
iNotFlying 7f97394861 Update README.md 2022-07-29 12:13:31 +04:00
aliveoutside d439469f39 Merge pull request #532 from k1zn/vtl-remaster
fixes a bug where pinned dialogs don't show up in the message section
2022-07-29 01:32:05 +03:00
k1zn 8ec891d0bc Fix locals + fix fields 2022-07-29 03:13:58 +05:00
k1zn bb318aeeb1 Set MessagesGetConversationsApiCmd fields to public 2022-07-29 02:29:00 +05:00
k1zn 6621f7c2a2 Add support for major_sort_id in messages
This commit fixes a bug where pinned dialogs don't show up in the message section.
2022-07-29 02:15:53 +05:00
iNotFlying 108e212c56 Update README.md 2022-07-28 23:15:47 +03:00
iNotFlying f923db90ea Update README.md 2022-07-28 23:15:47 +03:00
k1zn e5a0e9617b Update README.md 2022-07-28 23:15:47 +03:00
k1zn e0d27dd97c Update README.md 2022-07-28 23:15:47 +03:00
k1zn 5d49fc586b Update README.md 2022-07-28 23:15:47 +03:00
k1zn e1beef2e29 Update README.md 2022-07-28 23:15:47 +03:00
gdlbo 0803e73949 added music grabber 2022-07-28 20:16:01 +03:00
gdlbo e7b8dd56fe icon changed 2022-07-28 18:02:20 +03:00
gdlbo add56248e1 Revert "Temporary fix for pinned dialogs"
This reverts commit 90a539d361.
2022-07-28 17:48:31 +03:00
k1zn 90a539d361 Temporary fix for pinned dialogs
A temporary fix for pinned dialogs, so that they at least appear in the section
2022-07-28 17:45:45 +03:00
gdlbo ed2645e3ff cache sett refactoring 2022-07-28 15:49:24 +03:00
gdlbo cdc8d2eaf2 screenshot detect 2022-07-28 13:21:37 +03:00
gdlbo bdb9dc670c some code improvements 2022-07-28 11:46:08 +03:00
gdlbo 32b3a035a8 some settings logic reworked 2022-07-28 02:24:38 +03:00
gdlbo c44aea13d6 some improvements of scrobbler 2022-07-28 01:41:21 +03:00
gdlbo ce4bb21782 fixed hint text 2022-07-28 01:40:51 +03:00
gdlbo fa5716d651 Update Scrobbler.java 2022-07-28 00:49:39 +03:00
gdlbo c7971c9860 Update Scrobbler.java 2022-07-28 00:46:52 +03:00
gdlbo 9d3e7c53de lastfm test 2022-07-28 00:15:41 +03:00
gdlbo 81c4e1c019 fixed crashreporter 2022-07-28 00:15:41 +03:00
Vologhat a4125653cf The great refactoring 2022-07-27 21:05:15 +03:00
gdlbo 3c3b51d6ab podcasts are dead + returned old vk pay 2022-07-27 18:03:45 +03:00
gdlbo 9e21dee290 some pic fixes 2022-07-27 16:42:50 +03:00
gdlbo c341e493f8 upped conv api ver 2022-07-27 15:51:30 +03:00
gdlbo e6325c74d8 upped vk hardcoded build number 2022-07-27 13:52:12 +03:00
gdlbo e703adb168 some music fixes 2022-07-27 13:33:47 +03:00
gdlbo ae2b9e0cce some default prefs fix 2022-07-26 19:21:08 +03:00
gdlbo 6db84cbc12 default prefs + fix default fragment 2022-07-26 19:09:38 +03:00
gdlbo db41faee3e temp fix for a10+ 2022-07-26 18:50:45 +03:00
gdlbo 905158bb07 some deobf FileUtils (why?) 2022-07-26 18:42:13 +03:00
k1zn a08782de4e Fix access_token regex (again) 2022-07-26 18:14:32 +03:00
k1zn 0fcbffab26 Fix access_token regex 2022-07-26 18:14:32 +03:00
gdlbo 30d6ccbd9a fix comments 2022-07-26 18:13:40 +03:00
387 changed files with 7612 additions and 15016 deletions
+4
View File
@@ -4,11 +4,15 @@ on:
push:
branches:
- '*'
paths-ignore:
- '**.md'
pull_request:
types:
- opened
- synchronize
- reopened
paths-ignore:
- '**.md'
workflow_dispatch:
+147 -57
View File
@@ -1,99 +1,189 @@
# VTosters Lite
<p align="center">
<a href="https://vtosters.app/">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://cdn.discordapp.com/attachments/918864618116481029/1002916719595106344/VT_Fill_Logo_Dark.svg">
<img src="https://cdn.discordapp.com/attachments/918864618116481029/1002916719381201036/VT_Fill_Logo_Light.svg">
</picture>
</a>
<br>
<br>
<a href="https://t.me/s/vtosters">
<img src="https://img.shields.io/badge/-Telegram-blue?style=for-the-badge&logo=telegram&color=2AABEE"/>
</a>
<a href="https://vk.com/vtosters_official">
<img src="https://img.shields.io/badge/-VK-blue?style=for-the-badge&logo=vk&color=0077FF"/>
</a>
<a href="https://discord.gg/j9CAt3uYXj">
<img src="https://img.shields.io/badge/-Discord-blue?style=for-the-badge&logo=discord&color=5865F2&logoColor=FFFFFF"/>
</a>
<br>
<a href="https://github.com/vtosters/lite/issues">
<img src="https://img.shields.io/github/issues/vtosters/lite?style=flat-square"/>
</a>
<a href="https://github.com/vtosters/lite/network/members">
<img src="https://img.shields.io/github/forks/vtosters/lite?style=flat-square"/>
</a>
<a href="https://github.com/vtosters/lite/stargazers">
<img src="https://img.shields.io/github/stars/vtosters/lite?style=flat-square"/>
</a>
</p>
ВТостерс Lite - это модифицированный клиент (декомпиляция) официального ВКонтакте основанный на версии 5.56.1 (4838)
**ВТостерс Lite** — это модифицированный клиент официального ВКонтакте, основанный на версии **5.56.1 (4838)**
О найденных багах сообщать в [issues](https://github.com/vtosters/lite/issues), просьба не плодить дубликаты, воспользуйтесь поиском перед созданием нового issue
* Вы можете предложить свои идеи/сообщить о багах в [Issues](https://github.com/vtosters/lite/issues)
Скачивать самые актуальные версии можно с [Actions](https://github.com/vtosters/lite/actions)
* Скачивать самые актуальные версии можно с [Actions](https://github.com/vtosters/lite/actions)
<sup><sub>(могут содержать баги)</sub></sup>
Стабильные сборки находятся в [Releases](https://github.com/vtosters/lite/releases)
* Стабильные сборки находятся в [Releases](https://github.com/vtosters/lite/releases)
Зеркало на нашем [Git](https://git.maki.su/gdlbo/lite)
Зеркало на нашем [<img src="https://git.maki.su/assets/img/logo.svg" align="center" width="20" height="20"/> Git](https://git.maki.su/gdlbo/lite)
Зеркало на [Github](https://github.com/vtosters/lite)
### Быстрая навигация
* [Функционал](#функционал)
* [Отладка приложения](#отладка-приложения)
* [Разработка](#разработка)
* [Всё необходимое для сборки и компиляции](#всё-необходимое-для-сборки-и-компиляции)
* [Необходимые зависимости](#необходимые-зависимости)
* [Linux/macOS](#linuxmacos)
* [Windows](#windows)
## Функционал
* Лента
* Блокировка рекламы в ленте
* Блокировка постов через фильтры
* Возможность отключить рекомендации от ВК
* Редактор докбара
* Редактор элементов Superapp
* Медиа контент
* Округление дат
* 1 января в 4:20
* 1 января в 4:20:00
* 1 января 2000 в 4:20:00
* Округление чисел
* Сокращение постов **(Показать полностью)**
* Результаты опросов без участия
* Интеграция с <a href="https://www.last.fm/">LAST.FM</a> (а также возможность скробблинга)
* Новый раздел музыки
* Возможность скачивать видео
* Возможность найти фотографию через поисковые системы
* Интеграция с <a href="https://vkx.app/">VK X</a>
* Сообщения
* Обои в сообщениях
* Возможность выключения кнопки записи голосовых сообщений
* Возможность скрыть блок рекомендаций в сообщениях
* Режим **VK Me**
* Возможность вернуть вкладку уведомлений
* Встроенный переводчик текста для сообщений
* Возможность выбрать язык перевода
* Автоматический перевод ваших сообщений на выбранный язык
* Альтернативный дизайн эмодзи меню
* Возможность использовать системные эмодзи
* Активность
* Возможность видеть удаленные сообщения
* Функционал, позволяющий оставаться в «оффлайне» (принудительный оффлайн/не отправлять статус онлайна и т.п.)
* Нечиталка/неписалка для ЛС/бесед/ботов/групп
* Возможность отключить информацию о том, что вы просмотрели историю/прослушали голосовое сообщение
* Возможность видеть онлайн пользователей, если у вас скрыт онлайн через VK Messenger
* Отключить уведомление о том, что вы сделали скриншот в беседе
* Отключение редиректа через away.php
* Внешний вид
* **Milkshake** тема (дизайн новых версий ВК)
* Название заголовков в докбаре
* Возможность использовать акцент для иконок
* Возможность отключить счётчики в докбаре
* Смена иконки приложения (содержит много уникальных иконок для донатеров)
* Возможность покрасить панель навигации, веб-страницы
* Telegram Стикеры
* Возможность загружать свои стикерпаки из Telegram во ВКонтакте
* Интерфейс
* Возможность отключить блок историй наверху ленты
* Возможность отключить боковую камеру в разделе «Новости»
* Возможность отключить блок «Что у вас нового?» в разделе «Новости»
* Возможность менять раздел, который запускается при запуске
* Анимации фрагментов
* Возможность отключить редизайн видеопостов
* Возможность отключить блок миниаппов/VK Pay/Superapp
* Возможность отключить сокращение названий разделов в меню
* Возможность скрыть блок рекомендаций друзей в разделе «Друзья»
* Возможность скрыть подписи в настройках
* Прокси
* Возможность использовать **HTTP/HTTPS/SOCKS** прокси, менять домены **API/OAuth/Static**
* Другое
* Очистка кеша приложения (**всё/стикеры/изображения/видео/сообщения/WebView**)
* Автоочистка кеша при достижении указанного вами значения (**100/500 MB, 1/2/5 GB**)
* Функционал для **дебага приложения/бэкап возможности/верификации VTosters**
А также:
* Галочки, которые видны только пользователям приложения **ВТостерс Lite** (подробнее тут: [vtosters.app](https://vtosters.app) ➝ Пожертвования)
* Оптимизация приложения VK (удаление ненужных библиотек, которые встроены в оригинальный VK)
И многое другое!
## Отладка приложения
Для отладки с помощью Android Studio необходимо пройти в `/smali/AndroidManifest.xml`
```
android:debuggable="false" -> android:debuggable="true"
```
Для отладки с помощью <a href="#"><img src="https://i.imgur.com/cPvvFDP.png" align="center" width="20" height="23"/></a> Android Studio необходимо пройти в `/smali/AndroidManifest.xml` и изменить значение `android:debuggable`:
Для дополнительной отладки ответов, доп логов и подмены данных для дебаг приложения необходимо включить **Режим разработчика**
```
Настройки -> О приложении -> Для разработчиков -> Режим разработчика
```
`android:debuggable="false"` ➝ `android:debuggable="true"`
Для просмотра трафика необходимо отключить функцию **SSL Pinning**
Настройки, необходимые для **отладки** вне Android Studio, находятся по этой ссылке: [vk.com/vt/debug](https://vk.com/vt/debug)
```
Настройки -> О приложении -> Для разработчиков -> SSL Pinning
```
* Для дополнительной отладки ответов и логов необходимо включить **[Режим разработчика]**
Для логгирования внутренних запросов к API необходимо включить функции **Логгирование API**
* Для просмотра SSL-трафика необходимо **отключить** функцию **[SSL Pinning]**
(Работает только при использовании внутреннего логгера!)
* Для логгирования внутренних запросов к API необходимо включить функцию **[Логгирование API]** <sup>(работает только при использовании внутреннего логгера!)</sup>
```
Настройки -> О приложении -> Для разработчиков -> Логгирование API
```
* Для использования внутреннего логгера необходимо включить функцию **[Запись логов в файл]**
Для использования внутреннего логгера необходимо включить функции **Запись логов в файл**
```
Настройки -> О приложении -> Для разработчиков -> Запись логов в файл
```
Сразу после нажатия на запись аппа начнет записывать **все действия** в файлы по пути
```
/VK/logs/com.vtosters.lite
```
При следующем открытии аппы она автоматически запакует эти файлы и отправит вам в **Документы** ВК
Сразу после нажатия на запись приложение начнет записывать **все ваши действия** по пути `/Download/VK/logs/com.vtosters.lite/`
Позже архив можно будет скачать и работать с файлами логов которые находятся в нем
При следующем открытии приложения оно автоматически сохранит логи и отправит вам в [**Документы** ВК](https://vk.com/docs), откуда вы можете скачать архив логов и работать с ними.
## Разработка
Для понимания декомпилированного кода требуется использовать **Dex to Java** декомпилятор [jadx](https://github.com/skylot/jadx) или же сторонние варианты как [Fernflower](https://github.com/fesh0r/fernflower)
Для понимания работы декомпилированного кода требуется использовать **Dex to Java** декомпилятор [jadx](https://github.com/skylot/jadx) или же сторонние варианты как [Fernflower](https://github.com/fesh0r/fernflower)
Рекомендуется установка **Android Debug Bridge** в систему ([Гайд как это сделать](https://technastic.com/system-wide-adb-fastboot-windows-10))
При нахождении решения каких-либо проблем ждем вас в [Pull Requests](https://github.com/vtosters/lite/pulls)
Для индексации декомпилированного кода в Studio используется [dex2jar](https://github.com/pxb1988/dex2jar)
* Рекомендуется установка **ADB** в систему ([гайд](https://technastic.com/system-wide-adb-fastboot-windows-10))
Сгенерированные библиотеки из дексов находятся в `/app/libs`
* Для индексации декомпилированного кода в Studio используется [dex2jar](https://github.com/pxb1988/dex2jar)
При чистой перекомпиляции дексов в jar может сломаться некоторая индексация файлов, исправляйте ручками что попадется (К примеру какие-то функции в дексах изменены с **private** на **public**)
Сгенерированные библиотеки из .dex файлов находятся в `/app/libs`
При чистой перекомпиляции .dex в .jar может сломаться некоторая индексация файлов, исправляйте ручками что попадется (К примеру какие-то функции в дексах изменены с **private** на **public**)
Для сборки декомпилированного кода и ресурсов используется [Apktool](https://github.com/iBotPeaches/Apktool)
А при нахождении решения каких-либо проблем ждем вас в [Pull Requests](https://github.com/vtosters/lite/pulls)
### Всё необходимое для сборки и компиляции
`Не меняйте packagename во избе­жа­ние проблем с приложением`
```diff
- Не меняйте имя пакета во избежание проблем с приложением
`Некоторые функции связанные с музыкой не будут работать в пересобранном приложении`
- Некоторые функции, связанные с музыкой не будут работать в пересобранном приложении
```
Весь декомпилированный код клиента находится в `/smali`
* Весь декомпилированный код клиента находится в `/smali`
Весь исходный код модификации находится в `/app`
* Весь исходный код модификации находится в `/app`
Все необходимые скрипты/жарники для компиляции APK, его подписывании и не только находятся в `/scripts`
* Все необходимые скрипты/.jar файлы для компиляции APK, его подписывании и не только находятся в `/scripts`
### Необходимые зависимости
Требуется установленная **Java** >11 версии
<a href="https://www.oracle.com/java/technologies/downloads/"><img src="https://i.imgur.com/z8ZN19a.png" align="center" width="20" height="23"/> **JDK**</a> >11 версии
Требуется установленная **Android Studio**
<a href="https://developer.android.com/studio"><img src="https://i.imgur.com/cPvvFDP.png" align="center" width="20" height="23"/> **Android Studio**</a>
### Linux/macOS
```
./build.sh
```
![](https://cdn.discordapp.com/attachments/762063967979175946/961657476317581393/unknown.png)
Для сборки используется файл `./build.sh`
<img src="https://i.imgur.com/8BMX8lG.png" width="550" height="368"/>
### Windows
```
build.bat
```
Для сборки используется файл `build.bat`
![](https://cdn.discordapp.com/attachments/762063967979175946/961682299366309928/unknown.png)
<img src="https://i.imgur.com/iZSUKJ6.png" width="550" height="368"/>
+1 -1
View File
@@ -73,7 +73,7 @@ android {
defaultConfig {
applicationId "ru.vtosters.lite.utils.lite"
minSdkVersion 24
minSdkVersion 21
targetSdkVersion 32
versionCode 1
versionName "1.0"
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
b26e21ded459fd6a5748e46f9c0a39d5b6b7f939
@@ -5,7 +5,7 @@ package bruhcollective.itaysonlab.libvkx;
// Works only with original signature of VT
public interface ILibVkxService extends android.os.IInterface{
public interface ILibVkxService extends android.os.IInterface {
void play(java.util.List<String> audio_ids, int index, String playbackContext) throws android.os.RemoteException;
int getUserId() throws android.os.RemoteException;
@@ -24,42 +24,42 @@ public interface ILibVkxService extends android.os.IInterface{
/**
* Default implementation for ILibVkxService.
*/
class Default implements ILibVkxService{
class Default implements ILibVkxService {
// Starts playback. playbackContext can be "other" if you don't sure what it is
@Override
public void play(java.util.List<String> audio_ids, int index, String playbackContext) throws android.os.RemoteException{
public void play(java.util.List<String> audio_ids, int index, String playbackContext) throws android.os.RemoteException {
}
// A UserID. CHECK FOR THIS TO BE EQUAL BEFORE SENDING ANYTHING TO SERVICE!
@Override
public int getUserId() throws android.os.RemoteException{
public int getUserId() throws android.os.RemoteException {
return 0;
}
// Cache add/remove
@Override
public void addTrackToCache(int track_id, int owner_id, String access_key) throws android.os.RemoteException{
public void addTrackToCache(int track_id, int owner_id, String access_key) throws android.os.RemoteException {
}
@Override
public void deleteTrackFromCache(int track_id, int owner_id) throws android.os.RemoteException{
public void deleteTrackFromCache(int track_id, int owner_id) throws android.os.RemoteException {
}
@Override
public boolean isTrackCached(int track_id, int owner_id) throws android.os.RemoteException{
public boolean isTrackCached(int track_id, int owner_id) throws android.os.RemoteException {
return false;
}
// Get a list of cached tracks. The response is close to VK's original response (an audio list)
// Also, the items in the list are JSON ones.
@Override
public java.util.List<String> getCache() throws android.os.RemoteException{
public java.util.List<String> getCache() throws android.os.RemoteException {
return null;
}
@Override
public android.os.IBinder asBinder(){
public android.os.IBinder asBinder() {
return null;
}
}
@@ -69,7 +69,7 @@ public interface ILibVkxService extends android.os.IInterface{
/**
* Local-side IPC implementation stub class.
*/
abstract class Stub extends android.os.Binder implements ILibVkxService{
abstract class Stub extends android.os.Binder implements ILibVkxService {
static final int TRANSACTION_play = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_getUserId = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_addTrackToCache = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
@@ -81,7 +81,7 @@ public interface ILibVkxService extends android.os.IInterface{
/**
* Construct the stub at attach it to the interface.
*/
public Stub(){
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
@@ -89,7 +89,7 @@ public interface ILibVkxService extends android.os.IInterface{
* Cast an IBinder object into an bruhcollective.itaysonlab.libvkx.ILibVkxService interface,
* generating a proxy if needed.
*/
public static ILibVkxService asInterface(android.os.IBinder obj){
public static ILibVkxService asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
@@ -100,7 +100,7 @@ public interface ILibVkxService extends android.os.IInterface{
return new Proxy(obj);
}
public static boolean setDefaultImpl(ILibVkxService impl){
public static boolean setDefaultImpl(ILibVkxService impl) {
if (Proxy.sDefaultImpl == null && impl != null) {
Proxy.sDefaultImpl = impl;
return true;
@@ -108,19 +108,19 @@ public interface ILibVkxService extends android.os.IInterface{
return false;
}
public static ILibVkxService getDefaultImpl(){
public static ILibVkxService getDefaultImpl() {
return Proxy.sDefaultImpl;
}
@Override
public android.os.IBinder asBinder(){
public android.os.IBinder asBinder() {
return this;
}
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException{
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
String descriptor = DESCRIPTOR;
switch(code) {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(descriptor);
return true;
@@ -190,27 +190,27 @@ public interface ILibVkxService extends android.os.IInterface{
}
}
private static class Proxy implements ILibVkxService{
private static class Proxy implements ILibVkxService {
public static ILibVkxService sDefaultImpl;
private final android.os.IBinder mRemote;
Proxy(android.os.IBinder remote){
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public android.os.IBinder asBinder(){
public android.os.IBinder asBinder() {
return mRemote;
}
// Starts playback. playbackContext can be "other" if you don't sure what it is
public String getInterfaceDescriptor(){
public String getInterfaceDescriptor() {
return DESCRIPTOR;
}
// A UserID. CHECK FOR THIS TO BE EQUAL BEFORE SENDING ANYTHING TO SERVICE!
@Override
public void play(java.util.List<String> audio_ids, int index, String playbackContext) throws android.os.RemoteException{
public void play(java.util.List<String> audio_ids, int index, String playbackContext) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
@@ -232,7 +232,7 @@ public interface ILibVkxService extends android.os.IInterface{
// Cache add/remove
@Override
public int getUserId() throws android.os.RemoteException{
public int getUserId() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
@@ -252,7 +252,7 @@ public interface ILibVkxService extends android.os.IInterface{
}
@Override
public void addTrackToCache(int track_id, int owner_id, String access_key) throws android.os.RemoteException{
public void addTrackToCache(int track_id, int owner_id, String access_key) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
@@ -273,7 +273,7 @@ public interface ILibVkxService extends android.os.IInterface{
}
@Override
public void deleteTrackFromCache(int track_id, int owner_id) throws android.os.RemoteException{
public void deleteTrackFromCache(int track_id, int owner_id) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
@@ -295,7 +295,7 @@ public interface ILibVkxService extends android.os.IInterface{
// Also, the items in the list are JSON ones.
@Override
public boolean isTrackCached(int track_id, int owner_id) throws android.os.RemoteException{
public boolean isTrackCached(int track_id, int owner_id) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
@@ -317,7 +317,7 @@ public interface ILibVkxService extends android.os.IInterface{
}
@Override
public java.util.List<String> getCache() throws android.os.RemoteException{
public java.util.List<String> getCache() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.util.List<String> _result;
@@ -1,6 +1,6 @@
package bruhcollective.itaysonlab.libvkx.client;
public class ClientConstants{
public class ClientConstants {
public final static String ACTION = "bruhcollective.itaysonlab.libvkx.LIBVKX_SERVICE";
public final static String PACKAGE = "ua.itaysonlab.vkx";
}
@@ -1,11 +1,11 @@
package bruhcollective.itaysonlab.libvkx.client;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.RemoteException;
import android.util.Log;
import com.vk.dto.music.MusicTrack;
import com.vk.music.common.MusicPlaybackLaunchContext;
@@ -15,35 +15,36 @@ import java.util.List;
import bruhcollective.itaysonlab.libvkx.ILibVkxService;
public class LibVKXClient{
public class LibVKXClient {
@SuppressLint("StaticFieldLeak")
private static LibVKXClientImpl impl;
public static LibVKXClientImpl getInstance(Context context){
public static LibVKXClientImpl getInstance(Context context) {
if (impl == null) {
impl = new LibVKXClientImpl(context);
}
return impl;
}
public static LibVKXClientImpl getInstance(){
public static LibVKXClientImpl getInstance() {
LibVKXClientImpl libVKXClientImpl = impl;
return libVKXClientImpl == null ? getInstance(getContext()) : libVKXClientImpl;
return libVKXClientImpl == null ? getInstance(getGlobalContext()) : libVKXClientImpl;
}
public static boolean isVkxInstalled(){
public static boolean isVkxInstalled() {
try {
getContext().getPackageManager().getPackageInfo("ua.itaysonlab.vkx", 0);
getGlobalContext().getPackageManager().getPackageInfo("ua.itaysonlab.vkx", 0);
return true;
} catch (Exception unused) {
return false;
}
} // VKX check
public static boolean isIntegrationEnabled(){
public static boolean isIntegrationEnabled() {
return getBoolValue("libvkx_integration", false) && isVkxInstalled();
}
public static boolean play(MusicTrack musicTrack, List<MusicTrack> list, MusicPlaybackLaunchContext playerRefer){
public static boolean play(MusicTrack musicTrack, List<MusicTrack> list, MusicPlaybackLaunchContext playerRefer) {
if (!isIntegrationEnabled()) {
return false;
}
@@ -53,7 +54,7 @@ public class LibVKXClient{
return getInstance().runOnService(action);
}
public static void lambdaplay(List<MusicTrack> list, MusicTrack musicTrack, ILibVkxService iLibVkxService){
public static void lambdaplay(List<MusicTrack> list, MusicTrack musicTrack, ILibVkxService iLibVkxService) {
int indexOf = list.indexOf(musicTrack);
var ids = new ArrayList<String>();
for (var track : list) {
@@ -70,7 +71,7 @@ public class LibVKXClient{
}
}
private static String asId(MusicTrack musicTrack){
private static String asId(MusicTrack musicTrack) {
String str = musicTrack.e + "_" + musicTrack.d;
if (musicTrack.O == null || musicTrack.O.equals("")) {
return str;
@@ -1,6 +1,6 @@
package bruhcollective.itaysonlab.libvkx.client;
import static ru.vtosters.lite.utils.Globals.getUserId;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserId;
import android.content.ComponentName;
import android.content.Context;
@@ -15,7 +15,7 @@ import java.util.List;
import bruhcollective.itaysonlab.libvkx.ILibVkxService;
public class LibVKXClientImpl{
public class LibVKXClientImpl {
private ILibVkxService serviceInstance;
private PackageManager pm;
private Context ctx;
@@ -23,15 +23,15 @@ public class LibVKXClientImpl{
private boolean isBindFailed = false;
private LibVKXClientImpl(){
private LibVKXClientImpl() {
}
public LibVKXClientImpl(Context ctx){
public LibVKXClientImpl(Context ctx) {
this.ctx = ctx;
this.pm = ctx.getPackageManager();
}
public void finish(){
public void finish() {
if (cn != null) {
ctx.unbindService(cn);
}
@@ -39,7 +39,7 @@ public class LibVKXClientImpl{
serviceInstance = null;
}
public <T> T runOnServiceSync(LibVKXActionGeneric<T> action){
public <T> T runOnServiceSync(LibVKXActionGeneric<T> action) {
if (serviceInstance != null) {
return action.run(serviceInstance);
} else {
@@ -49,7 +49,7 @@ public class LibVKXClientImpl{
// true - action is ran
// false - action is failed, should fallback to default UI/UX
public boolean runOnService(LibVKXAction action){
public boolean runOnService(LibVKXAction action) {
if (serviceInstance != null) {
try {
if (serviceInstance.getUserId() != getUserId()) return false;
@@ -64,12 +64,12 @@ public class LibVKXClientImpl{
}
}
private boolean requestServiceInit(LibVKXAction runAfterBind){
private boolean requestServiceInit(LibVKXAction runAfterBind) {
if (!verifyBindActuality()) return false;
cn = new ServiceConnection(){
cn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service){
public void onServiceConnected(ComponentName name, IBinder service) {
serviceInstance = ILibVkxService.Stub.asInterface(service);
if (serviceInstance == null) {
// op mycopok...
@@ -85,7 +85,7 @@ public class LibVKXClientImpl{
}
@Override
public void onServiceDisconnected(ComponentName name){
public void onServiceDisconnected(ComponentName name) {
serviceInstance = null;
}
};
@@ -94,16 +94,16 @@ public class LibVKXClientImpl{
return true;
}
private boolean verifyBindActuality(){
private boolean verifyBindActuality() {
if (!checkIfAppExists()) return false; // no need
return !isBindFailed;
}
private Intent getIntent(){
private Intent getIntent() {
return new Intent(ClientConstants.ACTION).setPackage(ClientConstants.PACKAGE);
}
private boolean checkIfAppExists(){
private boolean checkIfAppExists() {
List<ResolveInfo> resolveInfos = pm.queryIntentServices(getIntent(), 0);
if (resolveInfos == null || resolveInfos.isEmpty()) return false;
@@ -114,14 +114,14 @@ public class LibVKXClientImpl{
return false;
}
public interface LibVKXAction{
public interface LibVKXAction {
void run(ILibVkxService service);
}
public interface LibVKXActionGeneric<T>{
public interface LibVKXActionGeneric<T> {
T run(ILibVkxService service);
default T defaultValue(){
default T defaultValue() {
return null;
}
}
@@ -3,35 +3,35 @@ package com.aefyr.tsg.g2;
/**
* Created by Aefyr on 19.05.2018.
*/
public abstract class CustomStickersEventsListener implements TelegramStickersService.StickersEventsListener{
public abstract class CustomStickersEventsListener implements TelegramStickersService.StickersEventsListener {
@Override
public void onPackAdded(TelegramStickersPack pack, int atIndex){
public void onPackAdded(TelegramStickersPack pack, int atIndex) {
}
@Override
public void onPackChanged(TelegramStickersPack pack, int atIndex){
public void onPackChanged(TelegramStickersPack pack, int atIndex) {
}
@Override
public void onPackRemoved(TelegramStickersPack pack, int atIndex){
public void onPackRemoved(TelegramStickersPack pack, int atIndex) {
}
@Override
public void onPackDownloadError(TelegramStickersPack pack, Exception error){
public void onPackDownloadError(TelegramStickersPack pack, Exception error) {
}
@Override
public void onActivePacksListChanged(){
public void onActivePacksListChanged() {
}
@Override
public void onInactivePacksListChanged(){
public void onInactivePacksListChanged() {
}
}
@@ -7,7 +7,7 @@ import java.io.File;
/**
* Created by Aefyr on 20.05.2018.
*/
public abstract class CustomStickersPack{
public abstract class CustomStickersPack {
public abstract File folder();
@@ -1,6 +1,6 @@
package com.aefyr.tsg.g2;
import static ru.vtosters.lite.utils.Globals.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -20,7 +20,7 @@ import java.util.concurrent.atomic.AtomicLong;
/**
* Created by Aefyr on 20.05.2018.
*/
public class NotificationsHelper{
public class NotificationsHelper {
private static final int NOTIFICATION_ID_BASE = 3921337;
private static final String NOTIFICATION_CHANNEL_ID = "tgss_chan_v5";
private static final int MAX_UPDATE_NOTIFICATIONS_PER_SECOND = 3;
@@ -31,7 +31,7 @@ public class NotificationsHelper{
private final AtomicLong lastNotificationTime = new AtomicLong(0);
private int currentNotificationN = 0;
public NotificationsHelper(Context c){
public NotificationsHelper(Context c) {
this.c = c;
manager = NotificationManagerCompat.from(c);
@@ -44,7 +44,7 @@ public class NotificationsHelper{
}
}
public void packStartedDownloading(TelegramStickersPack pack){
public void packStartedDownloading(TelegramStickersPack pack) {
int notificationId = NOTIFICATION_ID_BASE + currentNotificationN++;
downloadingPacksNotificationsIds.put(pack, notificationId);
@@ -56,7 +56,7 @@ public class NotificationsHelper{
manager.notify(notificationId, builder.build());
}
public void packDownloadUpdated(TelegramStickersPack pack, int downloadProgress){
public void packDownloadUpdated(TelegramStickersPack pack, int downloadProgress) {
if (System.currentTimeMillis() - lastNotificationTime.get() < MIN_TIME_BETWEEN_UPDATE_NOTIFICATIONS)
return;
@@ -73,7 +73,7 @@ public class NotificationsHelper{
manager.notify(downloadingPacksNotificationsIds.get(pack), builder.build());
}
public void packDoneDownloading(TelegramStickersPack pack, boolean success, boolean wasUpdate, @Nullable Exception e){
public void packDoneDownloading(TelegramStickersPack pack, boolean success, boolean wasUpdate, @Nullable Exception e) {
Notification.Builder builder = commonBuilder();
builder.setProgress(0, 0, false);
builder.setOngoing(false);
@@ -94,11 +94,11 @@ public class NotificationsHelper{
manager.notify(downloadingPacksNotificationsIds.remove(pack), builder.build());
}
public void removePackNotification(TelegramStickersPack pack){
public void removePackNotification(TelegramStickersPack pack) {
manager.cancel(downloadingPacksNotificationsIds.remove(pack));
}
private Notification.Builder commonBuilder(){
private Notification.Builder commonBuilder() {
var builder = new Notification.Builder(c).setPriority(Notification.PRIORITY_MAX).setSmallIcon(getIdentifier("ic_download_24", "drawable"));
if (oreo()) {
builder.setChannelId(NOTIFICATION_CHANNEL_ID);
@@ -107,7 +107,7 @@ public class NotificationsHelper{
return builder;
}
private boolean oreo(){
private boolean oreo() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
}
}
@@ -8,17 +8,17 @@ import java.io.File;
/**
* Created by Aefyr on 20.05.2018.
*/
class PackDeletionTask extends AsyncTask<Void, Void, Boolean>{
class PackDeletionTask extends AsyncTask<Void, Void, Boolean> {
private static final String TAG = "TGSSAnnihilator";
private final TelegramStickersPack pack;
PackDeletionTask(TelegramStickersPack pack){
PackDeletionTask(TelegramStickersPack pack) {
this.pack = pack;
}
@Override
protected Boolean doInBackground(Void... voids){
protected Boolean doInBackground(Void... voids) {
boolean success = true;
for (File f : pack.folder.listFiles()) {
@@ -31,7 +31,7 @@ class PackDeletionTask extends AsyncTask<Void, Void, Boolean>{
}
@Override
protected void onPostExecute(Boolean aBoolean){
protected void onPostExecute(Boolean aBoolean) {
Log.d(TAG, String.format("Attempted deleting pack %s, success?%s", pack.id, aBoolean));
}
}
@@ -17,7 +17,7 @@ import java.util.List;
/**
* Created by Aefyr on 18.05.2018.
*/
public class TelegramStickersPack extends CustomStickersPack{
public class TelegramStickersPack extends CustomStickersPack {
public static final int UNKNOWN = -1;
public static final int DOWNLOADED = 0;
@@ -35,12 +35,12 @@ public class TelegramStickersPack extends CustomStickersPack{
public HashMap<String, List<Integer>> emojis = new HashMap<>();
public TelegramStickersPack(String id){
public TelegramStickersPack(String id) {
this.id = id.toLowerCase();
title = id;
}
public JSONObject encodeEmojis() throws JSONException{
public JSONObject encodeEmojis() throws JSONException {
JSONObject obj = new JSONObject();
for (HashMap.Entry<String, List<Integer>> en : emojis.entrySet()) {
JSONArray arr = new JSONArray();
@@ -51,9 +51,9 @@ public class TelegramStickersPack extends CustomStickersPack{
return obj;
}
public void loadEmojis(JSONObject obj) throws JSONException{
public void loadEmojis(JSONObject obj) throws JSONException {
Iterator<String> it = obj.keys();
while(it.hasNext()) {
while (it.hasNext()) {
String key = it.next();
//emojis.put(key, obj.getInt(key));
List<Integer> list = emojis.get(key);
@@ -65,7 +65,7 @@ public class TelegramStickersPack extends CustomStickersPack{
}
}
public Bitmap getIcon(int targetMaxSideSize){
public Bitmap getIcon(int targetMaxSideSize) {
if (state != DOWNLOADED && state != UPDATING)
throw new IllegalStateException("Unable to get an icon of a pack that hasn't been downloaded yet");
@@ -74,7 +74,7 @@ public class TelegramStickersPack extends CustomStickersPack{
return getScaledBitmap(icon, targetMaxSideSize);
}
private Bitmap getScaledBitmap(File bitmapFile, int targetMaxSideSize){
private Bitmap getScaledBitmap(File bitmapFile, int targetMaxSideSize) {
BitmapFactory.Options op = new BitmapFactory.Options();
op.inJustDecodeBounds = true;
op.inPreferredConfig = Bitmap.Config.ARGB_8888;
@@ -100,46 +100,46 @@ public class TelegramStickersPack extends CustomStickersPack{
}
@Override
public boolean equals(Object obj){
public boolean equals(Object obj) {
return obj instanceof TelegramStickersPack && ((TelegramStickersPack) obj).id.equalsIgnoreCase(id);
}
@Override
public int hashCode(){
public int hashCode() {
return id.toLowerCase().hashCode();
}
@Override
public File folder(){
public File folder() {
return folder;
}
@Override
public int stickersCount(){
public int stickersCount() {
return stickersCount;
}
@Override
public String name(){
public String name() {
return title;
}
@Override
public Bitmap getIconBitmap(){
public Bitmap getIconBitmap() {
return getIcon(128);
}
@Override
public Bitmap getStickerBitmap(int index){
public Bitmap getStickerBitmap(int index) {
return BitmapFactory.decodeFile(new File(folder, String.format("%03d.png", index + 1)).getAbsolutePath());
}
@Override
public File getStickerFile(int index){
public File getStickerFile(int index) {
return new File(folder, String.format("%03d.png", index + 1));
}
public Bitmap getStickerBitmap(int index, int maxSize){
public Bitmap getStickerBitmap(int index, int maxSize) {
return getScaledBitmap(new File(folder, String.format("%03d.png", index + 1)), maxSize);
}
}
@@ -1,6 +1,6 @@
package com.aefyr.tsg.g2;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import android.content.Context;
import android.content.Intent;
@@ -24,7 +24,7 @@ import ru.vtosters.lite.ui.fragments.tgstickers.StickersFragment;
/**
* Created by Aefyr on 19.05.2018.
*/
public class TelegramStickersService{
public class TelegramStickersService {
private static final String TAG = "TGStickersService";
private static TelegramStickersService instance;
@@ -46,7 +46,7 @@ public class TelegramStickersService{
private final NotificationsHelper notificationsHelper;
private boolean ready = false;
private TelegramStickersService(Context context){
private TelegramStickersService(Context context) {
instance = this;
this.c = context.getApplicationContext();
@@ -67,15 +67,15 @@ public class TelegramStickersService{
updatePacks(true);
}
public static TelegramStickersService getInstance(Context c){
public static TelegramStickersService getInstance(Context c) {
return instance == null ? new TelegramStickersService(c) : instance;
}
private void updatePacks(final boolean notify){
private void updatePacks(final boolean notify) {
packs.clear();
dbHelper.getAllPacks(new TelegramStickersDbHelper.PacksLoadingListener(){
dbHelper.getAllPacks(new TelegramStickersDbHelper.PacksLoadingListener() {
@Override
public void onPackLoaded(final TelegramStickersPack pack){
public void onPackLoaded(final TelegramStickersPack pack) {
runOnUiThread(() -> {
packs.add(pack);
@@ -89,7 +89,7 @@ public class TelegramStickersService{
}
@Override
public void onAllPacksLoaded(ArrayList<TelegramStickersPack> packs){
public void onAllPacksLoaded(ArrayList<TelegramStickersPack> packs) {
ready = true;
if (notify) {
@@ -98,22 +98,22 @@ public class TelegramStickersService{
}
Log.d(TAG, String.format("Packs list loaded, running %d queued tasks...", queuedTasks.size()));
while(!queuedTasks.isEmpty())
while (!queuedTasks.isEmpty())
queuedTasks.remove(0).run();
}
});
}
public void addStickersEventsListener(StickersEventsListener listener){
public void addStickersEventsListener(StickersEventsListener listener) {
listeners.add(listener);
}
public void removeStickersEventsListener(StickersEventsListener listener){
public void removeStickersEventsListener(StickersEventsListener listener) {
listeners.remove(listener);
}
private void notifyPackAdded(TelegramStickersPack pack, int atIndex){
getContext().sendBroadcast(new Intent(StickersFragment.ACTION_RELOAD));
private void notifyPackAdded(TelegramStickersPack pack, int atIndex) {
getGlobalContext().sendBroadcast(new Intent(StickersFragment.ACTION_RELOAD));
if (listeners.isEmpty())
return;
@@ -122,8 +122,8 @@ public class TelegramStickersService{
}
}
private void notifyPackChanged(TelegramStickersPack pack, int atIndex){
getContext().sendBroadcast(new Intent(StickersFragment.ACTION_RELOAD));
private void notifyPackChanged(TelegramStickersPack pack, int atIndex) {
getGlobalContext().sendBroadcast(new Intent(StickersFragment.ACTION_RELOAD));
if (listeners.isEmpty())
return;
@@ -132,8 +132,8 @@ public class TelegramStickersService{
}
}
private void notifyPackRemoved(TelegramStickersPack pack, int atIndex){
getContext().sendBroadcast(new Intent(StickersFragment.ACTION_RELOAD));
private void notifyPackRemoved(TelegramStickersPack pack, int atIndex) {
getGlobalContext().sendBroadcast(new Intent(StickersFragment.ACTION_RELOAD));
if (listeners.isEmpty())
return;
@@ -142,8 +142,8 @@ public class TelegramStickersService{
}
}
private void notifyPackDownloadError(TelegramStickersPack pack, Exception error){
getContext().sendBroadcast(new Intent(StickersFragment.ACTION_RELOAD));
private void notifyPackDownloadError(TelegramStickersPack pack, Exception error) {
getGlobalContext().sendBroadcast(new Intent(StickersFragment.ACTION_RELOAD));
if (listeners.isEmpty())
return;
@@ -152,8 +152,8 @@ public class TelegramStickersService{
}
}
private void notifyActivePacksListChanged(){
getContext().sendBroadcast(new Intent(StickersFragment.ACTION_RELOAD));
private void notifyActivePacksListChanged() {
getGlobalContext().sendBroadcast(new Intent(StickersFragment.ACTION_RELOAD));
if (listeners.isEmpty())
return;
@@ -162,8 +162,8 @@ public class TelegramStickersService{
}
}
private void notifyInactivePacksListChanged(){
getContext().sendBroadcast(new Intent(StickersFragment.ACTION_RELOAD));
private void notifyInactivePacksListChanged() {
getGlobalContext().sendBroadcast(new Intent(StickersFragment.ACTION_RELOAD));
if (listeners.isEmpty())
return;
@@ -172,27 +172,27 @@ public class TelegramStickersService{
}
}
public void setBotKey(String botKey){
public void setBotKey(String botKey) {
grabber.setBotApiKey(botKey);
}
public ArrayList<TelegramStickersPack> getPacksListReference(){
public ArrayList<TelegramStickersPack> getPacksListReference() {
return packs;
}
public ArrayList<TelegramStickersPack> getActivePacksListReference(){
public ArrayList<TelegramStickersPack> getActivePacksListReference() {
return activePacks;
}
public ArrayList<TelegramStickersPack> getInactivePacksListReference(){
public ArrayList<TelegramStickersPack> getInactivePacksListReference() {
return inactivePacks;
}
public boolean isDoneLoading(){
public boolean isDoneLoading() {
return ready;
}
public boolean requestPackDownload(final String id, File packFolder){
public boolean requestPackDownload(final 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;
@@ -228,9 +228,9 @@ public class TelegramStickersService{
notificationsHelper.packStartedDownloading(newPack);
grabber.enableProxy();
grabber.grabPack(id, packFolder, pack.version, new TelegramStickersGrabber.PackDownloadListener(){
grabber.grabPack(id, packFolder, pack.version, new TelegramStickersGrabber.PackDownloadListener() {
@Override
public void onPackDownloaded(TelegramStickersPackInfo packInfo, boolean newVersionFound){
public void onPackDownloaded(TelegramStickersPackInfo packInfo, boolean newVersionFound) {
runOnUiThread(() -> {
newPack.state = TelegramStickersPack.DOWNLOADED;
@@ -250,7 +250,7 @@ public class TelegramStickersService{
}
@Override
public void onPackDownloadError(final Exception e){
public void onPackDownloadError(final Exception e) {
runOnUiThread(() -> {
Log.e(TAG, "Error while downloading pack " + newPack.id);
e.printStackTrace();
@@ -271,7 +271,7 @@ public class TelegramStickersService{
}
@Override
public void onGotPackInfo(final TelegramStickersPackInfo packInfo){
public void onGotPackInfo(final TelegramStickersPackInfo packInfo) {
runOnUiThread(() -> {
newPack.title = packInfo.title;
newPack.stickersCount = packInfo.stickersCount;
@@ -283,7 +283,7 @@ public class TelegramStickersService{
}
@Override
public void onStickerDownloaded(String pack, File sticker, String boundEmoji, int stickerIndex, int downloadedStickersCount, int totalStickersCount){
public void onStickerDownloaded(String pack, File sticker, String boundEmoji, int stickerIndex, int downloadedStickersCount, int totalStickersCount) {
stickerIndex--;
List<Integer> list = newPack.emojis.get(boundEmoji);
@@ -298,7 +298,7 @@ public class TelegramStickersService{
return true;
}
public void setPackEnabled(final TelegramStickersPack pack, final boolean enabled, final boolean notify){
public void setPackEnabled(final TelegramStickersPack pack, final boolean enabled, final boolean notify) {
if (!ready) {
queuedTasks.add(() -> setPackEnabled(pack, enabled, notify));
return;
@@ -324,7 +324,7 @@ public class TelegramStickersService{
}
}
public void deletePack(final TelegramStickersPack pack){
public void deletePack(final TelegramStickersPack pack) {
if (!ready) {
queuedTasks.add(() -> deletePack(pack));
return;
@@ -350,11 +350,11 @@ public class TelegramStickersService{
new PackDeletionTask(pack).executeOnExecutor(executor);
}
private void runOnUiThread(Runnable r){
private void runOnUiThread(Runnable r) {
uiThreadHandler.post(r);
}
private void syncPack(final TelegramStickersPack pack){
private void syncPack(final TelegramStickersPack pack) {
if (!ready) {
queuedTasks.add(() -> syncPack(pack));
return;
@@ -363,7 +363,7 @@ public class TelegramStickersService{
Log.d(TAG, "Sync=" + dbHelper.syncPack(pack));
}
public void swap(TelegramStickersPack p1, TelegramStickersPack p2){
public void swap(TelegramStickersPack p1, TelegramStickersPack p2) {
int i1 = p1.index;
int i2 = p2.index;
p1.index = i2;
@@ -383,7 +383,7 @@ public class TelegramStickersService{
getPacksListReference().set(li1, p2);
}
interface StickersEventsListener{
interface StickersEventsListener {
void onPackAdded(TelegramStickersPack pack, int atIndex);
void onPackRemoved(TelegramStickersPack pack, int atIndex);
@@ -5,16 +5,16 @@ import android.provider.BaseColumns;
/**
* Created by Aefyr on 19.05.2018.
*/
public final class TelegramStickersContract{
public final class TelegramStickersContract {
public static final String SQL_CREATE_ENTRIES = String.format("CREATE TABLE %s (%s INTEGER PRIMARY KEY, %s INTEGER AUTO_INCREMENT, %s TEXT, %s TEXT, %s TEXT, %s INTEGER, %s INTEGER, %s TEXT, %s TEXT)",
StickersTableEntry.TABLE_NAME, StickersTableEntry._ID, StickersTableEntry.COLUMN_NAME_INDEX, StickersTableEntry.COLUMN_NAME_ID, StickersTableEntry.COLUMN_NAME_NAME,
StickersTableEntry.COLUMN_NAME_FOLDER, StickersTableEntry.COLUMN_NAME_STICKERS_COUNT, StickersTableEntry.COLUMN_NAME_ENABLED, StickersTableEntry.COLUMN_NAME_VERSION, StickersTableEntry.COLUMN_NAME_EMOJIS);
private TelegramStickersContract(){
private TelegramStickersContract() {
}
public static class StickersTableEntry implements BaseColumns{
public static class StickersTableEntry implements BaseColumns {
public static final String TABLE_NAME = "packs";
public static final String COLUMN_NAME_ID = "id";
@@ -20,35 +20,35 @@ import java.util.ArrayList;
/**
* Created by Aefyr on 19.05.2018.
*/
public class TelegramStickersDbHelper extends SQLiteOpenHelper{
public class TelegramStickersDbHelper extends SQLiteOpenHelper {
private static final int DB_VERSION = 2;
private static final String DB_NAME = "TelegramStickers.db";
private SQLiteDatabase writableDb;
private SQLiteDatabase readableDb;
public TelegramStickersDbHelper(Context context){
public TelegramStickersDbHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db){
public void onCreate(SQLiteDatabase db) {
db.execSQL(TelegramStickersContract.SQL_CREATE_ENTRIES);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion == 1 && newVersion == 2) {
db.execSQL(String.format("ALTER TABLE %s ADD COLUMN %s TEXT", TelegramStickersContract.StickersTableEntry.TABLE_NAME, TelegramStickersContract.StickersTableEntry.COLUMN_NAME_EMOJIS));
}
}
public void loadDatabases(){
public void loadDatabases() {
writableDb = getWritableDatabase();
readableDb = getReadableDatabase();
}
public boolean syncPack(TelegramStickersPack pack){
public boolean syncPack(TelegramStickersPack pack) {
ContentValues sqlPack = new ContentValues();
sqlPack.put(TelegramStickersContract.StickersTableEntry.COLUMN_NAME_ID, pack.id);
sqlPack.put(TelegramStickersContract.StickersTableEntry.COLUMN_NAME_NAME, pack.title);
@@ -77,7 +77,7 @@ public class TelegramStickersDbHelper extends SQLiteOpenHelper{
return true;
}
private int getNewIndex(){
private int getNewIndex() {
Cursor c = readableDb.rawQuery("SELECT MAX(" + TelegramStickersContract.StickersTableEntry.COLUMN_NAME_INDEX + ") FROM " + TelegramStickersContract.StickersTableEntry.TABLE_NAME, new String[0]);
c.moveToLast();
int max;
@@ -91,30 +91,30 @@ public class TelegramStickersDbHelper extends SQLiteOpenHelper{
return max + 1;
}
public boolean deletePack(TelegramStickersPack pack){
public boolean deletePack(TelegramStickersPack pack) {
return writableDb.delete(TelegramStickersContract.StickersTableEntry.TABLE_NAME, TelegramStickersContract.StickersTableEntry.COLUMN_NAME_ID + "='" + pack.id + "'", null) == 1;
}
public void getAllPacks(PacksLoadingListener listener){
public void getAllPacks(PacksLoadingListener listener) {
new PacksLoadingTask(listener).execute();
}
public interface PacksLoadingListener{
public interface PacksLoadingListener {
void onPackLoaded(TelegramStickersPack pack);
void onAllPacksLoaded(ArrayList<TelegramStickersPack> packs);
}
private class PacksLoadingTask extends AsyncTask<Void, Void, ArrayList<TelegramStickersPack>>{
private class PacksLoadingTask extends AsyncTask<Void, Void, ArrayList<TelegramStickersPack>> {
PacksLoadingListener listener;
PacksLoadingTask(PacksLoadingListener listener){
PacksLoadingTask(PacksLoadingListener listener) {
this.listener = listener;
}
@Override
protected ArrayList<TelegramStickersPack> doInBackground(Void... voids){
protected ArrayList<TelegramStickersPack> doInBackground(Void... voids) {
if (readableDb == null)
loadDatabases();
@@ -125,7 +125,7 @@ public class TelegramStickersDbHelper extends SQLiteOpenHelper{
ArrayList<TelegramStickersPack> packs = new ArrayList<>(cursor.getCount() + 8);
while(cursor.moveToNext()) {
while (cursor.moveToNext()) {
Log.d("DB", "PACK LOADED");
String id = cursor.getString(cursor.getColumnIndexOrThrow(TelegramStickersContract.StickersTableEntry.COLUMN_NAME_ID));
String name = cursor.getString(cursor.getColumnIndexOrThrow(TelegramStickersContract.StickersTableEntry.COLUMN_NAME_NAME));
@@ -160,7 +160,7 @@ public class TelegramStickersDbHelper extends SQLiteOpenHelper{
}
@Override
protected void onPostExecute(ArrayList<TelegramStickersPack> packs){
protected void onPostExecute(ArrayList<TelegramStickersPack> packs) {
listener.onAllPacksLoaded(packs);
}
}
@@ -36,7 +36,7 @@ import ru.vtosters.lite.net.NetResponse;
/**
* Created by Aefyr on 11.05.2018.
*/
public class TelegramStickersGrabber{
public class TelegramStickersGrabber {
private static final String TAG = "TSG";
public static String REAL_TG_IP = null;
public static String PROXY_IP = null;
@@ -51,7 +51,7 @@ public class TelegramStickersGrabber{
private static String GET_FILE_URL;
private static String BOT_API_BASE_FILE_URL;
static{
static {
updateURLs();
}
@@ -60,7 +60,7 @@ public class TelegramStickersGrabber{
private String botApiKey = "";
private NetClient httpClient;
public TelegramStickersGrabber(String botApiKey){
public TelegramStickersGrabber(String botApiKey) {
this.botApiKey = botApiKey;
httpClient = new NetClient.Builder().connectTimeout(5, TimeUnit.SECONDS).build();
uiThreadHandler = new Handler(Looper.getMainLooper());
@@ -73,7 +73,7 @@ public class TelegramStickersGrabber{
}
}
public static void updateURLs(){
public static void updateURLs() {
BOT_API_BASE_FILE_URL = "https://api.telegram.org/file/bot%s/%s";
@@ -82,7 +82,7 @@ public class TelegramStickersGrabber{
GET_FILE_URL = BOT_API_BASE_URL + "getFile?file_id=%s";
}
public static boolean isTelegramBlocked(){
public static boolean isTelegramBlocked() {
NetClient client = new NetClient.Builder().connectTimeout(5, TimeUnit.SECONDS).build();
try {
if (PROXY_IP != null) {
@@ -112,14 +112,14 @@ public class TelegramStickersGrabber{
return false;
}
public void resetProxy(){
public void resetProxy() {
httpClient = new NetClient.Builder().connectTimeout(5, TimeUnit.SECONDS).build();
}
public void enableProxy(){
Thread kostil = new Thread(){
public void enableProxy() {
Thread kostil = new Thread() {
@Override
public void run(){
public void run() {
try {
if (PROXY_IP != null) {
Socket socket = new Socket(PROXY_IP, PROXY_PORT);
@@ -150,41 +150,41 @@ public class TelegramStickersGrabber{
}
}
public void grabPack(String id, File packFolder, String installedVersion, final PackDownloadListener listener){
public void grabPack(String id, File packFolder, String installedVersion, final PackDownloadListener listener) {
getPackInfo(id, packFolder, installedVersion, listener);
}
public void setBotApiKey(String key){
public void setBotApiKey(String key) {
botApiKey = key;
}
public void checkKey(final KeyCheckListener listener){
public void checkKey(final 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(){
httpClient.newCall(request).enqueue(new NetCallback() {
@Override
public void onFailure(NetCall call, IOException e){
public void onFailure(NetCall call, IOException e) {
e.printStackTrace();
runOnUiThread(listener::onNetError);
}
@Override
public void onResponse(NetCall call, final NetResponse response) throws IOException{
public void onResponse(NetCall call, final NetResponse response) throws IOException {
runOnUiThread(() -> listener.onKeyChecked(response.code() == 200));
}
});
}
private void getPackInfo(final String packName, final File packFolder, final String installedVersion, final PackDownloadListener listener){
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(){
httpClient.newCall(packInfoRequest).enqueue(new NetCallback() {
@Override
public void onFailure(NetCall call, IOException e){
public void onFailure(NetCall call, IOException e) {
listener.onPackDownloadError(e);
}
@Override
public void onResponse(NetCall call, NetResponse response) throws IOException{
public void onResponse(NetCall call, NetResponse response) throws IOException {
if (!response.isSuccessful()) {
if (response.getData() != null)
listener.onPackDownloadError(new TSGException(response.getDataString() + "\nURL: " + call.request().url()));
@@ -246,7 +246,7 @@ public class TelegramStickersGrabber{
});
}
private void getPack(final StickerSet set, final File packFolder, final TelegramStickersPackInfo packInfo, final PackDownloadListener 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()));
@@ -262,9 +262,9 @@ public class TelegramStickersGrabber{
final int stickerIndex = i + 1;
AtomicBoolean sync = new AtomicBoolean();
httpClient.newCall(fileInfoRequest).enqueue(new NetCallback(){
httpClient.newCall(fileInfoRequest).enqueue(new NetCallback() {
@Override
public void onFailure(NetCall call, IOException e){
public void onFailure(NetCall call, IOException e) {
if (deathFlag.up())
return;
@@ -275,7 +275,7 @@ public class TelegramStickersGrabber{
}
@Override
public void onResponse(NetCall call, NetResponse response) throws IOException{
public void onResponse(NetCall call, NetResponse response) throws IOException {
if (deathFlag.up())
return;
@@ -305,9 +305,9 @@ public class TelegramStickersGrabber{
NetRequest fileDownloadRequest = new NetRequest.Builder().get().url(String.format(BOT_API_BASE_FILE_URL, botApiKey, filePath)).build();
httpClient.newCall(fileDownloadRequest).enqueue(new NetCallback(){
httpClient.newCall(fileDownloadRequest).enqueue(new NetCallback() {
@Override
public void onFailure(NetCall call, IOException e){
public void onFailure(NetCall call, IOException e) {
if (deathFlag.up())
return;
@@ -318,7 +318,7 @@ public class TelegramStickersGrabber{
}
@Override
public void onResponse(NetCall call, NetResponse response) throws IOException{
public void onResponse(NetCall call, NetResponse response) throws IOException {
if (deathFlag.up())
return;
@@ -407,7 +407,7 @@ public class TelegramStickersGrabber{
}
});
while(!sync.get())
while (!sync.get())
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
@@ -415,11 +415,11 @@ public class TelegramStickersGrabber{
}
}
private void runOnUiThread(Runnable r){
private void runOnUiThread(Runnable r) {
uiThreadHandler.post(r);
}
public interface PackDownloadListener{
public interface PackDownloadListener {
void onPackDownloaded(TelegramStickersPackInfo pack, boolean newVersionFound);
void onPackDownloadError(Exception e);
@@ -429,27 +429,27 @@ public class TelegramStickersGrabber{
void onStickerDownloaded(String pack, File sticker, String boundEmoji, int stickerIndex, int downloadedStickersCount, int totalStickerCount);
}
public interface KeyCheckListener{
public interface KeyCheckListener {
void onKeyChecked(boolean ok);
void onNetError();
}
public class TSGException extends Exception{
public class TSGException extends Exception {
private static final long serialVersionUID = 7866915509988422944L;
private TSGException(String message){
private TSGException(String message) {
super(message);
}
}
private class StickerSet{
private class StickerSet {
String id;
String name;
String version;
ArrayList<Sticker> stickers;
StickerSet(String id, String name, String version, ArrayList<Sticker> stickers){
StickerSet(String id, String name, String version, ArrayList<Sticker> stickers) {
this.name = name;
this.stickers = stickers;
this.id = id;
@@ -457,22 +457,22 @@ public class TelegramStickersGrabber{
}
}
private class Sticker{
private class Sticker {
String emoji;
String fileId;
Sticker(String fileId, String emoji){
Sticker(String fileId, String emoji) {
this.fileId = fileId;
this.emoji = emoji;
}
@Override
public boolean equals(Object obj){
public boolean equals(Object obj) {
return obj instanceof Sticker && ((Sticker) obj).fileId.equals(fileId);
}
@Override
public int hashCode(){
public int hashCode() {
return (17 * emoji.hashCode()) << 32 + fileId.hashCode();
}
}
@@ -3,13 +3,13 @@ package com.aefyr.tsg.g2.stickersgrabber;
/**
* Created by Aefyr on 22.05.2018.
*/
public class TelegramStickersPackInfo{
public class TelegramStickersPackInfo {
public String id;
public String title;
public String version;
public int stickersCount;
TelegramStickersPackInfo(String id, String title, int stickersCount, String version){
TelegramStickersPackInfo(String id, String title, int stickersCount, String version) {
this.id = id;
this.title = title;
this.version = version;
@@ -3,18 +3,18 @@ package com.aefyr.tsg.g2.stickersgrabber.util;
/**
* Created by Aefyr on 11.05.2018.
*/
public class Flag{
public class Flag {
private boolean up = false;
public synchronized boolean up(){
public synchronized boolean up() {
return up;
}
public synchronized void raise(){
public synchronized void raise() {
up = true;
}
public synchronized void lower(){
public synchronized void lower() {
up = false;
}
}
@@ -5,34 +5,34 @@ import android.util.Log;
/**
* Created by Aefyr on 11.05.2018.
*/
public class GoalCounter{
public class GoalCounter {
private final int goal;
private final OnGoalReachListener listener;
private int i = 0;
public GoalCounter(int goal, OnGoalReachListener listener){
public GoalCounter(int goal, OnGoalReachListener listener) {
this.goal = goal;
this.listener = listener;
}
public synchronized void increase(){
public synchronized void increase() {
if (++i == goal)
listener.onGoalReached();
Log.d("COUNTER", "G=" + goal + ", I=" + i);
}
public synchronized void increase(int delta){
public synchronized void increase(int delta) {
if ((i += delta) == goal)
listener.onGoalReached();
}
public synchronized int value(){
public synchronized int value() {
return i;
}
public interface OnGoalReachListener{
public interface OnGoalReachListener {
void onGoalReached();
}
}
@@ -8,60 +8,60 @@ import com.arthenica.smartexception.java.Exceptions;
import java.util.Collections;
import java.util.List;
import ru.vtosters.lite.utils.Globals;
import ru.vtosters.lite.utils.AndroidUtils;
public class NativeLoader{
public class NativeLoader {
static final String[] FFMPEG_LIBRARIES = {"avutil", "swscale", "swresample", "avcodec", "avformat", "avfilter", "avdevice"};
private static void loadLibrary(String libraryName){
String path = Globals.getContext().getFilesDir() + "/lib" + libraryName + ".so";
private static void loadLibrary(String libraryName) {
String path = AndroidUtils.getGlobalContext().getFilesDir() + "/lib" + libraryName + ".so";
System.load(path);
}
private static List<String> loadExternalLibraries(){
private static List<String> loadExternalLibraries() {
// return Packages.getExternalLibraries();
return Collections.emptyList();
}
private static String loadNativeAbi(){
private static String loadNativeAbi() {
// return AbiDetect.getNativeAbi();
return Abi.ABI_ARMV7A_NEON.getName();
}
static String loadAbi(){
static String loadAbi() {
// return AbiDetect.getAbi();
return Abi.ABI_ARMV7A_NEON.getName();
}
static String loadPackageName(){
static String loadPackageName() {
return Packages.getPackageName();
}
static String loadVersion(){
static String loadVersion() {
return FFmpegKitConfig.getVersion();
}
static boolean loadIsLTSBuild(){
static boolean loadIsLTSBuild() {
return AbiDetect.isNativeLTSBuild();
}
static int loadLogLevel(){
static int loadLogLevel() {
return FFmpegKitConfig.getNativeLogLevel();
}
static String loadBuildDate(){
static String loadBuildDate() {
return FFmpegKitConfig.getBuildDate();
}
static void enableRedirection(){
static void enableRedirection() {
FFmpegKitConfig.enableRedirection();
}
static void loadFFmpegKitAbiDetect(){
static void loadFFmpegKitAbiDetect() {
loadLibrary("ffmpegkit_abidetect");
}
static boolean loadFFmpeg(){
static boolean loadFFmpeg() {
boolean nativeFFmpegLoaded = false;
boolean nativeFFmpegTriedAndFailed = false;
@@ -85,7 +85,7 @@ public class NativeLoader{
return nativeFFmpegTriedAndFailed;
}
static void loadFFmpegKit(boolean nativeFFmpegTriedAndFailed){
static void loadFFmpegKit(boolean nativeFFmpegTriedAndFailed) {
boolean nativeFFmpegKitLoaded = false;
if (!nativeFFmpegTriedAndFailed && "arm-v7a".equals(loadNativeAbi())) {
try {
@@ -102,7 +102,7 @@ public class NativeLoader{
}
static String getDeviceDebugInformation(){
static String getDeviceDebugInformation() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("brand: ");
stringBuilder.append(Build.BRAND);
@@ -43,7 +43,7 @@ import java.util.Set;
* @author Taner Sener
* @since 0.1.0
*/
public abstract class AbstractExceptions{
public abstract class AbstractExceptions {
/**
* <p>Default max depth used in methods which do not have a maxDepth argument.
@@ -90,14 +90,14 @@ public abstract class AbstractExceptions{
*
* @param packageString root package name to register
*/
public static void registerRootPackage(final String packageString){
public static void registerRootPackage(final String packageString) {
rootPackageSet.add(packageString);
}
/**
* <p>Clears previously registered root packages.
*/
public static void clearRootPackages(){
public static void clearRootPackages() {
rootPackageSet.clear();
}
@@ -106,14 +106,14 @@ public abstract class AbstractExceptions{
*
* @param packageString group package name to register
*/
public static void registerGroupPackage(final String packageString){
public static void registerGroupPackage(final String packageString) {
groupPackageSet.add(packageString);
}
/**
* <p>Clears previously registered group packages.
*/
public static void clearGroupPackages(){
public static void clearGroupPackages() {
groupPackageSet.clear();
}
@@ -123,7 +123,7 @@ public abstract class AbstractExceptions{
*
* @return current stack trace serializer implementation
*/
public static StackTraceElementSerializer getStackTraceElementSerializer(){
public static StackTraceElementSerializer getStackTraceElementSerializer() {
return stackTraceElementSerializer;
}
@@ -133,7 +133,7 @@ public abstract class AbstractExceptions{
*
* @param stackTraceElementSerializer new stack trace serializer implementation
*/
public static void setStackTraceElementSerializer(final StackTraceElementSerializer stackTraceElementSerializer){
public static void setStackTraceElementSerializer(final StackTraceElementSerializer stackTraceElementSerializer) {
AbstractExceptions.stackTraceElementSerializer = stackTraceElementSerializer;
}
@@ -143,7 +143,7 @@ public abstract class AbstractExceptions{
* @param packageString ignore package name to register
* @param ignoreCauseClasses ignore cause classes from this package too
*/
public static void registerIgnorePackage(final String packageString, final boolean ignoreCauseClasses){
public static void registerIgnorePackage(final String packageString, final boolean ignoreCauseClasses) {
ignorePackageSet.add(packageString);
if (ignoreCauseClasses) {
ignoreCausePackageSet.add(packageString);
@@ -153,7 +153,7 @@ public abstract class AbstractExceptions{
/**
* <p>Clears previously registered ignore packages.
*/
public static void clearIgnorePackages(){
public static void clearIgnorePackages() {
ignorePackageSet.clear();
ignoreCausePackageSet.clear();
}
@@ -165,7 +165,7 @@ public abstract class AbstractExceptions{
* converted to string will not include causes. If value is false causes will be appended to the stack trace of
* the main throwable.
*/
public static boolean getIgnoreAllCauses(){
public static boolean getIgnoreAllCauses() {
return ignoreAllCauses;
}
@@ -176,7 +176,7 @@ public abstract class AbstractExceptions{
* or converted to string will not include causes. If value is false causes will be appended to the stack trace of
* the main throwable.
*/
public static void setIgnoreAllCauses(final boolean ignoreAllCauses){
public static void setIgnoreAllCauses(final boolean ignoreAllCauses) {
AbstractExceptions.ignoreAllCauses = ignoreAllCauses;
}
@@ -190,7 +190,7 @@ public abstract class AbstractExceptions{
* @param throwable parent throwable
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable){
public static String getStackTraceString(final Throwable throwable) {
return getStackTraceString(throwable, false, rootPackageSet, groupPackageSet, ignorePackageSet, 0, ignoreAllCauses);
}
@@ -205,7 +205,7 @@ public abstract class AbstractExceptions{
* @param ignoreAllCauses ignore all causes in the exception chain
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable, final boolean ignoreAllCauses){
public static String getStackTraceString(final Throwable throwable, final boolean ignoreAllCauses) {
return getStackTraceString(throwable, false, rootPackageSet, groupPackageSet, ignorePackageSet, 0, ignoreAllCauses);
}
@@ -218,7 +218,7 @@ public abstract class AbstractExceptions{
* @param ignorePackageSet ignore packages to use for building the stack trace
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable, final Set<String> rootPackageSet, final Set<String> groupPackageSet, final Set<String> ignorePackageSet){
public static String getStackTraceString(final Throwable throwable, final Set<String> rootPackageSet, final Set<String> groupPackageSet, final Set<String> ignorePackageSet) {
return getStackTraceString(throwable, false, rootPackageSet, groupPackageSet, ignorePackageSet, 0, ignoreAllCauses);
}
@@ -232,7 +232,7 @@ public abstract class AbstractExceptions{
* @param ignoreAllCauses ignore all causes in the exception chain
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable, final Set<String> rootPackageSet, final Set<String> groupPackageSet, final Set<String> ignorePackageSet, final boolean ignoreAllCauses){
public static String getStackTraceString(final Throwable throwable, final Set<String> rootPackageSet, final Set<String> groupPackageSet, final Set<String> ignorePackageSet, final boolean ignoreAllCauses) {
return getStackTraceString(throwable, false, rootPackageSet, groupPackageSet, ignorePackageSet, 0, ignoreAllCauses);
}
@@ -243,7 +243,7 @@ public abstract class AbstractExceptions{
* @param rootPackage root package to use for building the stack trace
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable, final String rootPackage){
public static String getStackTraceString(final Throwable throwable, final String rootPackage) {
return getStackTraceString(throwable, false, Collections.singleton(rootPackage), new HashSet<String>(), new HashSet<String>(), 0, ignoreAllCauses);
}
@@ -255,7 +255,7 @@ public abstract class AbstractExceptions{
* @param groupPackage group package to use for building the stack trace
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable, final String rootPackage, final String groupPackage){
public static String getStackTraceString(final Throwable throwable, final String rootPackage, final String groupPackage) {
return getStackTraceString(throwable, false, Collections.singleton(rootPackage), Collections.singleton(groupPackage), new HashSet<String>(), 0, ignoreAllCauses);
}
@@ -266,7 +266,7 @@ public abstract class AbstractExceptions{
* @param maxDepth max depth in exception chain that will be used
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable, final int maxDepth){
public static String getStackTraceString(final Throwable throwable, final int maxDepth) {
return getStackTraceString(throwable, false, new HashSet<String>(), new HashSet<String>(), new HashSet<String>(), maxDepth, ignoreAllCauses);
}
@@ -278,7 +278,7 @@ public abstract class AbstractExceptions{
* @param ignoreAllCauses ignore all causes in the exception chain
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable, final int maxDepth, final boolean ignoreAllCauses){
public static String getStackTraceString(final Throwable throwable, final int maxDepth, final boolean ignoreAllCauses) {
return getStackTraceString(throwable, false, new HashSet<String>(), new HashSet<String>(), new HashSet<String>(), maxDepth, ignoreAllCauses);
}
@@ -294,7 +294,7 @@ public abstract class AbstractExceptions{
* @param ignoreAllCauses ignore all causes in the exception chain
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable, final boolean isCause, final Set<String> rootPackageSet, final Set<String> groupPackageSet, final Set<String> ignorePackageSet, final int maxDepth, final boolean ignoreAllCauses){
public static String getStackTraceString(final Throwable throwable, final boolean isCause, final Set<String> rootPackageSet, final Set<String> groupPackageSet, final Set<String> ignorePackageSet, final int maxDepth, final boolean ignoreAllCauses) {
final StringBuilder builder = new StringBuilder();
if (throwable == null) {
@@ -386,7 +386,7 @@ public abstract class AbstractExceptions{
* @param firstStackTraceElementInTheGroup first stack trace element of this group
* @return new value for the group element count
*/
public static int appendStackTraceGroupElement(final StringBuilder stringBuilder, final String currentGroupPackage, final int numberOfElementsInTheCurrentGroup, final StackTraceElement firstStackTraceElementInTheGroup){
public static int appendStackTraceGroupElement(final StringBuilder stringBuilder, final String currentGroupPackage, final int numberOfElementsInTheCurrentGroup, final StackTraceElement firstStackTraceElementInTheGroup) {
if (numberOfElementsInTheCurrentGroup > 0) {
if (stackTraceElementSerializer == null) {
throw new IllegalArgumentException("Stack trace element serializer not initialized.");
@@ -407,7 +407,7 @@ public abstract class AbstractExceptions{
* @return true if package of the given class name matches one of package names provided in <code>packageSet</code>,
* false otherwise
*/
public static boolean containsPackage(final String fullClassName, final Set<String> packageSet){
public static boolean containsPackage(final String fullClassName, final Set<String> packageSet) {
return getContainingPackage(fullClassName, packageSet) != null;
}
@@ -420,7 +420,7 @@ public abstract class AbstractExceptions{
* @return one of the package names in the <code>packageSet</code> that matches the package of the given class name
* or null if no matching package name is found in the <code>packageSet</code>
*/
public static String getContainingPackage(final String fullClassName, final Set<String> packageSet){
public static String getContainingPackage(final String fullClassName, final Set<String> packageSet) {
for (final String parentExceptionPackage : packageSet) {
if (fullClassName.startsWith(parentExceptionPackage)) {
return parentExceptionPackage;
@@ -436,7 +436,7 @@ public abstract class AbstractExceptions{
* @param throwable parent throwable
* @return a string containing all messages found in the exception chain
*/
public static String getAllMessages(final Throwable throwable){
public static String getAllMessages(final Throwable throwable) {
final StringBuilder messageBuilder = new StringBuilder();
getAllMessages(throwable, messageBuilder);
return messageBuilder.toString();
@@ -448,7 +448,7 @@ public abstract class AbstractExceptions{
* @param throwable parent throwable
* @param messageBuilder message builder
*/
public static void getAllMessages(final Throwable throwable, final StringBuilder messageBuilder){
public static void getAllMessages(final Throwable throwable, final StringBuilder messageBuilder) {
if (throwable != null) {
final String message = throwable.getMessage();
if (!isEmpty(message)) {
@@ -470,7 +470,7 @@ public abstract class AbstractExceptions{
* @param maxDepth max depth in exception chain that will be returned
* @return an array containing stack trace elements
*/
public static StackTraceElement[] getStackTrace(final Throwable throwable, final int maxDepth){
public static StackTraceElement[] getStackTrace(final Throwable throwable, final int maxDepth) {
final ArrayList<StackTraceElement> list = new ArrayList<StackTraceElement>();
if (throwable != null) {
@@ -492,7 +492,7 @@ public abstract class AbstractExceptions{
* @param ignorePackageSet ignore packages to use for building the stack trace
* @return an array containing stack trace elements
*/
public static StackTraceElement[] getStackTrace(final Throwable throwable, final Set<String> rootPackageSet, final Set<String> ignorePackageSet){
public static StackTraceElement[] getStackTrace(final Throwable throwable, final Set<String> rootPackageSet, final Set<String> ignorePackageSet) {
final ArrayList<StackTraceElement> list = new ArrayList<StackTraceElement>();
final ArrayList<StackTraceElement> partialList = new ArrayList<StackTraceElement>();
@@ -529,7 +529,7 @@ public abstract class AbstractExceptions{
* @return true if the given cause class is found in the exception chain of the <code>throwable</code>, false
* otherwise
*/
public static boolean containsCause(final Throwable throwable, final Class<?> causeClass){
public static boolean containsCause(final Throwable throwable, final Class<?> causeClass) {
return containsCause(throwable, causeClass, null);
}
@@ -547,7 +547,7 @@ public abstract class AbstractExceptions{
* @return true if the given cause class and cause message is found in the exception chain of the
* <code>throwable</code>, false otherwise
*/
public static boolean containsCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage){
public static boolean containsCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage) {
return (searchCause(throwable, causeClass, causeMessage, DEFAULT_MAX_DEPTH) != null);
}
@@ -557,7 +557,7 @@ public abstract class AbstractExceptions{
* @param throwable parent throwable
* @return the cause of the <code>throwable</code> found or null if <code>throwable</code> does not have a cause
*/
public static Throwable getCause(final Throwable throwable){
public static Throwable getCause(final Throwable throwable) {
return getCause(throwable, DEFAULT_MAX_DEPTH);
}
@@ -573,7 +573,7 @@ public abstract class AbstractExceptions{
* @return the cause of the <code>throwable</code> found until <code>maxDepth</code> is reached in the exception
* chain or null if <code>throwable</code> does not have a cause
*/
public static Throwable getCause(final Throwable throwable, final int maxDepth){
public static Throwable getCause(final Throwable throwable, final int maxDepth) {
if (throwable == null) {
return null;
}
@@ -601,7 +601,7 @@ public abstract class AbstractExceptions{
* @param causeClass class to search for
* @return the <code>throwable</code> found or null if no class in exception chain matches the given cause class
*/
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass){
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass) {
return searchCause(throwable, causeClass, null, DEFAULT_MAX_DEPTH);
}
@@ -618,7 +618,7 @@ public abstract class AbstractExceptions{
* @return the <code>throwable</code> found or null if no class in exception chain matches the given cause class
* and cause message
*/
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage){
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage) {
return searchCause(throwable, causeClass, causeMessage, DEFAULT_MAX_DEPTH);
}
@@ -636,7 +636,7 @@ public abstract class AbstractExceptions{
* @return the <code>throwable</code> found or null if no class in exception chain matches the given cause class
* and cause message
*/
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage, final int maxDepth){
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage, final int maxDepth) {
if (throwable == null) {
return null;
}
@@ -675,7 +675,7 @@ public abstract class AbstractExceptions{
* @param maxDepth max depth in exception chain that will be searched
* @return the <code>throwable</code> found or null if no class in exception chain matches the given cause class
*/
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final int maxDepth){
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final int maxDepth) {
if (throwable == null) {
return null;
}
@@ -702,7 +702,7 @@ public abstract class AbstractExceptions{
* @param value string to check
* @return true if given string is null or has zero length after trim(), false otherwise
*/
public static boolean isEmpty(final String value){
public static boolean isEmpty(final String value) {
if (value == null) {
return true;
}
@@ -716,7 +716,7 @@ public abstract class AbstractExceptions{
* @param className fully qualified class name
* @return name of the package
*/
public static String packageName(final String className){
public static String packageName(final String className) {
if (className == null) {
return "";
}
@@ -38,7 +38,7 @@ package com.arthenica.smartexception;
* @author Taner Sener
* @since 0.1.0
*/
public interface StackTraceElementSerializer{
public interface StackTraceElementSerializer {
/**
* <p>Converts the given <code>stackTraceElement</code> into a string.
@@ -44,13 +44,13 @@ import java.util.Set;
* @author Taner Sener
* @since 0.1.0
*/
public class Exceptions{
public class Exceptions {
static{
AbstractExceptions.setStackTraceElementSerializer(new StackTraceElementSerializer(){
static {
AbstractExceptions.setStackTraceElementSerializer(new StackTraceElementSerializer() {
@Override
public String toString(StackTraceElement stackTraceElement){
public String toString(StackTraceElement stackTraceElement) {
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(stackTraceElement.getClassName());
@@ -75,17 +75,17 @@ public class Exceptions{
}
@Override
public String getModuleName(StackTraceElement stackTraceElement){
public String getModuleName(StackTraceElement stackTraceElement) {
return "";
}
@Override
public String getNativeMethodDefinition(){
public String getNativeMethodDefinition() {
return "(Native Method)";
}
@Override
public String getUnknownSourceDefinition(){
public String getUnknownSourceDefinition() {
return "(Unknown Source)";
}
});
@@ -96,14 +96,14 @@ public class Exceptions{
*
* @param packageString root package name to register
*/
public static void registerRootPackage(final String packageString){
public static void registerRootPackage(final String packageString) {
AbstractExceptions.registerRootPackage(packageString);
}
/**
* <p>Clears previously registered root packages.
*/
public static void clearRootPackages(){
public static void clearRootPackages() {
AbstractExceptions.clearRootPackages();
}
@@ -112,14 +112,14 @@ public class Exceptions{
*
* @param packageString group package name to register
*/
public static void registerGroupPackage(final String packageString){
public static void registerGroupPackage(final String packageString) {
AbstractExceptions.registerGroupPackage(packageString);
}
/**
* <p>Clears previously registered group packages.
*/
public static void clearGroupPackages(){
public static void clearGroupPackages() {
AbstractExceptions.clearGroupPackages();
}
@@ -129,7 +129,7 @@ public class Exceptions{
*
* @return current stack trace serializer implementation
*/
public static StackTraceElementSerializer getStackTraceElementSerializer(){
public static StackTraceElementSerializer getStackTraceElementSerializer() {
return AbstractExceptions.getStackTraceElementSerializer();
}
@@ -139,7 +139,7 @@ public class Exceptions{
*
* @param stackTraceElementSerializer new stack trace serializer implementation
*/
public static void setStackTraceElementSerializer(final StackTraceElementSerializer stackTraceElementSerializer){
public static void setStackTraceElementSerializer(final StackTraceElementSerializer stackTraceElementSerializer) {
AbstractExceptions.setStackTraceElementSerializer(stackTraceElementSerializer);
}
@@ -149,14 +149,14 @@ public class Exceptions{
* @param packageString ignore package name to register
* @param ignoreCauseClasses ignore cause classes from this package too
*/
public static void registerIgnorePackage(final String packageString, final boolean ignoreCauseClasses){
public static void registerIgnorePackage(final String packageString, final boolean ignoreCauseClasses) {
AbstractExceptions.registerIgnorePackage(packageString, ignoreCauseClasses);
}
/**
* <p>Clears previously registered ignore packages.
*/
public static void clearIgnorePackages(){
public static void clearIgnorePackages() {
AbstractExceptions.clearIgnorePackages();
}
@@ -167,7 +167,7 @@ public class Exceptions{
* converted to string will not include causes. If value is false causes will be appended to the stack trace of
* the main throwable.
*/
public static boolean getIgnoreAllCauses(){
public static boolean getIgnoreAllCauses() {
return AbstractExceptions.getIgnoreAllCauses();
}
@@ -178,7 +178,7 @@ public class Exceptions{
* or converted to string will not include causes. If value is false causes will be appended to the stack trace of
* the main throwable.
*/
public static void setIgnoreAllCauses(final boolean ignoreAllCauses){
public static void setIgnoreAllCauses(final boolean ignoreAllCauses) {
AbstractExceptions.setIgnoreAllCauses(ignoreAllCauses);
}
@@ -192,7 +192,7 @@ public class Exceptions{
* @param throwable parent throwable
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable){
public static String getStackTraceString(final Throwable throwable) {
return AbstractExceptions.getStackTraceString(throwable);
}
@@ -207,7 +207,7 @@ public class Exceptions{
* @param ignoreAllCauses ignore all causes in the exception chain
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable, final boolean ignoreAllCauses){
public static String getStackTraceString(final Throwable throwable, final boolean ignoreAllCauses) {
return AbstractExceptions.getStackTraceString(throwable, ignoreAllCauses);
}
@@ -220,7 +220,7 @@ public class Exceptions{
* @param ignorePackageSet ignore packages to use for building the stack trace
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable, final Set<String> rootPackageSet, final Set<String> groupPackageSet, final Set<String> ignorePackageSet){
public static String getStackTraceString(final Throwable throwable, final Set<String> rootPackageSet, final Set<String> groupPackageSet, final Set<String> ignorePackageSet) {
return AbstractExceptions.getStackTraceString(throwable, rootPackageSet, groupPackageSet, ignorePackageSet);
}
@@ -234,7 +234,7 @@ public class Exceptions{
* @param ignoreAllCauses ignore all causes in the exception chain
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable, final Set<String> rootPackageSet, final Set<String> groupPackageSet, final Set<String> ignorePackageSet, final boolean ignoreAllCauses){
public static String getStackTraceString(final Throwable throwable, final Set<String> rootPackageSet, final Set<String> groupPackageSet, final Set<String> ignorePackageSet, final boolean ignoreAllCauses) {
return AbstractExceptions.getStackTraceString(throwable, rootPackageSet, groupPackageSet, ignorePackageSet, ignoreAllCauses);
}
@@ -245,7 +245,7 @@ public class Exceptions{
* @param rootPackage root package to use for building the stack trace
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable, final String rootPackage){
public static String getStackTraceString(final Throwable throwable, final String rootPackage) {
return AbstractExceptions.getStackTraceString(throwable, rootPackage);
}
@@ -257,7 +257,7 @@ public class Exceptions{
* @param groupPackage group package to use for building the stack trace
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable, final String rootPackage, final String groupPackage){
public static String getStackTraceString(final Throwable throwable, final String rootPackage, final String groupPackage) {
return AbstractExceptions.getStackTraceString(throwable, rootPackage, groupPackage);
}
@@ -268,7 +268,7 @@ public class Exceptions{
* @param maxDepth max depth in exception chain that will be used
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable, final int maxDepth){
public static String getStackTraceString(final Throwable throwable, final int maxDepth) {
return AbstractExceptions.getStackTraceString(throwable, maxDepth);
}
@@ -280,7 +280,7 @@ public class Exceptions{
* @param ignoreAllCauses ignore all causes in the exception chain
* @return a string containing the smart stack trace for the given <code>throwable</code>
*/
public static String getStackTraceString(final Throwable throwable, final int maxDepth, final boolean ignoreAllCauses){
public static String getStackTraceString(final Throwable throwable, final int maxDepth, final boolean ignoreAllCauses) {
return AbstractExceptions.getStackTraceString(throwable, maxDepth, ignoreAllCauses);
}
@@ -290,7 +290,7 @@ public class Exceptions{
* @param throwable parent throwable
* @return a string containing all messages found in the exception chain
*/
public static String getAllMessages(final Throwable throwable){
public static String getAllMessages(final Throwable throwable) {
return AbstractExceptions.getAllMessages(throwable);
}
@@ -306,7 +306,7 @@ public class Exceptions{
* @return true if the given cause class is found in the exception chain of the <code>throwable</code>, false
* otherwise
*/
public static boolean containsCause(final Throwable throwable, final Class<?> causeClass){
public static boolean containsCause(final Throwable throwable, final Class<?> causeClass) {
return AbstractExceptions.containsCause(throwable, causeClass);
}
@@ -324,7 +324,7 @@ public class Exceptions{
* @return true if the given cause class and cause message is found in the exception chain of the
* <code>throwable</code>, false otherwise
*/
public static boolean containsCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage){
public static boolean containsCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage) {
return AbstractExceptions.containsCause(throwable, causeClass, causeMessage);
}
@@ -334,7 +334,7 @@ public class Exceptions{
* @param throwable parent throwable
* @return the cause of the <code>throwable</code> found or null if <code>throwable</code> does not have a cause
*/
public static Throwable getCause(final Throwable throwable){
public static Throwable getCause(final Throwable throwable) {
return AbstractExceptions.getCause(throwable);
}
@@ -350,7 +350,7 @@ public class Exceptions{
* @return the cause of the <code>throwable</code> found until <code>maxDepth</code> is reached in the exception
* chain or null if <code>throwable</code> does not have a cause
*/
public static Throwable getCause(final Throwable throwable, final int maxDepth){
public static Throwable getCause(final Throwable throwable, final int maxDepth) {
return AbstractExceptions.getCause(throwable, maxDepth);
}
@@ -365,7 +365,7 @@ public class Exceptions{
* @param causeClass class to search for
* @return the <code>throwable</code> found or null if no class in exception chain matches the given cause class
*/
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass){
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass) {
return AbstractExceptions.searchCause(throwable, causeClass);
}
@@ -382,7 +382,7 @@ public class Exceptions{
* @return the <code>throwable</code> found or null if no class in exception chain matches the given cause class
* and cause message
*/
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage){
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage) {
return AbstractExceptions.searchCause(throwable, causeClass, causeMessage);
}
@@ -400,7 +400,7 @@ public class Exceptions{
* @return the <code>throwable</code> found or null if no class in exception chain matches the given cause class
* and cause message
*/
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage, final int maxDepth){
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage, final int maxDepth) {
return AbstractExceptions.searchCause(throwable, causeClass, causeMessage, maxDepth);
}
@@ -416,7 +416,7 @@ public class Exceptions{
* @param maxDepth max depth in exception chain that will be searched
* @return the <code>throwable</code> found or null if no class in exception chain matches the given cause class
*/
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final int maxDepth){
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final int maxDepth) {
return AbstractExceptions.searchCause(throwable, causeClass, maxDepth);
}
@@ -0,0 +1,35 @@
package com.vk.api.gifts;
import android.content.Context;
import com.vk.api.base.ApiRequest;
import com.vk.dto.gift.CatalogedGift;
import org.json.JSONException;
import org.json.JSONObject;
public class GiftGetByStickerId extends ApiRequest<GiftGetByStickerId.a> {
public static class a {
public final int a;
public final CatalogedGift b;
public a(int i, CatalogedGift catalogedGift) {
this.a = i;
this.b = catalogedGift;
}
}
public GiftGetByStickerId(Context context, int i) {
super("execute.getGiftByStickerId");
b("sticker_id", i);
c("no_inapp", "0");
b("force_payment", 1);
}
@Override // com.vk.api.sdk.o.VKRequest
public GiftGetByStickerId.a a(JSONObject jSONObject) throws JSONException {
JSONObject jSONObject2 = jSONObject.getJSONObject("response");
return new a(jSONObject2.optInt("balance"),
new CatalogedGift(jSONObject2.getJSONObject("gift")));
}
}
@@ -0,0 +1,220 @@
package com.vk.core.util;
import static ru.vtosters.lite.utils.Preferences.getDownloadsDir;
import static ru.vtosters.lite.utils.Preferences.getMusicDir;
import static ru.vtosters.lite.utils.Preferences.getPhotosDir;
import static ru.vtosters.lite.utils.Preferences.getVideosDir;
import android.annotation.SuppressLint;
import android.app.DownloadManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import com.facebook.common.i.MediaUtils;
import com.facebook.x.g.EncodedImage;
import com.vk.core.concurrent.VkExecutors;
import com.vk.imageloader.VKImageLoader;
import com.vk.log.L;
import com.vk.metrics.eventtracking.VkTracker;
import com.vtosters.lite.R;
import java.io.File;
import java.io.InputStream;
import java.net.URI;
import java.util.HashSet;
import b.h.g.m.CameraUtils;
import b.h.g.m.FileUtils;
public class DownloadUtils {
public static final HashSet<Long> a = new HashSet<>();
public static void a(Context context, String str, String str2) {
a(context, str, str2, false);
}
public static void b(Context context, String str, String str2) {
a(context, str, str2, true);
}
private static void a(Context context, String str, String str2, boolean z) {
try {
b(context, str, str2, z);
} catch (Exception e2) {
L.d(e2);
ToastUtils.a(context.getString(R.string.error) + " [" + e2.getMessage() + "]");
}
}
private static void b(final Context context, String str, String str2, boolean z) {
if (TextUtils.isEmpty(str2)) {
return;
}
String file = a(str, str2);
File b2;
boolean c2 = MediaUtils.c(MediaUtils.b(str2));
if (str.endsWith("png") || str.endsWith("jpg") || str.endsWith("jpeg")) {
b2 = new File(getPhotosDir(), file);
} else if (str.endsWith("mp3") || str.endsWith("wav") || str.endsWith("ogg") || str.endsWith("aac") || str.endsWith("flac") || str.endsWith("m4a")) {
b2 = new File(getMusicDir(), file);
} else if (str.endsWith("mp4") || str.endsWith("mkv") || str.endsWith("avi") || str.endsWith("flv") || str.endsWith("wmv") || str.endsWith("mov") || str.endsWith("3gp")) {
b2 = new File(getVideosDir(), file);
} else {
b2 = new File(getDownloadsDir(), file);
}
if (c2) {
EncodedImage c3 = VKImageLoader.c(Uri.parse(str2));
final InputStream h = c3 == null ? null : c3.h();
if (h != null) {
try {
if (b2.exists() || FileUtils.b(b2)) {
VkExecutors.x.a().execute(() -> ToastUtils.a(context.getString(R.string.file_saved, b2.getAbsoluteFile())));
}
} catch (Exception e2) {
L.a(e2);
}
CameraUtils.a(context, b2, null);
return;
}
}
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(str2));
request.setDestinationUri(Uri.fromFile(b2));
request.setMimeType(FileUtils.f(new File(str)));
request.setNotificationVisibility(1);
request.allowScanningByMediaScanner();
request.setTitle(str);
DownloadManager a2 = a(context);
if (a2 == null) {
return;
}
try {
long enqueue = a2.enqueue(request);
if (!z) {
return;
}
a.add(enqueue);
} catch (IllegalArgumentException e3) {
L.a(e3);
b(context);
}
}
private static String a(String str, String str2) {
String lastPathSegment = Uri.parse(str2).getLastPathSegment();
if (!TextUtils.isEmpty(str)) {
String replace = str.replace('/', '_');
return !replace.contains(".") ? lastPathSegment : replace;
}
return lastPathSegment;
}
@SuppressLint("Range")
public static boolean a(Context context, Uri uri) {
try {
Cursor query = a(context).query(new DownloadManager.Query().setFilterByStatus(11));
if (query != null && query.moveToFirst()) {
while (!uri.toString().equals(query.getString(query.getColumnIndex("uri")))) {
if (!query.moveToNext()) {
query.close();
return false;
}
}
@SuppressLint("Range")
int i = query.getInt(query.getColumnIndex("status"));
@SuppressLint("Range")
String string = query.getString(query.getColumnIndex("local_uri"));
query.close();
if (i == 1 || i == 2) {
ToastUtils.a(R.string.download_is_in_progress);
query.close();
return true;
} else if (i != 8) {
query.close();
return false;
} else {
boolean a2 = a(context, string);
query.close();
return a2;
}
}
return false;
} catch (SQLiteException e2) {
VkTracker.k.b(e2);
return false;
}
}
private static void b(Context context) {
if (context != null) {
try {
context.startActivity(new Intent("android.settings.APPLICATION_DETAILS_SETTINGS").setData(Uri.parse("package:com.android.providers.downloads")));
} catch (ActivityNotFoundException e2) {
L.a(e2);
context.startActivity(new Intent("android.settings.MANAGE_APPLICATIONS_SETTINGS"));
}
ToastUtils.a("Please enable download manager", true);
}
}
public static boolean a(Context context, String str) {
File file;
try {
try {
file = new File(new URI(str));
try {
if (!file.exists()) {
return false;
}
Intent intent = new Intent("android.intent.action.VIEW");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
String f2 = FileUtils.f(file);
if (!TextUtils.isEmpty(f2)) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(FileUtils.n(file), f2);
context.startActivity(intent);
return true;
}
throw new ActivityNotFoundException();
} catch (ActivityNotFoundException unused) {
return a(context, file);
}
} catch (ActivityNotFoundException unused2) {
unused2.printStackTrace();
}
} catch (Throwable th) {
VkTracker.k.b(th);
return false;
}
return false;
}
private static boolean a(Context context, File file) {
if (file != null && file.exists()) {
Intent intent = new Intent("android.intent.action.VIEW");
intent.setDataAndType(Uri.parse(file.getAbsolutePath()), "application/*");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(intent);
return true;
} catch (ActivityNotFoundException e2) {
L.a(e2);
}
}
return false;
}
private static DownloadManager a(Context context) {
return (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
}
}
@@ -0,0 +1,37 @@
package com.vk.im.ui.components.common;
public enum DialogAction {
OPEN_USER_PROFILE,
OPEN_GROUP_PROFILE,
CHAT_SETTINGS,
SEARCH,
ADD_CHAT_MEMBER,
CREATE_SHORTCUT,
PINNED_MSG_HIDE,
PINNED_MSG_SHOW,
PINNED_MSG_DETACH,
SHOW_ATTACHES,
NOTIFICATIONS_ON,
NOTIFICATIONS_OFF,
GROUP_RECEIVE_MSGS_ENABLE,
GROUP_RECEIVE_MSGS_DISABLE,
GROUP_RECEIVE_NOTIFY_DISABLE,
CHANNEL_INVITE_LINK,
CLEAR_HISTORY,
CLEAR_HISTORY_AND_LEAVE,
LEAVE,
LEAVE_CHANNEL,
RETURN,
RETURN_TO_CHANNEL,
MARK_AS_READ,
AUDIO_BTN_AUDIO_CALL,
AUDIO_BTN_VIDEO_CALL,
VIDEO_BTN_VIDEO_CALL,
VIDEO_BTN_AUDIO_CALL,
DNR_ON,
DNR_OFF,
DNT_ON,
DNT_OFF,
pinmsg,
unpinmsg,
}
@@ -0,0 +1,148 @@
package com.vk.im.ui.components.common;
import com.vk.core.extensions.CollectionExt;
import com.vk.core.network.TimeProvider;
import com.vk.im.engine.ImConfig;
import com.vk.im.engine.models.MemberType;
import com.vk.im.engine.models.Profile;
import com.vk.im.engine.models.ProfilesSimpleInfo;
import com.vk.im.engine.models.dialogs.ChatSettings;
import com.vk.im.engine.models.dialogs.Dialog;
import com.vk.im.engine.models.groups.Group;
import com.vk.im.engine.utils.DialogPermissionHelper;
import com.vk.im.ui.p.ImBridge7;
import java.util.ArrayList;
import java.util.List;
import ru.vtosters.lite.dnr.DNRInjector;
public final class DialogActionsHelper {
public static final DialogActionsHelper a = new DialogActionsHelper();
public final List<DialogAction> a(ImConfig imConfig, Dialog dialog, ProfilesSimpleInfo profilesSimpleInfo) {
if (dialog != null && profilesSimpleInfo != null) {
long b2 = TimeProvider.f.b();
ChatSettings z1 = dialog.z1();
boolean z = false;
boolean I1 = z1 != null && z1.I1();
ArrayList<DialogAction> arrayList = new ArrayList<>();
DNRInjector.inject(dialog, arrayList);
arrayList.add(DialogAction.SEARCH);
if (dialog.S1()) {
arrayList.add(DialogAction.SHOW_ATTACHES);
}
if (!I1 && !dialog.W1()) {
arrayList.add(DialogAction.CLEAR_HISTORY);
}
if (I1) {
arrayList.add(DialogAction.CHANNEL_INVITE_LINK);
}
if (dialog.K1() != null) {
CollectionExt.a(arrayList, DialogAction.PINNED_MSG_DETACH, !I1);
CollectionExt.a(arrayList, DialogAction.PINNED_MSG_SHOW, !dialog.L1());
CollectionExt.a(arrayList, DialogAction.PINNED_MSG_HIDE, dialog.L1());
}
if (dialog.a(MemberType.USER)) {
arrayList.add(DialogAction.OPEN_USER_PROFILE);
}
if (dialog.a(MemberType.GROUP)) {
arrayList.add(DialogAction.OPEN_GROUP_PROFILE);
Group group = profilesSimpleInfo.w1().get(dialog.I1());
if (group != null) {
if (group.v1()) {
arrayList.add(DialogAction.GROUP_RECEIVE_MSGS_DISABLE);
} else {
CollectionExt.a(arrayList, DialogAction.GROUP_RECEIVE_NOTIFY_DISABLE, group.w1());
CollectionExt.a(arrayList, DialogAction.GROUP_RECEIVE_MSGS_ENABLE, !group.w1());
}
}
}
if (dialog.W1()) {
DialogAction dialogAction = DialogAction.ADD_CHAT_MEMBER;
ChatSettings z12 = dialog.z1();
if (z12 != null) {
z = z12.y1();
}
CollectionExt.a(arrayList, dialogAction, z);
CollectionExt.a(arrayList, DialogAction.CHAT_SETTINGS, DialogPermissionHelper.a.a(dialog));
}
CollectionExt.a(arrayList, DialogAction.NOTIFICATIONS_ON, !dialog.b(b2));
CollectionExt.a(arrayList, DialogAction.NOTIFICATIONS_OFF, dialog.b(b2));
return arrayList;
}
return new ArrayList<>();
}
public final List<DialogAction> a(Dialog dialog, ProfilesSimpleInfo profilesSimpleInfo) {
long b2 = TimeProvider.f.b();
Profile profile = profilesSimpleInfo.get(dialog.getId());
if (!(profile instanceof Group)) {
profile = null;
}
Group group = (Group) profile;
ChatSettings z1 = dialog.z1();
ArrayList<DialogAction> arrayList = new ArrayList<>();
DNRInjector.inject(dialog, arrayList);
// if (dialog.hasUnread()) {
arrayList.add(DialogAction.MARK_AS_READ);
// }
if (!dialog.W1()) {
arrayList.add(DialogAction.CREATE_SHORTCUT);
arrayList.add(DialogAction.CLEAR_HISTORY);
CollectionExt.a(arrayList, DialogAction.NOTIFICATIONS_OFF, dialog.b(b2));
CollectionExt.a(arrayList, DialogAction.NOTIFICATIONS_ON, !dialog.b(b2));
}
if (dialog.a(MemberType.GROUP) && group != null) {
if (group.v1()) {
arrayList.add(DialogAction.GROUP_RECEIVE_MSGS_DISABLE);
} else {
CollectionExt.a(arrayList, DialogAction.GROUP_RECEIVE_NOTIFY_DISABLE, group.w1());
CollectionExt.a(arrayList, DialogAction.GROUP_RECEIVE_MSGS_ENABLE, !group.w1());
}
}
if (dialog.W1() && z1 != null) {
if (!z1.L1()) {
arrayList.add(DialogAction.CREATE_SHORTCUT);
CollectionExt.a(arrayList, DialogAction.NOTIFICATIONS_OFF, dialog.b(b2));
CollectionExt.a(arrayList, DialogAction.NOTIFICATIONS_ON, !dialog.b(b2));
}
CollectionExt.a(arrayList, DialogAction.CLEAR_HISTORY, z1.L1());
if (z1.I1()) {
CollectionExt.a(arrayList, DialogAction.LEAVE_CHANNEL, !z1.L1());
CollectionExt.a(arrayList, DialogAction.RETURN_TO_CHANNEL, z1.L1());
} else {
CollectionExt.a(arrayList, DialogAction.RETURN, z1.L1());
CollectionExt.a(arrayList, DialogAction.LEAVE, !z1.L1());
CollectionExt.a(arrayList, DialogAction.CLEAR_HISTORY_AND_LEAVE, !z1.L1());
}
}
return arrayList;
}
public final boolean a(Dialog dialog) {
if (dialog.V1() || !dialog.y1()) {
return false;
}
return !dialog.U1() || !ImBridge7.a().a();
}
}
@@ -0,0 +1,15 @@
package com.vk.im.ui.components.common;
public enum MsgAction {
RETRY,
REPLY,
FORWARD,
COPY,
EDIT,
DELETE,
SPAM,
PIN,
UNPIN,
TRANSLATE,
READTO
}
@@ -0,0 +1,43 @@
package com.vk.im.ui.components.common;
import com.vk.core.extensions.CollectionExt;
import com.vk.im.engine.ImConfig;
import com.vk.im.engine.ImEngine;
import com.vk.im.engine.models.dialogs.Dialog;
import com.vk.im.engine.models.messages.Msg;
import com.vk.im.engine.utils.MsgPermissionHelper;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public final class MsgActionHelper {
public static final MsgActionHelper a = new MsgActionHelper();
public final List<MsgAction> a(ImEngine imEngine, Dialog dialog, Collection<? extends Msg> collection) {
return a(imEngine != null ? imEngine.g() : null, dialog, collection);
}
public final List<MsgAction> a(ImConfig imConfig, Dialog dialog, Collection<? extends Msg> collection) {
if (imConfig != null && dialog != null && collection != null) {
MsgPermissionHelper.a aVar = new MsgPermissionHelper.a(imConfig, dialog, collection);
ArrayList<MsgAction> arrayList = new ArrayList<>();
CollectionExt.a(arrayList, MsgAction.RETRY, MsgPermissionHelper.b.g(aVar));
CollectionExt.a(arrayList, MsgAction.REPLY, MsgPermissionHelper.b.f(aVar));
CollectionExt.a(arrayList, MsgAction.FORWARD, MsgPermissionHelper.b.d(aVar));
CollectionExt.a(arrayList, MsgAction.COPY, MsgPermissionHelper.b.a(aVar));
CollectionExt.a(arrayList, MsgAction.EDIT, MsgPermissionHelper.b.c(aVar));
CollectionExt.a(arrayList, MsgAction.DELETE, MsgPermissionHelper.b.b(aVar));
CollectionExt.a(arrayList, MsgAction.SPAM, MsgPermissionHelper.b.h(aVar));
CollectionExt.a(arrayList, MsgAction.PIN, MsgPermissionHelper.b.e(aVar));
CollectionExt.a(arrayList, MsgAction.UNPIN, MsgPermissionHelper.b.i(aVar));
CollectionExt.a(arrayList, MsgAction.TRANSLATE, true);
CollectionExt.a(arrayList, MsgAction.READTO, true);
return arrayList;
}
return new ArrayList<>();
}
}
@@ -0,0 +1,131 @@
package com.vk.im.ui.views;
import androidx.annotation.NonNull;
public class Corners{
private int topLeft;
private int topRight;
private int bottomLeft;
private int bottomRight;
public Corners(int i, int i2, int i3, int i4){
this.topLeft = i;
this.topRight = i2;
this.bottomLeft = i3;
this.bottomRight = i4;
}
public Corners(int i, int i2, int i3, int i4, int i5) {
this((i5 & 1) != 0 ? 0 : i, (i5 & 2) != 0 ? 0 : i2, (i5 & 4) != 0 ? 0 : i3, (i5 & 8) != 0 ? 0 : i4);
}
public Corners() {
this(0, 0, 0, 0, 15);
}
public static Corners a(Corners corners, int i, int i2, int i3, int i4, int i5, Object obj){
if ((i5 & 1) != 0) {
i = corners.topLeft;
}
if ((i5 & 2) != 0) {
i2 = corners.topRight;
}
if ((i5 & 4) != 0) {
i3 = corners.bottomLeft;
}
if ((i5 & 8) != 0) {
i4 = corners.bottomRight;
}
corners.a(i, i2, i3, i4);
return corners;
}
public int a(){
return this.bottomLeft;
}
public int b(){
return this.bottomRight;
}
public int c(){
return this.topLeft;
}
public int d(){
return this.topRight;
}
public boolean e(){
int i;
int i2 = this.topLeft;
int i3 = this.topRight;
return i2 == i3 && i3 == (i = this.bottomRight) && this.bottomLeft == i;
}
public boolean equals(Object obj){
if (this != obj) {
if (!(obj instanceof Corners)) {
return false;
}
Corners corners = (Corners) obj;
return this.topLeft == corners.topLeft && this.topRight == corners.topRight && this.bottomLeft == corners.bottomLeft && this.bottomRight == corners.bottomRight;
}
return true;
}
public boolean f(){
return this.topLeft == 0 && e();
}
public void g(){
a(0, 0);
}
public int hashCode(){
return (((((this.topLeft * 31) + this.topRight) * 31) + this.bottomLeft) * 31) + this.bottomRight;
}
@NonNull
public String toString(){
return "Corners(topLeft=" + this.topLeft + ", topRight=" + this.topRight + ", bottomLeft=" + this.bottomLeft + ", bottomRight=" + this.bottomRight + ")";
}
public Corners a(int i, int i2){
if ((i2 & 1) > 0) {
this.topLeft = i;
}
if ((i2 & 2) > 0) {
this.topRight = i;
}
if ((i2 & 4) > 0) {
this.bottomLeft = i;
}
if ((i2 & 8) > 0) {
this.bottomRight = i;
}
if (i2 == 0) {
this.topLeft = 0;
this.topRight = 0;
this.bottomLeft = 0;
this.bottomRight = 0;
}
return this;
}
public Corners a(int i, int i2, int i3, int i4){
this.topLeft = i;
this.topRight = i2;
this.bottomLeft = i3;
this.bottomRight = i4;
return this;
}
public Corners a(Corners corners){
this.topLeft = corners.topLeft;
this.topRight = corners.topRight;
this.bottomLeft = corners.bottomLeft;
this.bottomRight = corners.bottomRight;
return this;
}
}
@@ -0,0 +1,137 @@
package com.vk.im.ui.views.avatars;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import com.vk.im.ui.o;
public class StoryBorderView extends View {
private boolean B;
private final Paint a;
private LinearGradient f15747b;
private int f15748c;
private int f15749d;
private int f15750e;
private int f15751f;
private final int g;
private final int h;
public StoryBorderView(Context context) {
this(context, null, 0, 6);
}
public StoryBorderView(Context context, AttributeSet attributeSet) {
this(context, attributeSet, 0, 4);
}
public StoryBorderView(Context context, AttributeSet attributeSet, int i, int i2) {
this(context, (i2 & 2) != 0 ? null : attributeSet, (i2 & 4) != 0 ? 0 : i);
}
public int getBorderColor() {
return this.f15749d;
}
public int getBorderGradientEndColor() {
return this.h;
}
public int getBorderGradientStartColor() {
return this.g;
}
public int getBorderWidth() {
return this.f15750e;
}
public int getPadding() {
return this.f15751f;
}
public int getViewSize() {
return this.f15748c;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawOval(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(), getHeight() - getPaddingBottom(), this.a);
}
@Override
protected void onMeasure(int i, int i2) {
int i3 = this.f15748c;
setMeasuredDimension(i3, i3);
}
public void setBorderColor(int i) {
if (this.f15749d != i) {
this.f15749d = i;
this.a.setColor(i);
invalidate();
}
}
public void setBorderWidth(int i) {
if (this.f15750e != i) {
this.f15750e = i;
this.a.setStrokeWidth(i);
invalidate();
}
}
@Override
public void setLayoutParams(ViewGroup.LayoutParams layoutParams) {
super.setLayoutParams(layoutParams);
boolean z = false;
this.f15748c = Math.min(layoutParams != null ? layoutParams.width : 0, layoutParams != null ? layoutParams.height : 0);
this.f15747b = new LinearGradient(0.0f, 0.0f, 0.0f, this.f15748c, this.g, this.h, Shader.TileMode.MIRROR);
if (this.f15748c > 0) {
z = true;
}
if (z) {
return;
}
throw new IllegalArgumentException("Only exact size supported, specify avatar sizes in layout params");
}
public void setLive(boolean z) {
if (this.B != z) {
this.a.setShader(z ? this.f15747b : null);
this.a.setColor(z ? -1 : this.f15749d);
this.B = z;
invalidate();
}
}
public void setPadding(int i) {
if (this.f15751f != i) {
this.f15751f = i;
setPadding(i, i, i, i);
}
}
public void setViewSize(int i) {
this.f15748c = i;
}
public StoryBorderView(Context context, AttributeSet attributeSet, int i) {
super(context, attributeSet, i);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
this.a = paint;
TypedArray obtainStyledAttributes = context.obtainStyledAttributes(attributeSet, o.StoryBorderView);
setBorderColor(obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderColor, 0));
this.g = obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderGradientStartColor, 0);
this.h = obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderGradientEndColor, 0);
setBorderWidth(obtainStyledAttributes.getDimensionPixelSize(o.StoryBorderView_vkim_borderWidth, 0));
obtainStyledAttributes.recycle();
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,304 @@
package com.vk.sharing.view;
import static b.h.z.f.roboto_medium;
import static ru.vtosters.lite.utils.Preferences.preferences;
import static ru.vtosters.lite.utils.ThemesUtils.getAccentColor;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.AttributeSet;
import androidx.annotation.UiThread;
import androidx.core.content.ContextCompat;
import com.facebook.drawee.drawable.ScalingUtils;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.view.DraweeHolder;
import com.vk.core.util.ContextExtKt;
import com.vk.core.util.Screen;
import com.vk.im.ui.views.avatars.AbbreviationAvatarDrawable;
import com.vk.imageloader.view.VKMultiImageView;
import com.vk.navigation.NavigatorKeys;
import com.vtosters.lite.R;
import com.vtosters.lite.a0;
import java.util.Arrays;
import ru.vtosters.lite.utils.AndroidUtils;
@UiThread
public class TargetImageView extends VKMultiImageView {
private static final int I = Screen.a(2);
private final int B;
private final int C;
private Drawable D;
private String[] F;
private int G;
private final RectF f21629d;
private final Paint f21630e;
private Canvas f21631f;
private final RectF g;
private final Paint h;
public TargetImageView(Context context, Drawable d) {
this(context, null, 0, 6);
}
public TargetImageView(Context context, AttributeSet attributeSet) {
this(context, attributeSet, 0, 4);
}
public TargetImageView(Context context, AttributeSet attributeSet, int i, int i2) {
this(context, (i2 & 2) != 0 ? null : attributeSet, (i2 & 4) != 0 ? 0 : i);
}
private void e() {
int i = this.G;
for (int i2 = 0; i2 < i; i2++) {
a(i2, this.F[i2]);
}
}
private void f() {
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int width = (getWidth() - paddingLeft) - getPaddingRight();
int height = (getHeight() - paddingTop) - getPaddingBottom();
int i = width / 2;
int i2 = height / 2;
int i3 = this.G;
if (i3 == 1) {
DraweeHolder<GenericDraweeHierarchy> a2 = this.a.a(0);
Drawable d2 = a2.d();
if (d2 != null) {
d2.setBounds(paddingLeft, paddingTop, width + paddingLeft, height + paddingTop);
}
} else if (i3 == 2) {
DraweeHolder<GenericDraweeHierarchy> a3 = this.a.a(0);
Drawable d3 = a3.d();
if (d3 != null) {
int i4 = i + paddingLeft;
int i5 = height + paddingTop;
d3.setBounds(paddingLeft, paddingTop, i4, i5);
DraweeHolder<GenericDraweeHierarchy> a4 = this.a.a(1);
Drawable d4 = a4.d();
if (d4 != null) {
d4.setBounds(i4, paddingTop, paddingLeft + width, i5);
}
}
} else if (i3 == 3) {
DraweeHolder<GenericDraweeHierarchy> a5 = this.a.a(0);
Drawable d5 = a5.d();
if (d5 != null) {
int i6 = i + paddingLeft;
int i7 = height + paddingTop;
d5.setBounds(paddingLeft, paddingTop, i6, i7);
DraweeHolder<GenericDraweeHierarchy> a6 = this.a.a(1);
Drawable d6 = a6.d();
if (d6 != null) {
int i9 = paddingLeft + width;
int i10 = i2 + paddingTop;
d6.setBounds(i6, paddingTop, i9, i10);
DraweeHolder<GenericDraweeHierarchy> a7 = this.a.a(2);
Drawable d7 = a7.d();
if (d7 != null) {
d7.setBounds(i6, i10, i9, i7);
}
}
}
} else {
DraweeHolder<GenericDraweeHierarchy> a8 = this.a.a(0);
Drawable d8 = a8.d();
if (d8 != null) {
int i11 = i + paddingLeft;
int i13 = i2 + paddingTop;
d8.setBounds(paddingLeft, paddingTop, i11, i13);
DraweeHolder<GenericDraweeHierarchy> a9 = this.a.a(1);
Drawable d9 = a9.d();
if (d9 != null) {
int i16 = height + paddingTop;
d9.setBounds(paddingLeft, i13, i11, i16);
DraweeHolder<GenericDraweeHierarchy> a10 = this.a.a(2);
Drawable d10 = a10.d();
if (d10 != null) {
int i18 = paddingLeft + width;
d10.setBounds(i11, paddingTop, i18, i13);
DraweeHolder<GenericDraweeHierarchy> a11 = this.a.a(3);
Drawable d11 = a11.d();
if (d11 != null) {
d11.setBounds(i11, i13, i18, i16);
}
}
}
}
}
}
private void g() {
if (getWidth() == 0 || getHeight() == 0) {
return;
}
f();
}
private AbbreviationAvatarDrawable getAbbreviationDrawable() {
return a(getContext(), null, 2);
}
private AbbreviationAvatarDrawable a(Context context, Typeface typeface, int i) {
return new AbbreviationAvatarDrawable(context, (i & 2) != 0 ? ContextExtKt.e(context, roboto_medium) : typeface);
}
public void a(String str) {
Arrays.fill(this.F, null);
if (str == null) {
b();
this.G = 1;
g();
e();
return;
}
Uri uri = Uri.parse(str);
if (uri.getScheme().equals("vkchatphoto")) {
this.G = 0;
while (true) {
String queryParameter = uri.getQueryParameter("photo" + this.G);
if (queryParameter != null) {
int i = this.G;
this.G = i + 1;
this.F[i] = queryParameter;
} else {
g();
e();
return;
}
}
} else if (uri.getScheme().equals("vkchatplaceholder")) {
this.G = 1;
g();
AbbreviationAvatarDrawable abbreviationDrawable = getAbbreviationDrawable();
String queryParameter2 = uri.getQueryParameter(NavigatorKeys.Q);
int parseInt = queryParameter2 != null ? Integer.parseInt(queryParameter2) : 0;
String queryParameter3 = uri.getQueryParameter(NavigatorKeys.d);
if (queryParameter3 == null) {
queryParameter3 = "";
}
abbreviationDrawable.a(parseInt, queryParameter3);
a(0, getAbbreviationDrawable());
} else {
this.F[0] = str;
this.G = 1;
g();
e();
}
}
@Override // android.view.View
protected void onDraw(Canvas canvas) {
Canvas canvas2 = this.f21631f;
int pref = preferences.getInt("pic_rounding", 0);
if (canvas2 != null) {
canvas2.drawColor(0, PorterDuff.Mode.CLEAR);
}
int i = this.G;
for (int i2 = 0; i2 < i; i2++) {
DraweeHolder<GenericDraweeHierarchy> a2 = this.a.a(i2);
Drawable d2 = a2.d();
if (d2 != null) {
Canvas canvas3 = this.f21631f;
d2.draw(canvas3);
}
}
if (pref > 0) {
canvas.drawRoundRect(this.f21629d, pref, pref, this.f21630e);
} else {
canvas.drawOval(this.f21629d, this.f21630e);
}
if (isSelected()) {
if (pref > 0) {
canvas.drawRoundRect(this.g.left, this.g.top, this.g.right, this.g.bottom, pref, pref, this.h);
} else {
canvas.drawCircle(this.g.centerX(), this.g.centerY(), this.g.width() / 2, this.h);
}
this.D.draw(canvas);
}
}
@Override // android.view.View
protected void onSizeChanged(int i, int i2, int i3, int i4) {
super.onSizeChanged(i, i2, i3, i4);
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
int paddingTop = getPaddingTop();
int i5 = i - paddingRight;
int paddingBottom = i2 - getPaddingBottom();
this.f21629d.set(paddingLeft, paddingTop, i5, paddingBottom);
Bitmap createBitmap = Bitmap.createBitmap(i5, paddingBottom, Bitmap.Config.ARGB_8888);
this.f21631f = new Canvas(createBitmap);
Shader.TileMode tileMode = Shader.TileMode.CLAMP;
this.f21630e.setShader(new BitmapShader(createBitmap, tileMode, tileMode));
float f2 = I / 2;
this.g.set(f2, f2, i - f2, (float) i2 - f2);
float f4 = i / 2;
this.h.setShader(new LinearGradient(f4, 0.0f, f4, (float) i2, this.B, this.C, Shader.TileMode.CLAMP));
Drawable drawable = this.D;
drawable.setBounds(i - drawable.getIntrinsicWidth(), i2 - this.D.getIntrinsicHeight(), i, i2);
f();
}
public TargetImageView(Context context, AttributeSet attributeSet, int i) {
super(context, attributeSet, i);
this.f21629d = new RectF();
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
paint.setFilterBitmap(true);
this.f21630e = paint;
this.g = new RectF();
Paint paint2 = new Paint();
paint2.setAntiAlias(true);
paint2.setStrokeWidth(I);
paint2.setStyle(Paint.Style.STROKE);
this.h = paint2;
this.B = getAccentColor();
this.C = this.B;
Drawable c2 = ContextExtKt.c(context, R.drawable.ic_check_circle_composite_24_full);
if (c2 != null) {
this.D = c2;
this.F = new String[4];
int i2 = I * 2;
setPadding(i2, i2, i2, i2);
if (attributeSet != null) {
TypedArray obtainStyledAttributes = context.obtainStyledAttributes(attributeSet, a0.TargetImageView);
setSelected(obtainStyledAttributes.getBoolean(0, false));
obtainStyledAttributes.recycle();
}
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.user_placeholder);
for (int i3 = 0; i3 <= 3; i3++) {
a();
DraweeHolder<GenericDraweeHierarchy> a3 = this.a.a(i3);
a3.b().e(drawable);
}
setScaleType(ScalingUtils.b.o);
}
}
}
+21 -21
View File
@@ -1,7 +1,7 @@
package com.vtosters.lite;
public class R{
public static final class anim{
public class R {
public static final class anim {
public static final int abc_fade_in = 0x7f010000;
public static final int abc_fade_out = 0x7f010001;
public static final int abc_grow_fade_in_from_bottom = 0x7f010002;
@@ -75,7 +75,7 @@ public class R{
public static final int vkme_exit_noop = 0x7f010046;
}
public static final class animator{
public static final class animator {
public static final int design_appbar_state_list_animator = 0x7f020000;
public static final int design_fab_hide_motion_spec = 0x7f020001;
public static final int design_fab_show_motion_spec = 0x7f020002;
@@ -88,7 +88,7 @@ public class R{
public static final int mtrl_fab_transformation_sheet_expand_spec = 0x7f020009;
}
public static final class array{
public static final class array {
public static final int ad_report_reasons = 0x7f030000;
public static final int ad_report_reasons_api = 0x7f030001;
public static final int address_will_be_opened = 0x7f030002;
@@ -180,7 +180,7 @@ public class R{
public static final int when_day_of_week = 0x7f030058;
}
public static final class attr{
public static final class attr {
public static final int BMSB_error_text_color = 0x7f040000;
public static final int BuyMusicSubscriptionButtonStyle = 0x7f040001;
public static final int PIAlphaNormal = 0x7f040002;
@@ -2091,7 +2091,7 @@ public class R{
public static final int zOrderOnTop = 0x7f040773;
}
public static final class bool{
public static final class bool {
public static final int abc_action_bar_embed_tabs = 0x7f050000;
public static final int abc_allow_stacked_button_bar = 0x7f050001;
public static final int abc_config_actionMenuItemAllCaps = 0x7f050002;
@@ -2110,7 +2110,7 @@ public class R{
public static final int vk_is_tablet = 0x7f05000f;
}
public static final class color{
public static final class color {
public static final int abc_background_cache_hint_selector_material_dark = 0x7f060000;
public static final int abc_background_cache_hint_selector_material_light = 0x7f060001;
public static final int abc_btn_colored_borderless_text_material = 0x7f060002;
@@ -2918,7 +2918,7 @@ public class R{
public static final int abc_color_highlight_material = 0x7f060004;
}
public static final class dimen{
public static final class dimen {
public static final int _post_side_padding = 0x7f070000;
public static final int abc_action_bar_content_inset_material = 0x7f070001;
public static final int abc_action_bar_content_inset_with_nav = 0x7f070002;
@@ -3783,7 +3783,7 @@ public class R{
public static final int camera_target_text_size = 0x7f070074;
}
public static final class drawable{
public static final class drawable {
public static final int $$notification_receive_28_60fps__1__0 = 0x7f080000;
public static final int $$notification_receive_28_60fps__1__1 = 0x7f080001;
public static final int $$notification_receive_28_60fps__1__2 = 0x7f080002;
@@ -6801,7 +6801,7 @@ public class R{
public static final int promo_qr_2 = 0x7f0809cf;
}
public static final class font{
public static final class font {
public static final int fortun_af_led7seg_3 = 0x7f090000;
public static final int roboto_black = 0x7f090001;
public static final int roboto_black_italic = 0x7f090002;
@@ -6824,7 +6824,7 @@ public class R{
public static final int vk_tt_commons_demi_bold = 0x7f090013;
}
public static final class id{
public static final class id {
public static final int ALT = 0x7f0a0000;
public static final int CIRCLE = 0x7f0a0001;
public static final int CTRL = 0x7f0a0002;
@@ -10931,7 +10931,7 @@ public class R{
public static final int choose_btn = 0x7f0a1007;
}
public static final class integer{
public static final class integer {
public static final int abc_config_activityDefaultDur = 0x7f0b0000;
public static final int abc_config_activityShortDur = 0x7f0b0001;
public static final int angle_rtl_180 = 0x7f0b0002;
@@ -10980,14 +10980,14 @@ public class R{
public static final int s2dip = 0x7f0b0028;
}
public static final class interpolator{
public static final class interpolator {
public static final int mtrl_fast_out_linear_in = 0x7f0c0000;
public static final int mtrl_fast_out_slow_in = 0x7f0c0001;
public static final int mtrl_linear = 0x7f0c0002;
public static final int mtrl_linear_out_slow_in = 0x7f0c0003;
}
public static final class layout{
public static final class layout {
public static final int ab_done_right = 0x7f0d0000;
public static final int abc_action_bar_title_item = 0x7f0d0001;
public static final int abc_action_bar_up_container = 0x7f0d0002;
@@ -12749,7 +12749,7 @@ public class R{
public static final int tgs_entry = 0x7f0d06de;
}
public static final class menu{
public static final class menu {
public static final int add = 0x7f0e0000;
public static final int attach_item = 0x7f0e0001;
public static final int audio = 0x7f0e0002;
@@ -12824,7 +12824,7 @@ public class R{
public static final int vkim_photo_viewer = 0x7f0e0047;
}
public static final class mipmap{
public static final class mipmap {
public static final int adaptive_launcher_background = 0x7f0f0000;
public static final int adaptive_launcher_foreground = 0x7f0f0001;
public static final int ic_launcher_round = 0x7f0f0002;
@@ -12840,7 +12840,7 @@ public class R{
public static final int ic_skip_previous_alpha_40_28 = 0x7f0f000b;
}
public static final class plurals{
public static final class plurals {
public static final int accessibility_comments = 0x7f100000;
public static final int accessibility_likes = 0x7f100001;
public static final int accessibility_reposts = 0x7f100002;
@@ -13113,7 +13113,7 @@ public class R{
public static final int x_stickers = 0x7f10010d;
}
public static final class raw{
public static final class raw {
public static final int amu_ballon_gx_prefix = 0x7f110000;
public static final int amu_basic_folder = 0x7f110001;
public static final int amu_basic_placemark = 0x7f110002;
@@ -13153,7 +13153,7 @@ public class R{
public static final int vklogo = 0x7f110024;
}
public static final class string{
public static final class string {
public static final int abc_action_bar_home_description = 0x7f120000;
public static final int abc_action_bar_up_description = 0x7f120001;
public static final int abc_action_menu_overflow_description = 0x7f120002;
@@ -18525,7 +18525,7 @@ public class R{
public static final int your_gender = 0x7f1214f8;
}
public static final class style{
public static final class style {
public static final int ActionBarGrayTheme = 0x7f130000;
public static final int ActionBarProgress = 0x7f130001;
public static final int ActionBarSpinner = 0x7f130002;
@@ -19662,7 +19662,7 @@ public class R{
public static final int Base_V28_Theme_AppCompat_Light = 0x7f1300a3;
}
public static final class xml{
public static final class xml {
public static final int account_preferences = 0x7f150000;
public static final int authenticator = 0x7f150001;
public static final int contacts_custom_type = 0x7f150002;
@@ -1,17 +1,15 @@
package com.vtosters.lite.ui.bottomnavigation;
import static ru.vtosters.lite.utils.Themes.getCSTDock;
import static ru.vtosters.lite.utils.ThemesUtils.getCSTDock;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -28,13 +26,10 @@ import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.view.ViewCompat;
import com.vk.core.ui.themes.Themable;
import com.vk.core.ui.themes.VKThemeHelper;
import com.vtosters.lite.R;
import me.grishka.appkit.utils.V;
import ru.vtosters.lite.utils.Globals;
import ru.vtosters.lite.utils.Themes;
public class BottomNavigationItemView extends FrameLayout implements MenuView.ItemView {
private final TextView mSmallLabel;
@@ -178,20 +173,20 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
counterContainerParams.topMargin = this.mMargin + V.a(1.5F);
counterContainerParams.bottomMargin = this.mMargin + V.a(1.5F);
this.mCounterContainer.setLayoutParams(counterContainerParams);
this.mCounterContainer.setTranslationY((float)(-V.a(5.5F)));
this.mCounterContainer.setTranslationY((float) (-V.a(5.5F)));
this.mLargeLabel.setVisibility(GONE);
this.mSmallLabel.setVisibility(GONE);
} else {
if (mShiftingModeEnabled) {
if (checked) {
var iconParams = (LayoutParams)this.mIcon.getLayoutParams();
iconParams.gravity = Gravity.TOP|Gravity.CENTER_HORIZONTAL;
var iconParams = (LayoutParams) this.mIcon.getLayoutParams();
iconParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
iconParams.topMargin = this.mMargin;
this.mIcon.setLayoutParams(iconParams);
var counterContainerParams = (LayoutParams)this.mCounterContainer.getLayoutParams();
counterContainerParams.gravity = Gravity.TOP|Gravity.CENTER_HORIZONTAL;
var counterContainerParams = (LayoutParams) this.mCounterContainer.getLayoutParams();
counterContainerParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
counterContainerParams.topMargin = this.mMargin + V.a(1.5F);
counterContainerParams.bottomMargin = this.mMargin + V.a(1.5F);
@@ -202,17 +197,17 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
ViewCompat.setScaleX(this.mLargeLabel, 1.0F);
ViewCompat.setScaleY(this.mLargeLabel, 1.0F);
} else {
var iconParams = (LayoutParams)this.mIcon.getLayoutParams();
var iconParams = (LayoutParams) this.mIcon.getLayoutParams();
iconParams.gravity = Gravity.CENTER;
iconParams.topMargin = this.mMargin;
this.mIcon.setLayoutParams(iconParams);
var counterContainerParams = (LayoutParams)this.mCounterContainer.getLayoutParams();
var counterContainerParams = (LayoutParams) this.mCounterContainer.getLayoutParams();
counterContainerParams.gravity = Gravity.CENTER;
counterContainerParams.topMargin = this.mMargin + V.a(1.5F);
counterContainerParams.bottomMargin = this.mMargin + V.a(1.5F);
this.mCounterContainer.setLayoutParams(counterContainerParams);
this.mCounterContainer.setTranslationY((float)(-V.a(5.5F)));
this.mCounterContainer.setTranslationY((float) (-V.a(5.5F)));
this.mLargeLabel.setVisibility(INVISIBLE);
ViewCompat.setScaleX(this.mLargeLabel, 0.5F);
@@ -241,7 +236,7 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
iconParams.bottomMargin = V.a(6);
this.mIcon.setLayoutParams(iconParams);
var counterContainerParams = (LayoutParams)this.mCounterContainer.getLayoutParams();
var counterContainerParams = (LayoutParams) this.mCounterContainer.getLayoutParams();
counterContainerParams.gravity = Gravity.CENTER;
counterContainerParams.topMargin = 0;
counterContainerParams.bottomMargin = V.a(8);
@@ -1,6 +1,6 @@
package ru.vtosters.lite.deviceinfo;
public class Device{
public class Device {
private String androidId;
private String bluetoothMac;
private String boardName;
@@ -16,81 +16,81 @@ public class Device{
private String serialId;
private String wifiMac;
public Device withSerialId(String str){
public Device withSerialId(String str) {
this.serialId = str;
return this;
}
public Device withAndroidId(String str){
public Device withAndroidId(String str) {
this.androidId = str;
return this;
}
public Device withWifiMac(String str){
public Device withWifiMac(String str) {
this.wifiMac = str;
return this;
}
public Device withBluetoothMac(String str){
public Device withBluetoothMac(String str) {
this.bluetoothMac = str;
return this;
}
public Device withSdkVersion(int i){
public Device withSdkVersion(int i) {
this.sdkVersion = i;
return this;
}
public Device withFirmwareId(String str){
public Device withFirmwareId(String str) {
this.firmwareId = str;
return this;
}
public Device withFirmwareDisplay(String str){
public Device withFirmwareDisplay(String str) {
this.firmwareDisplay = str;
return this;
}
public Device withProductName(String str){
public Device withProductName(String str) {
this.productName = str;
return this;
}
public Device withDeviceName(String str){
public Device withDeviceName(String str) {
this.deviceName = str;
return this;
}
public Device withBoardName(String str){
public Device withBoardName(String str) {
this.boardName = str;
return this;
}
public Device withCpuAbi(String str){
public Device withCpuAbi(String str) {
this.cpuAbi = str;
return this;
}
public Device withManufacturerName(String str){
public Device withManufacturerName(String str) {
this.manufacturerName = str;
return this;
}
public Device withBrandName(String str){
public Device withBrandName(String str) {
this.brandName = str;
return this;
}
public Device withModelName(String str){
public Device withModelName(String str) {
this.modelName = str;
return this;
}
public String toString(){
public String toString() {
return "Device{serialId='" + this.serialId + "', androidId='" + this.androidId + "', wifiMac='" + this.wifiMac + "', bluetoothMac='" + this.bluetoothMac + "'}";
}
public String toDeviceName(){
public String toDeviceName() {
return "Device{sdkVersion=" + this.sdkVersion + ", productName='" + this.productName + "', deviceName='" + this.deviceName + "', boardName='" + this.boardName + "', cpuAbi='" + this.cpuAbi + "', manufacturerName='" + this.manufacturerName + "', brandName='" + this.brandName + "', modelName='" + this.modelName + "'}";
}
}
@@ -18,14 +18,14 @@ import java.lang.reflect.Method;
import java.net.NetworkInterface;
import java.util.Collections;
public class DeviceInfoCollector{
public class DeviceInfoCollector {
private static final String TAG = "DeviceInfoCollector";
public Device collect(Context context){
public Device collect(Context context) {
return new Device().withSerialId(serialId()).withAndroidId(androidId(context)).withWifiMac(wifiMac(context)).withBluetoothMac(bluetoothMac(context)).withSdkVersion(Build.VERSION.SDK_INT).withFirmwareId(Build.ID).withFirmwareDisplay(Build.DISPLAY).withProductName(Build.PRODUCT).withDeviceName(Build.DEVICE).withBoardName(Build.BOARD).withCpuAbi(Build.CPU_ABI).withManufacturerName(Build.MANUFACTURER).withBrandName(Build.BRAND).withModelName(Build.MODEL);
}
private String serialId(){
private String serialId() {
String str;
try {
Class<?> cls = Class.forName("android.os.SystemProperties");
@@ -53,11 +53,11 @@ public class DeviceInfoCollector{
return null;
}
private String androidId(Context context){
private String androidId(Context context) {
return Settings.Secure.getString(context.getContentResolver(), "android_id").toLowerCase();
}
private String wifiMac(Context context){
private String wifiMac(Context context) {
String wifiMacFromManager = wifiMacFromManager(context);
if (isInvalidMac(wifiMacFromManager)) {
wifiMacFromManager = wifiMacFromNetworkInterfaces();
@@ -74,7 +74,7 @@ public class DeviceInfoCollector{
return null;
}
private String wifiMacFromManager(Context context){
private String wifiMacFromManager(Context context) {
WifiInfo connectionInfo;
try {
WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
@@ -88,7 +88,7 @@ public class DeviceInfoCollector{
}
}
private String wifiMacFromNetworkInterfaces(){
private String wifiMacFromNetworkInterfaces() {
try {
for (NetworkInterface networkInterface : Collections.list(NetworkInterface.getNetworkInterfaces())) {
if ("wlan0".equalsIgnoreCase(networkInterface.getName())) {
@@ -114,7 +114,7 @@ public class DeviceInfoCollector{
}
}
private String wifiMacFromFileSystem(){
private String wifiMacFromFileSystem() {
try {
FileReader fileReader = new FileReader("/sys/class/net/wlan0/address");
try {
@@ -137,7 +137,7 @@ public class DeviceInfoCollector{
return null;
}
private String bluetoothMac(Context context){
private String bluetoothMac(Context context) {
String bluetoothMacFromAdapter = bluetoothMacFromAdapter();
if (isInvalidMac(bluetoothMacFromAdapter)) {
bluetoothMacFromAdapter = bluetoothMacFromContentResolver(context);
@@ -151,7 +151,7 @@ public class DeviceInfoCollector{
return null;
}
private String bluetoothMacFromAdapter(){
private String bluetoothMacFromAdapter() {
try {
BluetoothAdapter defaultAdapter = BluetoothAdapter.getDefaultAdapter();
if (defaultAdapter == null) {
@@ -173,7 +173,7 @@ public class DeviceInfoCollector{
}
}
private String bluetoothMacFromContentResolver(Context context){
private String bluetoothMacFromContentResolver(Context context) {
try {
return Settings.Secure.getString(context.getContentResolver(), "bluetooth_address");
} catch (Exception e) {
@@ -182,11 +182,11 @@ public class DeviceInfoCollector{
}
}
private boolean isInvalidSerial(String str){
private boolean isInvalidSerial(String str) {
return TextUtils.isEmpty(str) || EnvironmentCompat.MEDIA_UNKNOWN.equalsIgnoreCase(str);
}
private boolean isInvalidMac(String str){
private boolean isInvalidMac(String str) {
return TextUtils.isEmpty(str) || "02:00:00:00:00:00".equalsIgnoreCase(str) || "00:00:00:00:00:00".equalsIgnoreCase(str);
}
}
@@ -1,4 +1,4 @@
package ru.vtosters.lite.utils;
package ru.vtosters.lite.deviceinfo;
import android.text.TextUtils;
@@ -6,36 +6,36 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class OEMDetector{
public static boolean isOEM(){
public class OEMDetector {
public static boolean isOEM() {
return isMIUI() || isEMUI() || isFlyme() || isZenUI() || isSamsung() || isVivo();
}
private static boolean isMIUI(){
private static boolean isMIUI() {
return !TextUtils.isEmpty(getSystemProperty("ro.miui.ui.version.name"));
}
private static boolean isEMUI(){
private static boolean isEMUI() {
return !TextUtils.isEmpty(getSystemProperty("ro.build.hw_emui_api_level"));
}
private static boolean isZenUI(){
private static boolean isZenUI() {
return !TextUtils.isEmpty(getSystemProperty("ro.asus.ui"));
}
private static boolean isVivo(){
private static boolean isVivo() {
return !TextUtils.isEmpty(getSystemProperty("ro.vivo.os.version")) || !TextUtils.isEmpty(getSystemProperty("ro.vivo.rom")) || !TextUtils.isEmpty(getSystemProperty("ro.vivo.rom.version")) || !TextUtils.isEmpty(getSystemProperty("ro.vivo.build.version.sdk"));
}
private static boolean isSamsung(){
private static boolean isSamsung() {
return !TextUtils.isEmpty(getSystemProperty("ro.config.knox"));
}
private static boolean isFlyme(){
private static boolean isFlyme() {
return !TextUtils.isEmpty(getSystemProperty("ro.build.ro.meizu.rom.config")) || !TextUtils.isEmpty(getSystemProperty("persist.sys.static_blur_mode")) || !TextUtils.isEmpty(getSystemProperty("persist.sys.use.flyme.icon"));
}
private static String getSystemProperty(String str){
private static String getSystemProperty(String str) {
BufferedReader bufferedReader;
try {
bufferedReader = new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec("getprop " + str).getInputStream()), 1024);
@@ -4,19 +4,37 @@ import static ru.vtosters.lite.dnr.DNRModule.hookDNR;
import static ru.vtosters.lite.dnr.DNRModule.hookDNT;
import static ru.vtosters.lite.dnr.DNRModule.isDnrEnabledFor;
import static ru.vtosters.lite.dnr.DNRModule.isDntEnabledFor;
import static ru.vtosters.lite.utils.Globals.getIdentifier;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
import com.vk.core.util.ToastUtils;
import android.content.Context;
import android.util.Log;
import com.vk.core.network.Network;
import com.vk.im.engine.models.dialogs.Dialog;
import com.vk.im.engine.models.messages.Msg;
import com.vk.im.engine.models.messages.MsgFromUser;
import com.vk.im.ui.components.common.DialogAction;
import com.vk.im.ui.components.common.MsgAction;
import com.vk.im.ui.components.viewcontrollers.popup.DelegateMsg;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;
public class DNRInjector{
public static void inject(Dialog dialog, List<DialogAction> list){
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import ru.vtosters.lite.ui.dialogs.Translate;
public class DNRInjector {
public static void inject(Dialog dialog, List<DialogAction> list) {
int peerId = dialog.getId();
list.add(DialogAction.valueOf("pinmsg"));
list.add(DialogAction.valueOf("unpinmsg"));
if (isDnrEnabledFor(peerId)) {
list.add(DialogAction.valueOf("DNR_OFF"));
} else {
@@ -30,15 +48,19 @@ public class DNRInjector{
}
}
public static LinkedHashMap<DialogAction, Integer> injectToHashMap(LinkedHashMap<DialogAction, Integer> hashMap){
public static LinkedHashMap<DialogAction, Integer> injectToHashMap(LinkedHashMap<DialogAction, Integer> hashMap) {
hashMap.put(DialogAction.valueOf("DNR_ON"), getIdentifier("DNR_ON", "string"));
hashMap.put(DialogAction.valueOf("DNR_OFF"), getIdentifier("DNR_OFF", "string"));
hashMap.put(DialogAction.valueOf("DNT_ON"), getIdentifier("DNT_ON", "string"));
hashMap.put(DialogAction.valueOf("DNT_OFF"), getIdentifier("DNT_OFF", "string"));
// hashMap.put(DialogAction.valueOf("pinmsg"), getIdentifier("pinmsg", "string"));
// hashMap.put(DialogAction.valueOf("unpinmsg"), getIdentifier("unpinmsg", "string"));
return hashMap;
}
public static boolean onClick(Dialog dialog, DialogAction action){
public static boolean onClick(Dialog dialog, DialogAction action) {
var id = dialog.getId();
if (action == DialogAction.valueOf("MARK_AS_READ")) {
@@ -61,14 +83,80 @@ public class DNRInjector{
return true;
}
if (action == DialogAction.valueOf("pinmsg")) {
pinnedMsg(id, true);
return true;
} else if (action == DialogAction.valueOf("unpinmsg")) {
pinnedMsg(id, false);
return true;
}
return false;
}
public static void setDnr(Dialog dialog, boolean value){
public static LinkedHashMap<MsgAction, DelegateMsg.a.a> injectToHashMapMsg(LinkedHashMap<MsgAction, DelegateMsg.a.a> hashMap) {
hashMap.put(MsgAction.valueOf("TRANSLATE"), new DelegateMsg.a.a(getIdentifier("translator", "string")));
hashMap.put(MsgAction.valueOf("READTO"), new DelegateMsg.a.a(getIdentifier("readto", "string")));
return hashMap;
}
public static boolean onClickMsg(Context context, MsgAction action, Msg msg) {
var text = ((MsgFromUser) msg).f();
var fullMsg = ((MsgFromUser) msg).j2(); // text + reply
var reply = fullMsg.substring(text.length() + 1);
if (action == MsgAction.valueOf("READTO")) {
DNRModule.hookReadStartMsgTo(msg);
return true;
}
var isTextExist = !text.isEmpty() && !text.equals(" ");
var isReplyExist = !reply.isEmpty() && !reply.equals(" ");
if (action == MsgAction.valueOf("TRANSLATE")) {
if (isTextExist && isReplyExist) {
Translate.showTranslatedText(context, text + "\n\nРеплай:\n" + reply);
} else if (isReplyExist) {
Translate.showTranslatedText(context, "Реплай:\n" + reply);
} else if (isTextExist) {
Translate.showTranslatedText(context, text);
} else {
sendToast("Нет текста для перевода");
}
}
return false;
}
public static void pinnedMsg(int dialogid, boolean needToBePinned) {
Thread thread = new Thread(() -> {
try {
var request = new Request.a()
.b("https://api.vk.com/method/" + (needToBePinned ? "messages.pinConversation" : "messages.unpinConversation") + "?peer_id=" + dialogid + "&access_token=" + getUserToken() + "&v=5.119")
.a(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8"))
.a();
try {
var response = new OkHttpClient().a(request).execute().a().g();
Log.d("Pins", response);
} catch (IOException e) {
Log.e("Pins", "Error while pinning message", e);
}
} catch (Exception e) {
e.printStackTrace();
}
});
thread.start();
sendToast("Диалог успешно " + (needToBePinned ? "закреплен" : "откреплен"));
}
public static void setDnr(Dialog dialog, boolean value) {
hookDNR(dialog.getId());
}
public static void setDnt(Dialog dialog, boolean value){
public static void setDnt(Dialog dialog, boolean value) {
hookDNT(dialog.getId());
}
}
@@ -1,65 +1,73 @@
package ru.vtosters.lite.dnr;
import static ru.vtosters.lite.net.Request.makeRequest;
import static ru.vtosters.lite.utils.Globals.getUserToken;
import static ru.vtosters.lite.utils.Proxy.getApi;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
import static ru.vtosters.lite.utils.ProxyUtils.getApi;
import android.util.Log;
import com.vk.core.util.ToastUtils;
import com.vk.im.engine.commands.messages.SetUserActivityCmd;
import com.vk.im.engine.models.dialogs.Dialog;
import com.vk.im.engine.models.messages.Msg;
import java.util.List;
import ru.vtosters.lite.dnr.helpers.DoNotReadDBHelper;
import ru.vtosters.lite.dnr.helpers.DoNotTypeDBHelper;
public class DNRModule{
public class DNRModule {
public static DoNotReadDBHelper mDoNotReadDBHelper = new DoNotReadDBHelper();
public static DoNotTypeDBHelper mDoNotTypeDBHelper = new DoNotTypeDBHelper();
public static Dialog mDialog;
public static boolean isDnrEnabledFor(int id){
public static boolean isDnrEnabledFor(int id) {
var isEnabled = mDoNotReadDBHelper.isEnabledForPeerId(id);
return isEnabled;
}
public static List<Integer> getDnrEnabled(){
public static List<Integer> getDnrEnabled() {
return mDoNotReadDBHelper.get();
}
public static List<Integer> getDntEnabled(){
public static List<Integer> getDntEnabled() {
return mDoNotTypeDBHelper.get();
}
public static boolean isDntEnabledFor(int id){
public static boolean isDntEnabledFor(int id) {
var isEnabled = mDoNotTypeDBHelper.isEnabledForPeerId(id);
return isEnabled;
}
public static boolean isDntEnabledFor(SetUserActivityCmd cmd){
public static boolean isDntEnabledFor(SetUserActivityCmd cmd) {
return isDntEnabledFor(cmd.b);
}
public static boolean isDnrEnabledFor(Dialog dialog){
public static boolean isDnrEnabledFor(Dialog dialog) {
if (dialog == null) return false;
return isDnrEnabledFor(dialog.getId());
}
public static boolean isDntEnabledFor(Dialog dialog){
public static boolean isDntEnabledFor(Dialog dialog) {
if (dialog == null) return false;
return isDntEnabledFor(dialog.getId());
}
public static void hookRead(Dialog dialog){
public static void hookRead(Dialog dialog) {
makeRequest("https://" + getApi() + "/method/messages.markAsRead?start_message_id=" + dialog.F1() + "&peer_id=" + dialog.getId() + "&v=5.119&access_token=" + getUserToken(), response -> {
});
}
public static void hookDNR(int peerId){
public static void hookReadStartMsgTo(Msg dialog) {
Log.d("DNR", "hookReadStartMsgTo: " + dialog.C1() + " " + dialog.v1());
makeRequest("https://" + getApi() + "/method/messages.markAsRead?start_message_id=" + dialog.C1() + "&peer_id=" + dialog.v1() + "&v=5.119&access_token=" + getUserToken(), response -> {
});
}
public static void hookDNR(int peerId) {
mDoNotReadDBHelper.setEnabledForPeerId(peerId, !mDoNotReadDBHelper.isEnabledForPeerId(peerId));
}
public static void hookDNT(int peerId){
public static void hookDNT(int peerId) {
mDoNotTypeDBHelper.setEnabledForPeerId(peerId, !mDoNotTypeDBHelper.isEnabledForPeerId(peerId));
}
}
@@ -2,16 +2,16 @@ package ru.vtosters.lite.dnr;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
public class DNRPrefs{
public static boolean getStoriesRead(){
public class DNRPrefs {
public static boolean getStoriesRead() {
return getBoolValue("read_s", false);
}
public static boolean getVoiceListened(){
public static boolean getVoiceListened() {
return getBoolValue("listen_v", false);
}
public static boolean getMarkAsReadWithoutExceptions(int peerId){
public static boolean getMarkAsReadWithoutExceptions(int peerId) {
if (readPM(peerId))
return true;
if (readConversations(peerId))
@@ -19,43 +19,43 @@ public class DNRPrefs{
return readBots(peerId);
}
public static boolean getMarkAsRead(int peerId){
public static boolean getMarkAsRead(int peerId) {
return isInDNRExceptions(peerId);
}
public static boolean isInDNRExceptions(int peerId){
public static boolean isInDNRExceptions(int peerId) {
return DNRModule.mDoNotReadDBHelper.isEnabledForPeerId(peerId);
}
public static boolean isInDNTExceptions(int peerId){
public static boolean isInDNTExceptions(int peerId) {
return DNRModule.mDoNotTypeDBHelper.isEnabledForPeerId(peerId);
}
public static boolean readPM(int peer){
public static boolean readPM(int peer) {
return (peer > 0 && peer < 2000000000) && getBoolValue("read_pm", false);
}
public static boolean readConversations(int peer){
public static boolean readConversations(int peer) {
return (peer > 2000000000) && getBoolValue("read_conversations", false);
}
public static boolean readBots(int peer){
public static boolean readBots(int peer) {
return (peer < 0) && getBoolValue("read_bot", false);
}
public static boolean writePM(int peer){
public static boolean writePM(int peer) {
return (peer > 0 && peer < 2000000000) && getBoolValue("write_pm", false);
}
public static boolean writeConversations(int peer){
public static boolean writeConversations(int peer) {
return (peer > 2000000000) && getBoolValue("write_conversations", false);
}
public static boolean writeBots(int peer){
public static boolean writeBots(int peer) {
return (peer < 0) && getBoolValue("write_bot", false);
}
public static boolean getActivityWithoutExceptions(int peerId){
public static boolean getActivityWithoutExceptions(int peerId) {
if (writePM(peerId))
return true;
if (writeConversations(peerId))
@@ -63,7 +63,7 @@ public class DNRPrefs{
return writeBots(peerId);
}
public static boolean getActivity(int peerId){
public static boolean getActivity(int peerId) {
return isInDNTExceptions(peerId);
}
}
@@ -1,6 +1,6 @@
package ru.vtosters.lite.dnr.helpers;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import android.content.ContentValues;
import android.database.Cursor;
@@ -12,22 +12,22 @@ import java.util.List;
import ru.vtosters.lite.dnr.DNRPrefs;
public class DoNotReadDBHelper extends SQLiteOpenHelper{
public DoNotReadDBHelper(){
super(getContext(), "dnr", null, 1);
public class DoNotReadDBHelper extends SQLiteOpenHelper {
public DoNotReadDBHelper() {
super(getGlobalContext(), "dnr", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db){
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table dnr (peerId integer primary key, enabled integer)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public boolean isEnabledForPeerId(int peerId){
public boolean isEnabledForPeerId(int peerId) {
try (Cursor c = getReadableDatabase().query("dnr", null, null, null, null, null, null)) {
if (c.moveToFirst()) {
int peerIdIndex = c.getColumnIndex("peerId");
@@ -36,7 +36,7 @@ public class DoNotReadDBHelper extends SQLiteOpenHelper{
do {
if (c.getInt(peerIdIndex) == peerId)
return c.getInt(enabledIndex) == 1;
} while(c.moveToNext());
} while (c.moveToNext());
}
} catch (Exception e) {
e.printStackTrace();
@@ -45,7 +45,7 @@ public class DoNotReadDBHelper extends SQLiteOpenHelper{
return DNRPrefs.getMarkAsReadWithoutExceptions(peerId);
}
public List<Integer> get(){
public List<Integer> get() {
ArrayList<Integer> rs = new ArrayList<>();
try (Cursor c = getReadableDatabase().query("dnr", null, null, null, null, null, null)) {
@@ -57,7 +57,7 @@ public class DoNotReadDBHelper extends SQLiteOpenHelper{
if (c.getInt(enabledIndex) == 1) {
rs.add(c.getInt(peerIdIndex));
}
} while(c.moveToNext());
} while (c.moveToNext());
}
} catch (Exception e) {
e.printStackTrace();
@@ -66,7 +66,7 @@ public class DoNotReadDBHelper extends SQLiteOpenHelper{
return rs;
}
public void setEnabledForPeerId(int peerId, boolean enabled){
public void setEnabledForPeerId(int peerId, boolean enabled) {
ContentValues cv = new ContentValues();
cv.put("enabled", enabled ? 1 : 0);
@@ -1,6 +1,6 @@
package ru.vtosters.lite.dnr.helpers;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import android.content.ContentValues;
import android.database.Cursor;
@@ -12,22 +12,22 @@ import java.util.List;
import ru.vtosters.lite.dnr.DNRPrefs;
public class DoNotTypeDBHelper extends SQLiteOpenHelper{
public DoNotTypeDBHelper(){
super(getContext(), "dnt", null, 1);
public class DoNotTypeDBHelper extends SQLiteOpenHelper {
public DoNotTypeDBHelper() {
super(getGlobalContext(), "dnt", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db){
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table dnt (peerId integer primary key, enabled integer)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public List<Integer> get(){
public List<Integer> get() {
ArrayList<Integer> rs = new ArrayList<>();
try (Cursor c = getReadableDatabase().query("dnt", null, null, null, null, null, null)) {
@@ -39,7 +39,7 @@ public class DoNotTypeDBHelper extends SQLiteOpenHelper{
if (c.getInt(enabledIndex) == 1) {
rs.add(c.getInt(peerIdIndex));
}
} while(c.moveToNext());
} while (c.moveToNext());
}
} catch (Exception e) {
e.printStackTrace();
@@ -48,7 +48,7 @@ public class DoNotTypeDBHelper extends SQLiteOpenHelper{
return rs;
}
public boolean isEnabledForPeerId(int peerId){
public boolean isEnabledForPeerId(int peerId) {
try (Cursor c = getReadableDatabase().query("dnt", null, null, null, null, null, null)) {
if (c.moveToFirst()) {
int peerIdIndex = c.getColumnIndex("peerId");
@@ -57,7 +57,7 @@ public class DoNotTypeDBHelper extends SQLiteOpenHelper{
do {
if (c.getInt(peerIdIndex) == peerId)
return c.getInt(enabledIndex) == 1;
} while(c.moveToNext());
} while (c.moveToNext());
}
} catch (Exception e) {
e.printStackTrace();
@@ -66,7 +66,7 @@ public class DoNotTypeDBHelper extends SQLiteOpenHelper{
return DNRPrefs.getActivityWithoutExceptions(peerId);
}
public void setEnabledForPeerId(int peerId, boolean enabled){
public void setEnabledForPeerId(int peerId, boolean enabled) {
ContentValues cv = new ContentValues();
cv.put("enabled", enabled ? 1 : 0);
@@ -16,13 +16,13 @@ import ru.vtosters.lite.music.Callback;
import ru.vtosters.lite.music.FFMpeg;
import ru.vtosters.lite.music.M3UDownloader;
import ru.vtosters.lite.music.MP3Downloader;
import ru.vtosters.lite.utils.Globals;
import ru.vtosters.lite.utils.AndroidUtils;
public class AudioDownloader {
private static NotificationManagerCompat notificationManager = NotificationManagerCompat.from(Globals.getContext());
private static NotificationManagerCompat notificationManager = NotificationManagerCompat.from(AndroidUtils.getGlobalContext());
public static void downloadAudio(MusicTrack track) {
if (Globals.getDefprefs().getBoolean("new_music_downloading_way", false)) {
if (AndroidUtils.getDefaultPrefs().getBoolean("new_music_downloading_way", false)) {
downloadMP3(track);
} else {
downloadM3U8(track);
@@ -36,6 +36,16 @@ public class AudioDownloader {
}
var musicPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath();
var musicDir = new File(musicPath);
if (!musicDir.exists()) {
if (musicDir.mkdirs()) {
Log.d("AudioDownloader", "Created music dir");
} else {
Log.e("AudioDownloader", "Failed to create music dir");
return;
}
}
var tempId = track.d;
var downloadPath = musicPath + File.separator + tempId;
@@ -89,15 +99,15 @@ public class AudioDownloader {
else
Log.e("AudioDownloader", "Directory creation failed");
Log.i("AudioDownloader", "Downloading audio to " + path);
new M3UDownloader(track.D, outDir, callback).execute();
M3UDownloader.execute(track.D, outDir, callback);
}
private static void downloadMP3(MusicTrack track) {
new MP3Downloader().execute(track);
MP3Downloader.execute(track);
}
private static NotificationCompat.Builder buildDownloadNotification(MusicTrack track, int id) {
var notificationBuilder = new NotificationCompat.Builder(Globals.getContext(), NotificationChannels.MUSIC_DOWNLOAD_CHANNEL_ID)
var notificationBuilder = new NotificationCompat.Builder(AndroidUtils.getGlobalContext(), NotificationChannels.MUSIC_DOWNLOAD_CHANNEL_ID)
.setSmallIcon(android.R.drawable.stat_sys_download)
.setContentTitle("Загрузка аудиозаписи")
.setContentText(track.toString())
@@ -1,6 +1,6 @@
package ru.vtosters.lite.downloaders;
import static ru.vtosters.lite.utils.Globals.getString;
import static ru.vtosters.lite.utils.AndroidUtils.getString;
import android.annotation.SuppressLint;
import android.app.DownloadManager;
@@ -15,13 +15,13 @@ import java.io.File;
import b.h.g.m.FileUtils;
import ru.vtosters.lite.ui.activities.APKInstallActivity;
import ru.vtosters.lite.utils.Globals;
import ru.vtosters.lite.utils.AndroidUtils;
public class OTADownloader{
public class OTADownloader {
private static final BroadcastReceiver callback = new BroadcastReceiver(){
private static final BroadcastReceiver callback = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent){
public void onReceive(Context context, Intent intent) {
var extras = intent.getExtras();
if (extras == null || !intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
return;
@@ -29,7 +29,7 @@ public class OTADownloader{
var query = new DownloadManager.Query();
var id = extras.getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
query.setFilterById(id);
var manager = (DownloadManager) Globals.getContext().getSystemService(Context.DOWNLOAD_SERVICE);
var manager = (DownloadManager) AndroidUtils.getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE);
var cursor = manager.query(query);
if (cursor.moveToFirst()) {
@SuppressLint("Range") var status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
@@ -48,14 +48,14 @@ public class OTADownloader{
File apk = maxIndex == -1 ? new File(downloadDir, "VTLite.apk") : new File(downloadDir, "VTLite-" + maxIndex + ".apk");
APKInstallActivity.installOta(context, FileUtils.n(apk));
} else if (status == DownloadManager.STATUS_FAILED) {
Globals.sendToast(getString("downloaderr"));
AndroidUtils.sendToast(getString("downloaderr"));
}
}
}
};
public static void downloadBuild(String url){
var context = Globals.getContext();
public static void downloadBuild(String url) {
var context = AndroidUtils.getGlobalContext();
var uri = Uri.parse(url);
context.registerReceiver(callback, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
@@ -65,7 +65,7 @@ public class OTADownloader{
request.setTitle("VTLite.apk");
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "VTLite.apk");
var manager = (DownloadManager) Globals.getContext().getSystemService(Context.DOWNLOAD_SERVICE);
var manager = (DownloadManager) AndroidUtils.getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
}
}
@@ -1,6 +1,8 @@
package ru.vtosters.lite.downloaders;
import static ru.vtosters.lite.downloaders.VideoDownloader.downloadVideo;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.Preferences.getPhotosDir;
import android.app.DownloadManager;
import android.content.Context;
@@ -12,8 +14,8 @@ import com.vk.dto.stories.model.StoryEntry;
import java.util.List;
public class StoryDownloader{
public static Runnable injectButton(StoryEntry story){
public class StoryDownloader {
public static Runnable injectButton(StoryEntry story) {
return () -> {
// if story is a pic
if (story.T1()) {
@@ -22,8 +24,8 @@ public class StoryDownloader{
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle("photo" + story.E.a);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DCIM, "/Stories/photo" + story.E.a + ".jpg");
((DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
request.setDestinationInExternalPublicDir(getPhotosDir().getAbsolutePath(), "/Stories/photo" + story.E.a + ".jpg");
((DownloadManager) getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
return;
}
@@ -1,10 +1,11 @@
package ru.vtosters.lite.downloaders;
import static ru.vtosters.lite.net.Request.makeRequest;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.Globals.getIdentifier;
import static ru.vtosters.lite.utils.Globals.getString;
import static ru.vtosters.lite.utils.Globals.getUserToken;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.getString;
import static ru.vtosters.lite.utils.Preferences.getVideosDir;
import android.app.AlertDialog;
import android.app.DownloadManager;
@@ -27,23 +28,23 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import ru.vtosters.lite.utils.ExternalLinkHandler;
import ru.vtosters.lite.utils.ExternalLinkParser;
public class VideoDownloader{
public class VideoDownloader {
private static final int DOWNLOAD_ID = 0;
private static final int OPEN_EXTERNAL_LINK_ID = 1;
public static boolean onClick(int id, VideoFile video, Context ctx){
public static boolean onClick(int id, VideoFile video, Context ctx) {
if (id == DOWNLOAD_ID) {
downloadVideo(video, ctx);
return true;
} else if (id == OPEN_EXTERNAL_LINK_ID) {
ExternalLinkHandler.parseVideoFile(video, ctx, true);
ExternalLinkParser.parseVideoFile(video, ctx, true);
}
return false;
}
public static void injectAction(ArrayList<MenuBottomSheetAction> list, VideoFile video){
public static void injectAction(ArrayList<MenuBottomSheetAction> list, VideoFile video) {
if (!video.U && !video.I1()) {
addAction(list, DOWNLOAD_ID, R.drawable.ic_download_outline_24, R.string.download, 9);
addAction(list, OPEN_EXTERNAL_LINK_ID, R.drawable.ic_link_outline_28, getIdentifier("interfacevideoext_short", "string"), 9);
@@ -54,7 +55,7 @@ public class VideoDownloader{
actions.add(new MenuBottomSheetAction(ints[0], ints[1], ints[2], ints[3]));
}
public static void downloadVideo(VideoFile videoFile, Context context){
public static void downloadVideo(VideoFile videoFile, Context context) {
final List<String> list = new ArrayList<>();
final List<String> urls = new ArrayList<>();
@@ -104,8 +105,8 @@ public class VideoDownloader{
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle(videoFile.toString());
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_MOVIES, videoFile + ".mp4");
((DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
request.setDestinationInExternalPublicDir(getVideosDir().getAbsolutePath(), videoFile + ".mp4");
((DownloadManager) getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
return;
}
@@ -115,13 +116,13 @@ public class VideoDownloader{
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle(videoFile.toString());
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_MOVIES, videoFile + ".mp4");
request.setDestinationInExternalPublicDir(getVideosDir().getAbsolutePath(), videoFile + ".mp4");
((DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
}));
builder.show();
}
public static void parseVideoLink(String url, Context ctx){
public static void parseVideoLink(String url, Context ctx) {
if (url.contains("vk.com/story")) {
ToastUtils.a("Не поддерживается загрузка историй");
return;
@@ -8,7 +8,7 @@ import android.os.Build;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationManagerCompat;
import ru.vtosters.lite.utils.Globals;
import ru.vtosters.lite.utils.AndroidUtils;
public class NotificationChannels {
public static final String MUSIC_DOWNLOAD_CHANNEL_ID = "music_download_channel";
@@ -26,7 +26,7 @@ public class NotificationChannels {
musicDownloadChannel.setDescription(MUSIC_DOWNLOAD_CHANNEL_DESCRIPTION);
musicDownloadChannel.setShowBadge(true);
musicDownloadChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
var notificationManager = NotificationManagerCompat.from(Globals.getContext());
var notificationManager = NotificationManagerCompat.from(AndroidUtils.getGlobalContext());
notificationManager.createNotificationChannel(musicDownloadChannel);
}
}
@@ -19,10 +19,10 @@ import ru.vtosters.lite.encryption.processors.MP3InvisibleProcessor;
import ru.vtosters.lite.encryption.processors.VTostersAESProcessor;
import ru.vtosters.lite.encryption.processors.VTostersProcessor;
public class EncryptProvider{
public class EncryptProvider {
public static List<IMProcessor> processors = new ArrayList<>();
static{
static {
processors.add(new VTostersProcessor());
processors.add(new VTostersAESProcessor());
processors.add(new DefaultCoffeeProcessor());
@@ -31,7 +31,7 @@ public class EncryptProvider{
processors.add(new MP3InvisibleProcessor());
}
public static IMProcessor getProcessorFor(int peerId){
public static IMProcessor getProcessorFor(int peerId) {
IMProcessor enabled = null;
for (IMProcessor processor : EncryptProvider.processors) {
if (processor.isUsedToEncrypt(peerId)) {
@@ -41,20 +41,20 @@ public class EncryptProvider{
return enabled;
}
public static String getBody(MsgFromUser msg){
public static String getBody(MsgFromUser msg) {
return msg.f();
}
public static int getPeerId(Msg msg){
public static int getPeerId(Msg msg) {
return msg.v1();
}
// This will run through EVERY single processor available.
public static String decryptMessage(MsgFromUser msg){
public static String decryptMessage(MsgFromUser msg) {
return decryptMessage(getBody(msg), getPeerId(msg));
}
public static String decryptMessage(String msgBody, int peer){
public static String decryptMessage(String msgBody, int peer) {
try {
for (IMProcessor processor : processors) {
if ((processor.isUsed() || !processor.isPublic()) && processor.isEncrypted(msgBody) && (processor.isPublic() || getKeyForProcessor(processor, peer) != null))
@@ -66,7 +66,7 @@ public class EncryptProvider{
return msgBody;
}
private static byte[] getKeyForProcessor(IMProcessor processor, int peer){
private static byte[] getKeyForProcessor(IMProcessor processor, int peer) {
if (processor.isPublic()) return null;
String keyString = processor.getEncryptionKeyFor(peer);
if (keyString == null) return null;
@@ -85,7 +85,7 @@ public class EncryptProvider{
}
// This will use only the processor which was chosen in chat menu [that's why ID is needed, bruh]
public static String encryptMessage(MsgFromUser msg){
public static String encryptMessage(MsgFromUser msg) {
String msgBody = getBody(msg);
@@ -104,7 +104,7 @@ public class EncryptProvider{
}
// For rendering UI
public static List<Pair<String, String>> getUserVisibleEncoders(){
public static List<Pair<String, String>> getUserVisibleEncoders() {
List<Pair<String, String>> theList = new ArrayList<>();
for (IMProcessor processor : processors) {
@@ -5,11 +5,11 @@ import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import ru.vtosters.lite.utils.Globals;
import ru.vtosters.lite.utils.AndroidUtils;
public abstract class IMProcessor{
public abstract class IMProcessor {
// By default it checks start and end tag.
public boolean isEncrypted(String source){
public boolean isEncrypted(String source) {
//Log.d("IMProcessor", "Checking if encrypted: "+source+" / "+getUIName());
return source.startsWith(startTag()) && source.endsWith(endTag());
}
@@ -23,19 +23,19 @@ public abstract class IMProcessor{
// Automatically removes tags. Magic!
@NonNull
public String encode(@NonNull String source, @Nullable byte[] key){
public String encode(@NonNull String source, @Nullable byte[] key) {
//Log.d("IMProcessor", "Encoding "+source);
return startTag() + encodeInternal(source, key) + endTag();
}
@NonNull
public String decode(@NonNull String source, @Nullable byte[] key){
public String decode(@NonNull String source, @Nullable byte[] key) {
//Log.d("IMProcessor", "Decoding");
return decodeInternal(source.substring(startTag().length(), source.length() - endTag().length()), key);
}
// Public - no key required.
public boolean isPublic(){
public boolean isPublic() {
return true;
}
@@ -47,40 +47,40 @@ public abstract class IMProcessor{
abstract public String getPrefKey();
@NonNull
public String startTag(){
public String startTag() {
return "";
}
@NonNull
public String endTag(){
public String endTag() {
return "";
}
public boolean isUsed(){
public boolean isUsed() {
//Log.d("IMProcessor", "Checking if decoded with "+getUIName());
return getBoolValue("VT_IMDecode_" + getPrefKey(), true);
}
public boolean isUsedToEncrypt(int id){
public boolean isUsedToEncrypt(int id) {
//Log.d("IMProcessor", "Checking if "+id+" is ready to be encrypted with "+getUIName());
return getBoolValue("VT_IMEncode_" + getPrefKey() + "_" + id, false);
}
public void enableEncryptFor(int id){
Globals.getDefprefs().edit().putBoolean("VT_IMEncode_" + getPrefKey() + "_" + id, true).apply();
public void enableEncryptFor(int id) {
AndroidUtils.getDefaultPrefs().edit().putBoolean("VT_IMEncode_" + getPrefKey() + "_" + id, true).apply();
}
public void disableEncryptFor(int id){
Globals.getDefprefs().edit().putBoolean("VT_IMEncode_" + getPrefKey() + "_" + id, false).apply();
public void disableEncryptFor(int id) {
AndroidUtils.getDefaultPrefs().edit().putBoolean("VT_IMEncode_" + getPrefKey() + "_" + id, false).apply();
}
public void setEncryptionKeyFor(int id, @Nullable String key){
public void setEncryptionKeyFor(int id, @Nullable String key) {
if (key == null || key.isEmpty()) key = "VTAesDefault";
Globals.getDefprefs().edit().putString("VT_IMEncodeKey_" + getPrefKey() + "_" + id, key).apply();
AndroidUtils.getDefaultPrefs().edit().putString("VT_IMEncodeKey_" + getPrefKey() + "_" + id, key).apply();
}
@Nullable
public String getEncryptionKeyFor(int id){
return Globals.getDefprefs().getString("VT_IMEncodeKey_" + getPrefKey() + "_" + id, null);
public String getEncryptionKeyFor(int id) {
return AndroidUtils.getDefaultPrefs().getString("VT_IMEncodeKey_" + getPrefKey() + "_" + id, null);
}
}
@@ -9,12 +9,12 @@ import java.nio.charset.StandardCharsets;
import ru.vtosters.lite.encryption.base.IMProcessor;
public class BeeCryptProcessor extends IMProcessor{
public class BeeCryptProcessor extends IMProcessor {
private static final String BC_CHARSET = "жъЖЪ";
@NonNull
@Override
protected String encodeInternal(@NonNull String source, @Nullable byte[] key){
protected String encodeInternal(@NonNull String source, @Nullable byte[] key) {
try {
String a = Base64.encodeToString(source.getBytes(StandardCharsets.UTF_8), 2);
StringBuilder res = new StringBuilder();
@@ -35,16 +35,16 @@ public class BeeCryptProcessor extends IMProcessor{
}
@Override
public boolean isEncrypted(String source){
public boolean isEncrypted(String source) {
return source.matches("[жъЖЪ]{16,}");
}
@NonNull
@Override
protected String decodeInternal(@NonNull String source, @Nullable byte[] key){
protected String decodeInternal(@NonNull String source, @Nullable byte[] key) {
StringBuilder b64 = new StringBuilder();
int i = 0;
while(i < source.length() - 3) {
while (i < source.length() - 3) {
try {
String bintxt = source.substring(i, i + 4);
int c = 0;
@@ -63,13 +63,13 @@ public class BeeCryptProcessor extends IMProcessor{
@NonNull
@Override
public String getUIName(){
public String getUIName() {
return "MP3 [beecrypt]";
}
@NonNull
@Override
public String getPrefKey(){
public String getPrefKey() {
return "mp3_bc";
}
}
@@ -10,11 +10,11 @@ import javax.crypto.spec.SecretKeySpec;
import ru.vtosters.lite.encryption.base.IMProcessor;
public class DefaultCoffeeProcessor extends IMProcessor{
public class DefaultCoffeeProcessor extends IMProcessor {
private final static String KEY = "stupidUsersMustD";
private static Cipher dCipher, eCipher;
static{
static {
try {
SecretKeySpec key = new SecretKeySpec(KEY.getBytes(), "AES");
@@ -28,7 +28,7 @@ public class DefaultCoffeeProcessor extends IMProcessor{
}
}
private String toHex(String text){
private String toHex(String text) {
char[] chars = text.toCharArray();
StringBuilder str = new StringBuilder();
for (char aChar : chars) {
@@ -41,7 +41,7 @@ public class DefaultCoffeeProcessor extends IMProcessor{
return string.substring(0, string.length() - 1);
}
private String fromHex(String text){
private String fromHex(String text) {
text = text.replace(" ", "");
char[] chars = text.toCharArray();
char[] chars2 = new char[chars.length / 2];
@@ -55,7 +55,7 @@ public class DefaultCoffeeProcessor extends IMProcessor{
@NonNull
@Override
protected String encodeInternal(@NonNull String source, @Nullable byte[] key){
protected String encodeInternal(@NonNull String source, @Nullable byte[] key) {
try {
return toHex(Base64.encodeToString(eCipher.doFinal(source.getBytes()), 0));
} catch (Exception e) {
@@ -67,7 +67,7 @@ public class DefaultCoffeeProcessor extends IMProcessor{
@NonNull
@Override
protected String decodeInternal(@NonNull String source, @Nullable byte[] key){
protected String decodeInternal(@NonNull String source, @Nullable byte[] key) {
try {
return new String(dCipher.doFinal(Base64.decode(fromHex(source), 0)));
} catch (Exception e) {
@@ -79,25 +79,25 @@ public class DefaultCoffeeProcessor extends IMProcessor{
@Override
@NonNull
public String startTag(){
public String startTag() {
return "VK CO FF EE ";
}
@Override
@NonNull
public String endTag(){
public String endTag() {
return " VK CO FF EE";
}
@NonNull
@Override
public String getUIName(){
public String getUIName() {
return "VK Coffee [default]";
}
@NonNull
@Override
public String getPrefKey(){
public String getPrefKey() {
return "coffee_default";
}
}
@@ -2,28 +2,28 @@ package ru.vtosters.lite.encryption.processors;
import androidx.annotation.NonNull;
public class DonateCoffeeProcessor extends DefaultCoffeeProcessor{
public class DonateCoffeeProcessor extends DefaultCoffeeProcessor {
@Override
@NonNull
public String startTag(){
public String startTag() {
return "II ";
}
@Override
@NonNull
public String endTag(){
public String endTag() {
return " II";
}
@NonNull
@Override
public String getUIName(){
public String getUIName() {
return "VK Coffee [hidden]";
}
@NonNull
@Override
public String getPrefKey(){
public String getPrefKey() {
return "coffee_donate";
}
}
@@ -9,17 +9,17 @@ import java.nio.charset.StandardCharsets;
import ru.vtosters.lite.encryption.base.IMProcessor;
public class MP3InvisibleProcessor extends IMProcessor{
private static String toStr(int a, String cc){
public class MP3InvisibleProcessor extends IMProcessor {
private static String toStr(int a, String cc) {
StringBuilder s = new StringBuilder();
while(a > 0) {
while (a > 0) {
s.insert(0, cc.charAt(a % cc.length()));
a /= cc.length();
}
return s.toString();
}
private static int toNum(String a, String cc){
private static int toNum(String a, String cc) {
int n = 0;
for (int i = 0; i < a.length(); i++) {
int start = (a.length() - i) - 1;
@@ -30,7 +30,7 @@ public class MP3InvisibleProcessor extends IMProcessor{
@NonNull
@Override
protected String encodeInternal(@NonNull String source, @Nullable byte[] key){
protected String encodeInternal(@NonNull String source, @Nullable byte[] key) {
try {
byte[] bytes = source.getBytes(StandardCharsets.UTF_8);
java.lang.String[] plainText = new String[bytes.length];
@@ -46,7 +46,7 @@ public class MP3InvisibleProcessor extends IMProcessor{
@NonNull
@Override
protected String decodeInternal(@NonNull String source, @Nullable byte[] key){
protected String decodeInternal(@NonNull String source, @Nullable byte[] key) {
try {
java.lang.String[] t = source.replaceAll("^" + "  ", "").split(" ");
byte[] plainText = new byte[t.length];
@@ -61,19 +61,19 @@ public class MP3InvisibleProcessor extends IMProcessor{
}
@Override
public boolean isEncrypted(String source){
public boolean isEncrypted(String source) {
return source.matches("^" + "  " + "([" + " ​‌‏ " + "\\s]*)");
}
@NonNull
@Override
public String getUIName(){
public String getUIName() {
return "MP3 [invisible]";
}
@NonNull
@Override
public String getPrefKey(){
public String getPrefKey() {
return "mp3";
}
}
@@ -17,22 +17,22 @@ import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import ru.vtosters.lite.encryption.base.IMProcessor;
import ru.vtosters.lite.utils.Globals;
import ru.vtosters.lite.utils.AndroidUtils;
public class VTostersAESProcessor extends IMProcessor{
public class VTostersAESProcessor extends IMProcessor {
private final static String CIPHER_INSTANCE = "AES/CBC/PKCS7Padding";
private final static String KEY_METHOD = "AES";
private final HashMap<byte[], Cipher> decodeMap = new HashMap<>();
private final HashMap<byte[], Cipher> encodeMap = new HashMap<>();
public void free(byte[] key){
public void free(byte[] key) {
decodeMap.remove(key);
encodeMap.remove(key);
}
@NonNull
private Cipher wrapEncoder(byte[] key) throws InvalidAlgorithmParameterException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException{
private Cipher wrapEncoder(byte[] key) throws InvalidAlgorithmParameterException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException {
if (encodeMap.containsKey(key)) return encodeMap.get(key);
Triple<Cipher, SecretKeySpec, IvParameterSpec> encodeCipher = getBaseCipher(key);
@@ -43,7 +43,7 @@ public class VTostersAESProcessor extends IMProcessor{
}
@NonNull
private Cipher wrapDecoder(byte[] key) throws InvalidAlgorithmParameterException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException{
private Cipher wrapDecoder(byte[] key) throws InvalidAlgorithmParameterException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException {
if (decodeMap.containsKey(key)) return decodeMap.get(key);
Triple<Cipher, SecretKeySpec, IvParameterSpec> decodeCipher = getBaseCipher(key);
@@ -54,7 +54,7 @@ public class VTostersAESProcessor extends IMProcessor{
}
@NonNull
private Triple<Cipher, SecretKeySpec, IvParameterSpec> getBaseCipher(byte[] key) throws NoSuchPaddingException, NoSuchAlgorithmException{
private Triple<Cipher, SecretKeySpec, IvParameterSpec> getBaseCipher(byte[] key) throws NoSuchPaddingException, NoSuchAlgorithmException {
byte[] off = new byte[16];
System.arraycopy(key, 0, off, 0, off.length);
return new Triple<>(Cipher.getInstance(CIPHER_INSTANCE), new SecretKeySpec(key, KEY_METHOD), new IvParameterSpec(off));
@@ -62,7 +62,7 @@ public class VTostersAESProcessor extends IMProcessor{
@NonNull
@Override
protected String encodeInternal(@NonNull String source, @Nullable byte[] key){
protected String encodeInternal(@NonNull String source, @Nullable byte[] key) {
try {
return Base64.encodeToString(wrapEncoder(key).doFinal(source.getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT);
} catch (Exception e) {
@@ -73,7 +73,7 @@ public class VTostersAESProcessor extends IMProcessor{
@NonNull
@Override
protected String decodeInternal(@NonNull String source, @Nullable byte[] key){
protected String decodeInternal(@NonNull String source, @Nullable byte[] key) {
try {
return new String(wrapDecoder(key).doFinal(Base64.decode(source, Base64.DEFAULT)), StandardCharsets.UTF_8);
} catch (Exception e) {
@@ -83,46 +83,46 @@ public class VTostersAESProcessor extends IMProcessor{
}
@Override
public boolean isPublic(){
public boolean isPublic() {
return false;
}
@NonNull
@Override
public String startTag(){
public String startTag() {
return "VT0ST3RS [AES] ";
}
@NonNull
@Override
public String endTag(){
public String endTag() {
return " VT0ST3RS [AES]";
}
@NonNull
@Override
public String getUIName(){
public String getUIName() {
return "VTosters [AES]";
}
@NonNull
@Override
public String getPrefKey(){
public String getPrefKey() {
return "vtaes";
}
@Nullable
@Override
public String getEncryptionKeyFor(int id){
return Globals.getDefprefs().getString("VT_IMEncodeKey_" + getPrefKey() + "_" + id, "VTAesDefault");
public String getEncryptionKeyFor(int id) {
return AndroidUtils.getDefaultPrefs().getString("VT_IMEncodeKey_" + getPrefKey() + "_" + id, "VTAesDefault");
}
public static class Triple<F, S, T>{
public static class Triple<F, S, T> {
public final F first;
public final S second;
public final T third;
public Triple(F first, S second, T third){
public Triple(F first, S second, T third) {
this.first = first;
this.second = second;
this.third = third;
@@ -7,40 +7,40 @@ import androidx.annotation.Nullable;
import ru.vtosters.lite.encryption.base.IMProcessor;
public class VTostersProcessor extends IMProcessor{
public class VTostersProcessor extends IMProcessor {
@NonNull
@Override
protected String encodeInternal(@NonNull String source, @Nullable byte[] key){
protected String encodeInternal(@NonNull String source, @Nullable byte[] key) {
return Base64.encodeToString(source.getBytes(), Base64.DEFAULT);
}
@NonNull
@Override
protected String decodeInternal(@NonNull String source, @Nullable byte[] key){
protected String decodeInternal(@NonNull String source, @Nullable byte[] key) {
return new String(Base64.decode(source, Base64.DEFAULT));
}
@Override
@NonNull
public String startTag(){
public String startTag() {
return "VT0ST3RS ";
}
@Override
@NonNull
public String endTag(){
public String endTag() {
return " VT0ST3RS";
}
@NonNull
@Override
public String getUIName(){
public String getUIName() {
return "VTosters Classique [Base64]";
}
@NonNull
@Override
public String getPrefKey(){
public String getPrefKey() {
return "vt64";
}
}
@@ -2,10 +2,11 @@ package ru.vtosters.lite.foaf;
import static android.widget.Toast.LENGTH_SHORT;
import static android.widget.Toast.makeText;
import static ru.vtosters.lite.utils.Globals.getIdentifier;
import static ru.vtosters.lite.utils.Globals.getString;
import static ru.vtosters.lite.utils.Proxy.apiproxy;
import static ru.vtosters.lite.utils.Proxy.getApi;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.getString;
import static ru.vtosters.lite.utils.ProxyUtils.apiproxy;
import static ru.vtosters.lite.utils.ProxyUtils.getApi;
import android.app.ProgressDialog;
import android.content.Context;
@@ -30,13 +31,13 @@ import okhttp3.Headers;
import okhttp3.OkHttpClient;
import ru.vtosters.lite.net.Request;
public class FoafBase{
public class FoafBase {
private static final Pattern FOAF_REGEX = Pattern.compile("<ya:created dc:date=\"(.+?)\"\\/>");
private static final Pattern FOAF_REGEX_LAST_SEEN = Pattern.compile("<ya:lastLoggedIn dc:date=\"(.*)(((\\+|-)\\d\\d):(\\d\\d))\"\\/>");
private static final Pattern FOAF_REGEX_LOGIN = Pattern.compile("<ya:created dc:date=\"(.+?)\"\\/>");
private static final OkHttpClient client = new OkHttpClient();
public static long getLastSeen(long origtime, int id) throws ParseException, IOException{
public static long getLastSeen(long origtime, int id) throws ParseException, IOException {
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();
@@ -62,7 +63,7 @@ public class FoafBase{
return sdf.parse(sdf.format(date)).getTime() / 1000;
}
private static String getLink(int i){
private static String getLink(int i) {
String str;
StringBuilder sb;
if (apiproxy()) {
@@ -77,7 +78,7 @@ public class FoafBase{
return sb.toString();
}
public static void loadAndShow(Context context, int i){
public static void loadAndShow(Context context, int i) {
ProgressDialog progressDialog = new ProgressDialog(context);
progressDialog.setMessage(getString("com_facebook_loading"));
progressDialog.setCancelable(false);
@@ -87,7 +88,7 @@ public class FoafBase{
Request.makeRequest(getLink(i), callback);
}
static void lambdaLoadAndShow(ProgressDialog progressDialog, Context context, int i, String str){
static void lambdaLoadAndShow(ProgressDialog progressDialog, Context context, int i, String str) {
try {
progressDialog.cancel();
Matcher matcher = FOAF_REGEX.matcher(str);
@@ -100,11 +101,11 @@ public class FoafBase{
a2.setMessage(getString("foafid") + " " + i + getString("foafregdate") + " " + normalHumanDate + getString("foafdate") + " " + daysPassedFromFoafDate(normalHumanDate)).setPositiveButton(17039370, null).create().show();
} catch (Exception e) {
e.printStackTrace();
makeText(context, getString("foaferr"), LENGTH_SHORT).show();
makeText(getGlobalContext(), getString("foaferr"), LENGTH_SHORT).show();
}
}
private static long daysPassedFromFoafDate(String str){
private static long daysPassedFromFoafDate(String str) {
try {
Date parse = new SimpleDateFormat("yyyy-MM-dd").parse(str.split(" ")[1]);
return TimeUnit.DAYS.convert(new Date().getTime() - parse.getTime(), TimeUnit.MILLISECONDS);
@@ -114,7 +115,7 @@ public class FoafBase{
}
}
private static String getNormalHumanDate(String str){
private static String getNormalHumanDate(String str) {
String[] split = str.split(ExifInterface.GPS_DIRECTION_TRUE);
return split[1].split("\\+")[0] + " " + split[0];
}
@@ -1,8 +1,9 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.Globals.getIdentifier;
import static ru.vtosters.lite.utils.Globals.getPrefsValue;
import static ru.vtosters.lite.utils.Globals.getString;
import static ru.vtosters.lite.utils.Globals.getStringDate;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.AndroidUtils.getString;
import static ru.vtosters.lite.utils.AndroidUtils.getStringDate;
import android.annotation.SuppressLint;
@@ -10,13 +11,13 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class DateHook{
public static boolean fulltime(){
public class DateHook {
public static boolean fulltime() {
return getPrefsValue("dateformat").equals("noyear") || getPrefsValue("dateformat").equals("full") || getPrefsValue("dateformat").equals("noseconds");
}
public static String getDateFormat(){
switch(getPrefsValue("dateformat")) {
public static String getDateFormat() {
switch (getPrefsValue("dateformat")) {
case "noyear":
return getString("fulltime2");
case "full":
@@ -27,11 +28,11 @@ public class DateHook{
}
@SuppressLint("SimpleDateFormat")
public static SimpleDateFormat setDateFormat(){
public static SimpleDateFormat setDateFormat() {
return new SimpleDateFormat(getDateFormat());
}
public static String getFormattedDate(boolean isFemale, long time){
public static String getFormattedDate(boolean isFemale, long time) {
SimpleDateFormat date = new SimpleDateFormat(getDateFormat(), Locale.getDefault());
if (!fulltime()) return null;
@@ -44,7 +45,7 @@ public class DateHook{
}
}
public static String getLocale(){
public static String getLocale() {
String string = getPrefsValue("lang_value");
if (string.equals("system")) {
@@ -0,0 +1,39 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import android.util.Log;
import java.util.Random;
public class DeviceInfoHook{
public static String getDeviceInfo(String input) {
Log.d("DeviceInfoHook", "getDeviceInfo: " + input);
if (getBoolValue("hideDeviceInfo", true)) return "";
return input;
}
public static String getDeviceId(String input) {
Log.d("DeviceInfoHook", "getDeviceId: " + input);
Log.d("DeviceInfoHook", "getDeviceId shuffled: " + shuffle(input));
if (getBoolValue("hideDeviceInfo", true)) return shuffle(input);
return input;
}
public static String shuffle(String string) {
StringBuilder sb = new StringBuilder(string.length());
double rnd;
for (char c: string.toCharArray()) {
rnd = Math.random();
if (rnd < 0.34)
sb.append(c);
else if (rnd < 0.67)
sb.insert(sb.length() / 2, c);
else
sb.insert(0, c);
sb.append(new Random().nextInt(10));
sb.deleteCharAt(0);
}
return sb.toString();
}
}
@@ -1,6 +1,5 @@
package ru.vtosters.lite.hooks;
import static android.graphics.Color.*;
import static com.vtosters.lite.R.id.menu_fave;
import static com.vtosters.lite.R.id.menu_feedback;
import static com.vtosters.lite.R.id.menu_friends;
@@ -17,14 +16,14 @@ import static com.vtosters.lite.R.id.tab_feedback;
import static com.vtosters.lite.R.id.tab_menu;
import static com.vtosters.lite.R.id.tab_messages;
import static com.vtosters.lite.R.id.tab_news;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.Globals.getResources;
import static ru.vtosters.lite.utils.Preferences.*;
import static ru.vtosters.lite.utils.Themes.getCSTDock;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getResources;
import static ru.vtosters.lite.utils.Preferences.dockcounter;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Preferences.milkshake;
import static ru.vtosters.lite.utils.ThemesUtils.getCSTDock;
import android.annotation.SuppressLint;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.view.Menu;
import android.view.MenuItem;
@@ -54,8 +53,6 @@ import java.util.Map;
import ru.vtosters.lite.ui.components.DockBarEditorManager;
import ru.vtosters.lite.ui.items.DockBarTab;
import ru.vtosters.lite.utils.Globals;
import ru.vtosters.lite.utils.Preferences;
public class DockBarInjector {
private static final DockBarEditorManager sManager = DockBarEditorManager.getInstance();
@@ -94,10 +91,10 @@ public class DockBarInjector {
Drawable drawable = getResources().getDrawable(tab.iconID);
add.setIcon(new RecoloredDrawable(drawable, getCSTDock()));
add.setTitle(getContext().getString(tab.titleID));
add.setTitle(getGlobalContext().getString(tab.titleID));
add.setCheckable(true);
}
if (getBoolValue("dockbar_tab_titles", false)) {
if (getBoolValue("dockbar_tab_titles", true)) {
var menuView = (BottomNavigationMenuView) navigationView.getChildAt(0);
for (int i = 0; i < menuView.getChildCount(); i++) {
var item = (com.vtosters.lite.ui.bottomnavigation.BottomNavigationItemView) menuView.getChildAt(i);
@@ -1,17 +1,18 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.FragAnimationKit.setAnimations;
import static ru.vtosters.lite.utils.Globals.getPrefsValue;
import static ru.vtosters.lite.ui.components.FragAnimationKit.setAnimations;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import androidx.fragment.app.FragmentTransaction;
public class FragAnimationHook{
public static boolean animateOpen(FragmentTransaction transaction){
public class FragAnimationHook {
public static boolean animateOpen(FragmentTransaction transaction) {
setAnimations(transaction);
return getPrefsValue("anim_rtrn_type").equals("noanim") || getPrefsValue("anim_rtrn_type").isEmpty();
}
public static void animateClose(FragmentTransaction transaction){
public static void animateClose(FragmentTransaction transaction) {
setAnimations(transaction);
}
}
@@ -27,28 +27,28 @@ import java.util.concurrent.atomic.AtomicBoolean;
import javax.net.ssl.HttpsURLConnection;
public class GcmHook{
public class GcmHook {
private static final String agent = String.format("Android-GCM/1.5 (%s %s)", Build.MODEL, Build.MODEL);
public static ArrayList<String> langs = new ArrayList<>();
private static KeyPair pair;
private static int rid = 0;
static{
static {
genNewKey();
}
public static String requestTokenV2(String orig){
public static String requestTokenV2(String orig) {
if (musicFixNew()) return "null";
return orig;
}
public static String requestToken(String orig){
public static String requestToken(String orig) {
if (musicFixNew()) return "{null}";
if (orig.equals("")) return requestToken();
return orig;
}
public static String requestToken(){
public static String requestToken() {
String xappide;
try {
String aid = getRandomAid();
@@ -59,7 +59,7 @@ public class GcmHook{
bytes[0] = (byte) (((bytes[0] & 15) + 112) & 255);
xappide = Base64.encodeToString(bytes, 2).substring(0, 11);
} catch (NoSuchAlgorithmException e) {
xappide = "";
xappide = "";
}
AtomicBoolean wait = new AtomicBoolean(false);
StringBuilder sb = new StringBuilder();
@@ -69,7 +69,7 @@ public class GcmHook{
Callback callback = str -> GcmHook.lambdaRequestToken(sb, wait, str);
doRequest("https://android.clients.google.com/c2dm/register3", "POST", params, aid, callback);
while(!wait.get()) {
while (!wait.get()) {
Thread.sleep(100);
}
String token = sb.toString();
@@ -90,15 +90,15 @@ public class GcmHook{
}
}
static void lambdaRequestToken(StringBuilder sb, AtomicBoolean wait, String s){
static void lambdaRequestToken(StringBuilder sb, AtomicBoolean wait, String s) {
sb.append(s.substring(20));
wait.set(true);
}
static void lambda$requestToken$1(String str){
static void lambda$requestToken$1(String str) {
}
private static void fillParams(List<String> params, String sig, String pub2, String xappid, long androidId, boolean del){
private static void fillParams(List<String> params, String sig, String pub2, String xappid, long androidId, boolean del) {
rid++;
params.add("X-subtype=841415684880");
if (del) {
@@ -108,7 +108,7 @@ public class GcmHook{
params.add("X-X-subscription=841415684880");
}
params.add("X-X-subtype=841415684880");
params.add("X-app_ver=" + "5.56.1");
params.add("X-app_ver=" + "7.26");
params.add("X-kid=|ID|" + rid + "|");
params.add("X-osv=30");
params.add("X-sig=" + sig);
@@ -129,16 +129,16 @@ public class GcmHook{
if (!del) {
params.add("X-gmp_app_id=1:841415684880:android:632f429381141121");
}
params.add("X-app_ver_name=" + "5.56.1");
params.add("X-app_ver_name=" + "7.26");
params.add("app=com.vkontakte.android");
params.add("sender=841415684880");
params.add("device=" + androidId);
params.add("cert=48761eef50ee53afc4cc9c5f10e6bde7f8f5b82f");
params.add("app_ver=" + "4838");
params.add("app_ver=" + "12338");
params.add("gcm_ver=11949470");
}
private static String join(String chr, Iterable<String> arr){
private static String join(String chr, Iterable<String> arr) {
String str = "";
for (String s : arr) {
str = str.isEmpty() ? s : str + chr + s;
@@ -146,11 +146,11 @@ public class GcmHook{
return str;
}
private static String join(String chr, String[] arr){
private static String join(String chr, String[] arr) {
return join(chr, Arrays.asList(arr));
}
private static void doRequest(String url, String method, List<String> params, String aidlogin, Callback callback) throws IOException{
private static void doRequest(String url, String method, List<String> params, String aidlogin, Callback callback) throws IOException {
HttpsURLConnection con = (HttpsURLConnection) new URL(url).openConnection();
con.setRequestMethod(method);
con.setRequestProperty("Authorization", aidlogin);
@@ -169,13 +169,13 @@ public class GcmHook{
}
private static String getRandomAid() {
var arr1 = new String[]{ "3974055026275073921", "4418584909973341826", "4585634953328772978" };
var arr2 = new String[]{ "1932960345884890854", "6594645578425092292", "1792344590975444730" };
var arr1 = new String[]{"3974055026275073921", "4418584909973341826", "4585634953328772978"};
var arr2 = new String[]{"1932960345884890854", "6594645578425092292", "1792344590975444730"};
int r = new Random().nextInt(2);
return "AidLogin " + arr1[r] + ":" + arr2[r];
}
private static String genNewKey(){
private static String genNewKey() {
try {
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(2048);
@@ -186,12 +186,12 @@ public class GcmHook{
return Base64.encodeToString(pair.getPublic().getEncoded(), 0);
}
private static String getSig(String pub2){
private static String getSig(String pub2) {
try {
PrivateKey key = pair.getPrivate();
Signature sign = Signature.getInstance(key instanceof RSAPrivateKey ? "SHA256withRSA" : "SHA256withECDSA");
sign.initSign(key);
sign.update(join("\n", new String[] {"com.vkontakte.android", pub2}).getBytes(StandardCharsets.UTF_8));
sign.update(join("\n", new String[]{"com.vkontakte.android", pub2}).getBytes(StandardCharsets.UTF_8));
return Base64.encodeToString(sign.sign(), 0);
} catch (Exception e) {
e.printStackTrace();
@@ -199,7 +199,7 @@ public class GcmHook{
}
}
public interface Callback{
public interface Callback {
void doCallback(String str);
}
}
@@ -1,19 +1,11 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.f0x1d.VTVerifications.isDeveloper;
import static ru.vtosters.lite.f0x1d.VTVerifications.isPrometheus;
import static ru.vtosters.lite.f0x1d.VTVerifications.isVerified;
import static ru.vtosters.lite.foaf.FoafBase.getLastSeen;
import static ru.vtosters.lite.hooks.DateHook.getLocale;
import static ru.vtosters.lite.utils.Base64Utils.decode;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.Globals.getPrefsValue;
import static ru.vtosters.lite.utils.Globals.getUserId;
import static ru.vtosters.lite.utils.Globals.getUserToken;
import static ru.vtosters.lite.utils.Globals.isVKTester;
import static ru.vtosters.lite.utils.Newsfeed.checkCaption;
import static ru.vtosters.lite.utils.Newsfeed.checkCopyright;
import static ru.vtosters.lite.utils.Newsfeed.isBadNews;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.checkCaption;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.checkCopyright;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.isBadNews;
import static ru.vtosters.lite.utils.Preferences.ads;
import static ru.vtosters.lite.utils.Preferences.adsgroup;
import static ru.vtosters.lite.utils.Preferences.adsstories;
@@ -23,16 +15,17 @@ import static ru.vtosters.lite.utils.Preferences.friendsblock;
import static ru.vtosters.lite.utils.Preferences.friendsrecomm;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Preferences.hasVerification;
import static ru.vtosters.lite.utils.Preferences.podcastcatalog;
import static ru.vtosters.lite.utils.Preferences.postsrecomm;
import static ru.vtosters.lite.utils.VTVerifications.isDeveloper;
import static ru.vtosters.lite.utils.VTVerifications.isPrometheus;
import static ru.vtosters.lite.utils.VTVerifications.isVerified;
import android.net.Uri;
import android.util.Log;
import com.vk.core.network.Network;
import com.vk.core.util.DeviceIdProvider;
import com.vk.core.util.LangUtils;
import com.vk.core.util.UriExt;
import com.vk.webapp.VkUiFragment;
import org.json.JSONArray;
import org.json.JSONException;
@@ -46,13 +39,14 @@ import java.util.Random;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import ru.vtosters.lite.utils.Globals;
import ru.vtosters.lite.utils.Newsfeed;
import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.NewsFeedFiltersUtils;
public class JsonInjectors{
public class JsonInjectors {
private static final OkHttpClient mClient = new OkHttpClient();
public static JSONObject profileButton(JSONObject orig) throws JSONException{
public static JSONObject profileButton(JSONObject orig) throws JSONException {
var id = orig.getInt("id");
var newItem = new JSONArray();
@@ -61,11 +55,11 @@ public class JsonInjectors{
newItem = orig.getJSONArray("buttons");
}
if (!haveDonateButton() && id == getUserId()) {
if (!haveDonateButton() && id == AccountManagerUtils.getUserId()) {
newItem.put(donateRecomm());
}
if (!orig.has("type") && isVKTester()) {
if (!orig.has("type") && AccountManagerUtils.isVKTester()) {
newItem.put(vktesters(id));
}
@@ -74,7 +68,7 @@ public class JsonInjectors{
return orig;
}
public static JSONObject donateRecomm() throws JSONException{
public static JSONObject donateRecomm() throws JSONException {
var title = "Помоги проекту донатом и получи бонус!";
var link = "https://vk.com/vtosters_official";
var text_color = "2D81E0";
@@ -115,7 +109,7 @@ public class JsonInjectors{
return json;
}
public static JSONObject vktesters(int id) throws JSONException{
public static JSONObject vktesters(int id) throws JSONException {
var title = "Карточка Тестера";
var text_color = "2D81E0";
var link = "https://static.vk.com/bugs?lang=" + LangUtils.a() + "#/reporter" + id;
@@ -156,7 +150,7 @@ public class JsonInjectors{
return json;
}
public static JSONObject convBar(JSONObject orig) throws JSONException{
public static JSONObject convBar(JSONObject orig) throws JSONException {
var peerid = Objects.requireNonNull(orig.optJSONObject("peer")).optInt("id");
var pic = "https://image.pngaaa.com/641/326641-middle.png"; // can be null
@@ -198,7 +192,7 @@ public class JsonInjectors{
+ decode("fQ=="));
}
public static JSONObject menu(JSONObject orig) throws JSONException{
public static JSONObject menu(JSONObject orig) throws JSONException {
var Special = orig.optJSONArray("special");
var Main = orig.getJSONArray("main");
var Other = orig.optJSONArray("other");
@@ -210,9 +204,9 @@ public class JsonInjectors{
return orig;
}
public static JSONObject superapp(JSONObject json) throws JSONException{
var superApps = Globals.getPreferences().getString("superapp_items",
"menu,promo,miniapps,vkpay_slim,greeting,holiday,weather,sport,games,informer,food,event,music,vk_run").split(",");
public static JSONObject superapp(JSONObject json) throws JSONException {
var superApps = AndroidUtils.getPreferences().getString("superapp_items",
"menu,miniapps,vkpay_slim,greeting,promo,holiday,weather,sport,games,informer,food,event,music,vk_run").split(",");
if (superApps.length == 0) return json;
var oldItems = json.optJSONArray("items");
@@ -239,12 +233,31 @@ public class JsonInjectors{
return json.putOpt("items", newItems);
}
public static JSONObject musiclink(JSONObject json){
public static JSONObject musiclink(JSONObject json) {
var oldItems = json.optJSONArray("links");
var section = json.optJSONObject("section");
var linksblock = section.optJSONArray("blocks");
var newBlock = new JSONArray();
if (oldItems != null) {
if (oldItems.optJSONObject(0).optString("url").contains("?section=recent")) {
json.remove("links");
for (int i = 0; i < linksblock.length(); i++) {
var item = linksblock.optJSONObject(i);
var datatype = item.optString("data_type");
var layname = item.optJSONObject("layout").optString("name");
if (!datatype.equals("links") && !layname.equals("separator")) {
newBlock.put(item);
}
}
try {
section.putOpt("blocks", newBlock);
} catch (JSONException e) {
e.printStackTrace();
}
if (dev()) Log.d("VKMusic", "Removed links buttons");
}
}
@@ -252,12 +265,12 @@ public class JsonInjectors{
return json;
}
public static JSONObject setOnlineInfo(JSONObject json) throws ParseException, IOException, JSONException{
public static JSONObject setOnlineInfo(JSONObject json) throws ParseException, IOException, JSONException {
var id = json.optInt("id");
var onlineinfo = json.optJSONObject("online_info");
var time = getLastSeen(0L, id);
if (time != 0L && onlineinfo != null && !onlineinfo.optBoolean("is_online") && id != getUserId()) {
if (time != 0L && onlineinfo != null && !onlineinfo.optBoolean("is_online") && id != AccountManagerUtils.getUserId()) {
json.remove("online_info");
var online_info = new JSONObject()
@@ -277,7 +290,7 @@ public class JsonInjectors{
return json;
}
public static JSONObject storiesads(JSONObject json, boolean isDeleteFix) throws JSONException{
public static JSONObject storiesads(JSONObject json, boolean isDeleteFix) throws JSONException {
if (!adsstories()) {
return json;
}
@@ -311,7 +324,7 @@ public class JsonInjectors{
return json;
}
private static void parseStoriesItem(JSONObject item) throws JSONException{
private static void parseStoriesItem(JSONObject item) throws JSONException {
var stories = item.optJSONArray("stories");
var newStories = new JSONArray();
@@ -331,7 +344,7 @@ public class JsonInjectors{
item.put("stories", newStories);
}
public static Boolean isAds(JSONObject list, String type) throws JSONException{
public static Boolean isAds(JSONObject list, String type) throws JSONException {
if (list == null || type == null || !ads()) return false;
if (list.has("ads")
@@ -357,7 +370,7 @@ public class JsonInjectors{
return false;
}
public static JSONArray newsfeedlist(JSONArray items) throws JSONException{
public static JSONArray newsfeedlist(JSONArray items) throws JSONException {
for (int j = 0; j < items.length(); j++) {
var list = items.optJSONObject(j);
var name = list.optString("id");
@@ -371,7 +384,7 @@ public class JsonInjectors{
return items;
}
public static JSONArray newsfeedadtest(JSONArray items) throws JSONException{
public static JSONArray newsfeedadtest(JSONArray items) throws JSONException {
if (!getBoolValue("newadblock", true)) return items;
var newItems = new JSONArray();
@@ -429,7 +442,7 @@ public class JsonInjectors{
continue;
}
if (Newsfeed.injectFiltersReposts(list)) {
if (NewsFeedFiltersUtils.injectFiltersReposts(list)) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: repost ad");
continue;
@@ -441,7 +454,7 @@ public class JsonInjectors{
return newItems;
}
public static JSONObject music(JSONObject json) throws JSONException{
public static JSONObject music(JSONObject json) throws JSONException {
var catalog = json.optJSONObject("catalog");
JSONArray oldItems = null;
@@ -450,7 +463,22 @@ public class JsonInjectors{
oldItems = catalog.optJSONArray("sections");
}
if (oldItems != null) {
if (oldItems != null && oldItems.optJSONObject(0).optString("url").contains("general")) {
if (podcastcatalog()) {
var podcasts = fetchCatalogPodcast();
if (podcasts != null) {
var catalogarr = podcasts.optJSONObject("catalog").optJSONArray("sections").optJSONObject(0);
var title = catalogarr.optString("title");
var id = catalogarr.optString("id");
var url = catalogarr.optString("url");
if (dev()) Log.d("VKMusic", "Added " + title + " in music sections");
oldItems.put(new JSONObject().put("id", id).put("title", title).put("url", url));
}
}
var playlists = fetchCatalogId("https://vk.com/audio?section=my_playlists");
if (playlists != null) {
var catalogarr = playlists.optJSONObject("catalog").optJSONArray("sections").optJSONObject(0);
@@ -495,11 +523,11 @@ public class JsonInjectors{
var title = item.optString("title");
var id = item.optString("id");
var url = item.optString("url");
var value = getPrefsValue("musicdefcatalog");
var value = AndroidUtils.getPrefsValue("musicdefcatalog");
Log.d("VKMusic", "title: " + title + " id: " + id + " url: " + url + " value: " + value);
if (url.contains(value)) {
if (url.contains(value) && !value.isEmpty()) {
catalog.put("default_section", id);
if (dev()) Log.d("VKMusic", "Added " + title + " as default music section");
}
@@ -509,7 +537,7 @@ public class JsonInjectors{
return json;
}
public static JSONObject fetchCatalogId(String section){
public static JSONObject fetchCatalogId(String section) {
if (section == null) return null;
var request = new Request.a()
@@ -520,11 +548,11 @@ public class JsonInjectors{
+ "&lang="
+ getLocale()
+ "&device_id="
+ DeviceIdProvider.d(getContext())
+ DeviceIdProvider.d(AndroidUtils.getGlobalContext())
+ "&url="
+ section
+ "&access_token="
+ getUserToken())
+ AccountManagerUtils.getUserToken())
.a(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8")).a();
try {
return new JSONObject(mClient.a(request).execute().a().g()).getJSONObject("response");
@@ -535,7 +563,29 @@ public class JsonInjectors{
return null;
}
public static JSONObject friends(JSONObject json) throws JSONException{
public static JSONObject fetchCatalogPodcast() {
var request = new Request.a()
.b("https://api.vk.com/method/catalog.getPodcasts"
+ "?v=5.119"
+ "&https=1"
+ "&need_blocks=1"
+ "&lang="
+ getLocale()
+ "&device_id="
+ DeviceIdProvider.d(AndroidUtils.getGlobalContext())
+ "&access_token="
+ AccountManagerUtils.getUserToken())
.a(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8")).a();
try {
return new JSONObject(mClient.a(request).execute().a().g()).getJSONObject("response");
} catch (JSONException | IOException e) {
Log.d("VTLMusic", "Error: " + e.getMessage());
}
return null;
}
public static JSONObject friends(JSONObject json) throws JSONException {
JSONObject catalog = json;
boolean sectionexecute = true;
boolean hasBirthday = false;
@@ -602,7 +652,7 @@ public class JsonInjectors{
}
public static boolean haveDonateButton(){
public static boolean haveDonateButton() {
int randomshower = new Random().nextInt(6);
return hasVerification() || randomshower != 1;
@@ -0,0 +1,43 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.ui.dialogs.ServerDialog.sendRequest;
import static ru.vtosters.lite.utils.CacheUtils.getInstance;
import static ru.vtosters.lite.utils.DeletedMessagesHandler.reloadMessagesList;
import static ru.vtosters.lite.utils.Preferences.checkupdates;
import static ru.vtosters.lite.utils.ThemesUtils.isDarkTheme;
import static ru.vtosters.lite.utils.ThemesUtils.setNeededTheme;
import android.app.Activity;
import android.os.Build;
import android.preference.PreferenceManager;
import ru.vtosters.lite.downloaders.notifications.NotificationChannels;
import ru.vtosters.lite.ui.dialogs.DisableBattery;
import ru.vtosters.lite.ui.dialogs.InstallGMS;
import ru.vtosters.lite.ui.dialogs.OTADialog;
import ru.vtosters.lite.ui.dialogs.ServerDialog;
import ru.vtosters.lite.ui.dialogs.Start;
public class MainActivityInjector {
public static void inject(Activity activity) {
setNeededTheme(activity);
ServerDialog.activity = activity;
sendRequest();
if (checkupdates()) OTADialog.checkUpdates(activity);
reloadMessagesList();
Start.alert(activity);
InstallGMS.alert(activity);
DisableBattery.alert(activity);
PreferenceManager.getDefaultSharedPreferences(activity)
.edit()
.putBoolean("isdark", isDarkTheme())
.commit();
getInstance().autoCleaningCache();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannels.createChannels();
}
// VKIDProtection.alert(activity);
}
}
@@ -0,0 +1,107 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.ui.dialogs.MessageSettings.argDialog;
import static ru.vtosters.lite.ui.dialogs.MessageSettings.bombCount;
import static ru.vtosters.lite.ui.dialogs.MessageSettings.isSilentEnabled;
import static ru.vtosters.lite.utils.Preferences.autoalltranslate;
import static ru.vtosters.lite.utils.Preferences.autotranslate;
import static ru.vtosters.lite.utils.Preferences.savemsgsett;
import android.text.TextUtils;
import android.view.View;
import com.vk.api.internal.MethodCall;
import ru.vtosters.lite.translators.BaseTranslator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.ArrayList;
public class MessagesHook {
public static String injectOwnText(String oldText) {
if (!autotranslate() || TextUtils.isEmpty(oldText))
return oldText;
var instance = BaseTranslator.getInstance();
return replaceMentions(oldText, instance);
}
public static String injectOwnTextAll(String oldText) {
if (!autoalltranslate() || TextUtils.isEmpty(oldText)) {
return oldText;
}
var instance = BaseTranslator.getInstance();
return replaceMentions(oldText, instance);
}
public static String replaceMentions(String oldText, BaseTranslator instance) {
try {
var matcher = Pattern.compile("(\\[(?:club|id|public)\\d+\\|[^]]+\\])|(@[^\\s]+)").matcher(oldText);
var mentionsCount = 0;
var textBuff = new StringBuffer();
var mentions = new ArrayList<String>();
while (matcher.find()) {
mentions.add(matcher.group());
matcher.appendReplacement(textBuff, "vtl_mention" + mentionsCount + ""); ++mentionsCount;
}
matcher.appendTail(textBuff);
var translatedText = instance.getTranslation(textBuff.toString());
var matcherMentions = Pattern.compile("vtl_mention(\\d+)").matcher(translatedText);
var retTextBuff = new StringBuffer();
while (matcherMentions.find()) {
matcherMentions.appendReplacement(retTextBuff, mentions.get(
Integer.parseInt(matcherMentions.group(1))
));
}
matcherMentions.appendTail(retTextBuff);
return retTextBuff.toString();
} catch(Exception e) {
e.printStackTrace();
return instance.getTranslation(oldText);
}
}
public static void onLongClick(View view) {
view.setOnLongClickListener(v -> {
argDialog(v.getContext());
return true;
});
}
public static void injRequest(MethodCall.a req) {
var time = expireTime();
if (time > 0) {
req.a("expire_ttl", time);
if (!savemsgsett()) bombCount = "0";
}
if (isSilentEnabled) {
req.a("silent", 1);
if (!savemsgsett()) isSilentEnabled = false;
}
}
private static int expireTime() {
switch (bombCount) {
case "15s":
return 15;
case "1m":
return 60;
case "5m":
return 300;
case "1h":
return 3600;
case "24h":
return 86400;
default:
return 0;
}
}
}
@@ -1,18 +1,23 @@
package ru.vtosters.lite.hooks;
import static java.lang.Long.MAX_VALUE;
import static ru.vtosters.lite.utils.Globals.getPrefsValue;
import static ru.vtosters.lite.utils.Newsfeed.checkCaption;
import static ru.vtosters.lite.utils.Newsfeed.checkCopyright;
import static ru.vtosters.lite.utils.Newsfeed.injectFiltersReposts;
import static ru.vtosters.lite.utils.Newsfeed.isAds;
import static ru.vtosters.lite.utils.Newsfeed.isAuthorRecommendations;
import static ru.vtosters.lite.utils.Newsfeed.isBadNews;
import static ru.vtosters.lite.utils.Newsfeed.isFriendsRecommendations;
import static ru.vtosters.lite.utils.Newsfeed.isGroupAds;
import static ru.vtosters.lite.utils.Newsfeed.isMusicBlock;
import static ru.vtosters.lite.utils.Newsfeed.isNewsBlock;
import static ru.vtosters.lite.utils.Newsfeed.isPostRecommendations;
import static ru.vtosters.lite.utils.Newsfeed.isRecomsGroup;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.checkCaption;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.checkCopyright;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.injectFiltersReposts;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.isAds;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.isAuthorRecommendations;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.isBadNews;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.isFriendsRecommendations;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.isGroupAds;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.isMusicBlock;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.isNewsBlock;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.isPostRecommendations;
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.isRecomsGroup;
import static ru.vtosters.lite.utils.Preferences.ads;
import static ru.vtosters.lite.utils.Preferences.adsslider;
import static ru.vtosters.lite.utils.Preferences.authorsrecomm;
import static ru.vtosters.lite.utils.Preferences.friendsrecomm;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Preferences.vkme;
@@ -22,10 +27,11 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
public class NewsfeedHook{
public static boolean injectFilters(JSONObject obj) throws JSONException{
public class NewsfeedHook {
public static boolean injectFilters(JSONObject obj) throws JSONException {
if (getBoolValue("newadblock", true)) return true;
var optString = obj.optString("type", "");
@@ -52,11 +58,11 @@ public class NewsfeedHook{
return !injectFiltersReposts(obj);
} // inject our filters to newsfeed, getpost and discover
public static long getUpdateNewsfeed(boolean refresh_timeout){
public static long getUpdateNewsfeed(boolean refresh_timeout) {
if (vkme()) {
return MAX_VALUE;
}
switch(getPrefsValue("newsupdate")) {
switch (getPrefsValue("newsupdate")) {
case "no_update":
return MAX_VALUE;
case "imd_update":
@@ -66,10 +72,48 @@ public class NewsfeedHook{
}
}
public static List hideElement(ArrayList list){
public static List hideElement(ArrayList list) {
if (!getBoolValue("whatsnew", true)) {
list.clear();
}
return list;
}
public static String[] feedParams(){
HashSet<String> params = new HashSet<>();
params.add("post");
params.add("photo");
params.add("photo_tag");
if (!friendsrecomm()) {
params.add("friends_recomm");
}
if (!ads()) {
params.add("app_widget");
params.add("promo_button");
}
if (!authorsrecomm()) {
params.add("authors_rec");
}
return params.toArray(new String[0]);
}
public static void adsParams(HashSet hashSet) {
if (ads() || adsslider()) {
hashSet.add("ads_disabled");
return;
}
hashSet.add("ads_app");
hashSet.add("ads_site");
hashSet.add("ads_post");
hashSet.add("ads_app_slider");
hashSet.add("ads_site_slider");
hashSet.add("ads_app_video");
hashSet.add("ads_post_pretty_cards");
hashSet.add("ads_post_snippet_video");
}
}
@@ -1,16 +1,14 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.hooks.JsonInjectors.setOnlineInfo;
import static ru.vtosters.lite.net.Request.makeRequest;
import static ru.vtosters.lite.utils.Globals.getString;
import static ru.vtosters.lite.utils.Globals.getUserId;
import static ru.vtosters.lite.utils.Globals.getUserToken;
import static ru.vtosters.lite.utils.Globals.sendToast;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
import static ru.vtosters.lite.utils.AndroidUtils.getString;
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
import static ru.vtosters.lite.utils.Preferences.dev;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Preferences.getPrefsFromFile;
import static ru.vtosters.lite.utils.Proxy.getApi;
import android.util.Log;
import static ru.vtosters.lite.utils.ProxyUtils.getApi;
import org.json.JSONArray;
import org.json.JSONException;
@@ -19,13 +17,13 @@ import org.json.JSONObject;
import java.io.IOException;
import java.text.ParseException;
public class OnlineFormatterHook{
public class OnlineFormatterHook {
private static String AppName;
public static String getAppName(int appid){ // thanks to egormetlitsky (vk mp3 mod) for helping with online ids
public static String getAppName(int appid) { // thanks to egormetlitsky (vk mp3 mod) for helping with online ids
if (appid <= 3 || !getBoolValue("onlineformatter", true)) return null;
switch(appid) {
switch (appid) {
case 2274003:
return "Android";
case 6328039:
@@ -133,7 +131,7 @@ public class OnlineFormatterHook{
}
public static String getAppNameFromOnline(int appid){
public static String getAppNameFromOnline(int appid) {
var prefs = getPrefsFromFile("onlines");
var appname = prefs.getString(String.valueOf(appid), null);
@@ -159,7 +157,7 @@ public class OnlineFormatterHook{
return AppName;
}
public static String getOnline(int appid){
public static String getOnline(int appid) {
var appname = getAppName(appid);
if (appname == null) return null;
@@ -167,7 +165,7 @@ public class OnlineFormatterHook{
return getString("custom_online") + " " + appname;
}
public static JSONObject onlineHook(JSONObject json, boolean isGlobalHook) throws ParseException, IOException, JSONException{
public static JSONObject onlineHook(JSONObject json, boolean isGlobalHook) throws ParseException, IOException, JSONException {
if (!getBoolValue("onlinefix", false)) return json;
if (isGlobalHook && !getBoolValue("globalUsersOnline", false)) {
@@ -1,8 +1,9 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.Globals.getIdentifier;
import static ru.vtosters.lite.utils.Globals.getPreferences;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
@@ -31,42 +32,43 @@ import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import ru.vtosters.lite.utils.Globals;
import ru.vtosters.lite.utils.Themes;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.ThemesUtils;
public class PhotoViewer {
static OkHttpClient client = new OkHttpClient();
public static boolean interceptClick(AttachmentWithMedia attachment, MenuItem item, View view) {
if (item.getItemId() == Globals.getIdentifier("search_photo", "id")) {
if (item.getItemId() == AndroidUtils.getIdentifier("search_photo", "id")) {
searchPhoto(getUrlFromAttachment((PhotoAttachment) attachment));
return true;
} else if (item.getItemId() == Globals.getIdentifier("copy_photo_url", "id")) {
} else if (item.getItemId() == AndroidUtils.getIdentifier("copy_photo_url", "id")) {
copyPhotoUrl(getUrlFromAttachment((PhotoAttachment) attachment));
return true;
} else if (item.getItemId() == Globals.getIdentifier("open_original_photo", "id")) {
} else if (item.getItemId() == AndroidUtils.getIdentifier("open_original_photo", "id")) {
openUrl(getUrlFromAttachment((PhotoAttachment) attachment));
return true;
}
return true;
}
@SuppressLint("UseCompatLoadingForDrawables")
public static void addMenuItems(AttachmentWithMedia attachment, ActionsPopup.b actionPopup, int i, boolean z) {
actionPopup.a(getIdentifier("search_photo_content", "string"),
Themes.isDarkTheme()
? Globals.getContext().getDrawable(R.drawable.ic_menu_search_outline_28)
: new RecoloredDrawable(Globals.getContext().getDrawable(R.drawable.ic_menu_search_outline_28), Themes.getAccentColor()),
ThemesUtils.isDarkTheme()
? AndroidUtils.getGlobalContext().getDrawable(R.drawable.ic_menu_search_outline_28)
: new RecoloredDrawable(AndroidUtils.getGlobalContext().getDrawable(R.drawable.ic_menu_search_outline_28), ThemesUtils.getAccentColor()),
false,
() -> {
searchPhoto(getUrlFromAttachment((PhotoAttachment) attachment));
return null;
}
() -> {
searchPhoto(getUrlFromAttachment((PhotoAttachment) attachment));
return null;
}
);
actionPopup.a(getIdentifier("copy_photo_url_content", "string"),
!Themes.isDarkTheme()
? new RecoloredDrawable(Globals.getContext().getDrawable(R.drawable.ic_copy_outline_28), Themes.getAccentColor())
: new RecoloredDrawable(Globals.getContext().getDrawable(R.drawable.ic_copy_outline_28), Color.WHITE),
!ThemesUtils.isDarkTheme()
? new RecoloredDrawable(AndroidUtils.getGlobalContext().getDrawable(R.drawable.ic_copy_outline_28), ThemesUtils.getAccentColor())
: new RecoloredDrawable(AndroidUtils.getGlobalContext().getDrawable(R.drawable.ic_copy_outline_28), Color.WHITE),
false,
() -> {
copyPhotoUrl(getUrlFromAttachment((PhotoAttachment) attachment));
@@ -74,10 +76,10 @@ public class PhotoViewer {
}
);
actionPopup.a(getIdentifier("open_original_photo_content", "string"),
Themes.isDarkTheme()
? Globals.getContext().getDrawable(R.drawable.ic_link_outline_28)
: new RecoloredDrawable(Globals.getContext().getDrawable(R.drawable.ic_link_outline_28),
Themes.getAccentColor()),
ThemesUtils.isDarkTheme()
? AndroidUtils.getGlobalContext().getDrawable(R.drawable.ic_link_outline_28)
: new RecoloredDrawable(AndroidUtils.getGlobalContext().getDrawable(R.drawable.ic_link_outline_28),
ThemesUtils.getAccentColor()),
false,
() -> {
openUrl(getUrlFromAttachment((PhotoAttachment) attachment));
@@ -99,7 +101,7 @@ public class PhotoViewer {
}
return max.url;
}
private static void searchPhoto(String url) {
if (url == null || url.isEmpty()) return;
switch (getPreferences().getInt("search_engine", 0)) {
@@ -123,7 +125,7 @@ public class PhotoViewer {
client.a(request).a(new Callback() {
@Override
public void a(Call call, IOException e) {
Log.d("PhotoViewer", e+"");
Log.d("PhotoViewer", e + "");
}
@Override
@@ -153,15 +155,15 @@ public class PhotoViewer {
private static void copyPhotoUrl(String url) {
if (url == null || url.isEmpty()) return;
ClipboardManager manager = (ClipboardManager) Globals.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipboardManager manager = (ClipboardManager) AndroidUtils.getGlobalContext().getSystemService(Context.CLIPBOARD_SERVICE);
manager.setPrimaryClip(ClipData.newPlainText("vk_photo_url", url));
Toast.makeText(Globals.getContext(), Globals.getIdentifier("copied_to_clipboard", "string"), Toast.LENGTH_SHORT).show();
Toast.makeText(AndroidUtils.getGlobalContext(), AndroidUtils.getIdentifier("copied_to_clipboard", "string"), Toast.LENGTH_SHORT).show();
}
private static void openUrl(String url) {
var uri = Uri.parse(url);
var intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Globals.getContext().startActivity(intent);
AndroidUtils.getGlobalContext().startActivity(intent);
}
}
@@ -0,0 +1,66 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.Preferences.preferences;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import com.facebook.drawee.generic.RoundingParams;
import ru.vtosters.lite.utils.AndroidUtils;
public class PicRoundingHook{
private static final int pref = preferences.getInt("pic_rounding", 0);
public static RoundingParams inject() {
if (pref > 0) {
return customParams();
} else {
return new RoundingParams().a(true);
}
}
public static RoundingParams inject(float orig) {
if (pref > 0) {
return customParams();
} else {
return new RoundingParams().b(orig);
}
}
public static RoundingParams inject(float orig, float orig2, float orig3, float orig4) {
if (pref > 0) {
return new RoundingParams().a(AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref));
} else {
return new RoundingParams().a(orig, orig2, orig3, orig4);
}
}
public static void inject(float orig, Canvas canvas, Paint paint){
if (pref > 0) {
canvas.drawRoundRect(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), paint);
} else {
canvas.drawCircle(orig, orig, orig, paint);
}
}
public static void inject(Bitmap bitmap, Bitmap bitmap2, Paint b2) {
Shader.TileMode tileMode = Shader.TileMode.CLAMP;
b2.setShader(new BitmapShader(bitmap2, tileMode, tileMode));
Canvas canvas = new Canvas(bitmap);
float width = bitmap2.getWidth() / 2;
if (pref > 0) {
canvas.drawRoundRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), b2);
} else {
canvas.drawCircle(width, width, width, b2);
}
}
private static RoundingParams customParams(){
return RoundingParams.b(AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref));
}
}
@@ -9,8 +9,8 @@ import android.widget.TextView;
import com.vk.dto.polls.PollOption;
import com.vk.polls.ui.views.PollOptionView;
public class PollHook{
public static void show(PollOptionView view){
public class PollHook {
public static void show(PollOptionView view) {
if (!getBoolValue("pollresults", false)) return;
TextView resultsView = view.c;
@@ -0,0 +1,67 @@
package ru.vtosters.lite.hooks;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import androidx.recyclerview.widget.RecyclerView;
import com.vk.newsfeed.holders.BaseFooterHolder;
import com.vtosters.lite.R;
import ru.vtosters.lite.utils.Preferences;
public class PostViewHook {
/**
* For displaying child elements with custom direction in rtl container we should remove their, set layout direction and add again */
private static void saveChildDirectionForRlt(ViewGroup container) {
var children = new View[container.getChildCount()];
for (int i = 0; i < container.getChildCount(); i++) {
var child = container.getChildAt(i);
child.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
children[i] = child;
}
container.removeAllViews();
for (View child : children) {
container.addView(child);
}
container.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
}
// res/layout/likes_panel.xml
public static void injectBaseFooterHolder(BaseFooterHolder baseFooterHolder) {
if (!Preferences.isLikesOnRightEnabled())
return;
try {
var container = (ViewGroup) ((RecyclerView.ViewHolder) baseFooterHolder).itemView;
saveChildDirectionForRlt((ViewGroup) container.getChildAt(1));
} catch (Exception e) {
e.printStackTrace();
}
}
// res/layout/photo_viewer_bottom.xml
public static void injectPhotoViewer(View container) {
if (!Preferences.isLikesOnRightEnabled())
return;
try {
var bottomPanel = (ViewGroup) container.findViewById(R.id.photo_viewer_bottom_panel);
saveChildDirectionForRlt(bottomPanel);
} catch (Exception e) {
e.printStackTrace();
}
}
// res/layout/video_bottom_view.xml
public static void injectVideoView(RelativeLayout container) {
if (!Preferences.isLikesOnRightEnabled())
return;
try {
var bottomBar = (ViewGroup) container.findViewById(R.id.bottom_bar);
saveChildDirectionForRlt(bottomBar);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -1,13 +1,14 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.Globals.convertDpToPixel;
import static ru.vtosters.lite.utils.Globals.edit;
import static ru.vtosters.lite.utils.Globals.getPrefsValue;
import static ru.vtosters.lite.utils.Globals.restartApplication;
import static ru.vtosters.lite.utils.Proxy.apiproxy;
import static ru.vtosters.lite.utils.Proxy.isZaboronaEnabled;
import static ru.vtosters.lite.utils.Themes.getAccentColor;
import static ru.vtosters.lite.utils.Themes.getAlertStyle;
import static ru.vtosters.lite.utils.Themes.getTextAttr;
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.LifecycleUtils.restartApplication;
import static ru.vtosters.lite.utils.ProxyUtils.apiproxy;
import static ru.vtosters.lite.utils.ProxyUtils.isZaboronaEnabled;
import static ru.vtosters.lite.utils.ThemesUtils.getAccentColor;
import static ru.vtosters.lite.utils.ThemesUtils.getAlertStyle;
import static ru.vtosters.lite.utils.ThemesUtils.getTextAttr;
import android.annotation.SuppressLint;
import android.content.Context;
@@ -27,15 +28,15 @@ import com.vk.navigation.Navigator;
import ru.vtosters.lite.ui.fragments.ProxySettingsFragment;
public class ProxyHook{
public static void hookAuth(View v){
public class ProxyHook {
public static void hookAuth(View v) {
VkAuthTextView button = (VkAuthTextView) v;
button.setText("Настроить прокси");
button.setOnClickListener(v1 -> callProxyDialog(v1.getContext()));
}
@SuppressLint("SetTextI18n")
public static void callProxyDialog(Context ctx){
public static void callProxyDialog(Context ctx) {
RadioGroup rg = new RadioGroup(ctx);
RadioButton rgDefault = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
@@ -44,10 +45,10 @@ public class ProxyHook{
rg.addView(rgDefault);
rg.addView(rgProxy);
rgDefault.setTextSize(TypedValue.COMPLEX_UNIT_PX, convertDpToPixel(14f));
rgProxy.setTextSize(TypedValue.COMPLEX_UNIT_PX, convertDpToPixel(14f));
rgDefault.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
rgProxy.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
rg.setPadding(convertDpToPixel(18f), convertDpToPixel(12f), convertDpToPixel(18f), 0);
rg.setPadding(dp2px(18f), dp2px(12f), dp2px(18f), 0);
rgDefault.setText("Отключить");
rgDefault.setTextColor(getTextAttr());
@@ -90,7 +91,7 @@ public class ProxyHook{
alert.getButton(DialogInterface.BUTTON_NEUTRAL).setTextColor(getAccentColor());
}
public static String linkReplacer(String link){
public static String linkReplacer(String link) {
var vkapi = "api.vk.com";
var oauth = "oauth.vk.com";
var vkstatic = "static.vk.com";
@@ -123,7 +124,7 @@ public class ProxyHook{
return link;
}
public static String getAwayPhpCom(){
public static String getAwayPhpCom() {
var proxyapi = getPrefsValue("proxyapi");
if (apiproxy() & !proxyapi.isEmpty()) {
@@ -0,0 +1,26 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.Preferences.dev;
import android.util.Log;
import com.vk.api.internal.MethodCall;
import java.util.LinkedHashMap;
public class RequestDumper{
public static void addParams(MethodCall.a paramslist, String method, LinkedHashMap params, String apiver) {
if (method.contains("execute.getGiftByStickerId") || method.contains("execute.getNewsfeedCustom")) {
apiver = "5.187";
}
if (dev()) {
Log.d("RequestDumper", "Method: " + method);
Log.d("RequestDumper", "API version: " + apiver);
Log.d("RequestDumper", "Params: " + params);
}
paramslist.a(method);
paramslist.a(params);
paramslist.b(apiver);
}
}
@@ -1,11 +1,12 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.ui.components.DockBarEditorManager.getInstance;
import static ru.vtosters.lite.utils.Globals.getPrefsValue;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Preferences.milkshake;
import static ru.vtosters.lite.utils.Preferences.superapp;
import static ru.vtosters.lite.utils.Preferences.useNewSettings;
import static ru.vtosters.lite.utils.Preferences.videoewcatalog;
import static ru.vtosters.lite.utils.Preferences.videonewcatalog;
import static ru.vtosters.lite.utils.Preferences.vkme;
import com.vk.apps.AppsFragment;
@@ -33,12 +34,12 @@ import com.vtosters.lite.fragments.y2.VideosFragment;
import com.vtosters.lite.general.fragments.GamesFragment;
import com.vtosters.lite.general.fragments.PhotosFragment;
public class StartFragmentHook{
public static Class getStartFragment(){
public class StartFragmentHook {
public static Class getStartFragment() {
if (vkme()) {
return DialogsFragment.class;
}
switch(getPrefsValue("start_values")) {
switch (getPrefsValue("start_values")) {
case "newsfeed":
return milkshake() ? HomeFragment.class : NewsfeedFragment.class;
case "messenger":
@@ -52,7 +53,7 @@ public class StartFragmentHook{
case "photos":
return PhotosFragment.class;
case "videos":
return videoewcatalog() ? VideoCatalogFragment.class : VideosFragment.class;
return videonewcatalog() ? VideoCatalogFragment.class : VideosFragment.class;
case "settings":
return useNewSettings();
case "apps":
@@ -1,13 +1,14 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.Preferences.adsstories;
import static ru.vtosters.lite.utils.Preferences.stories;
public class StoriesHook{
public static String ads(){
public class StoriesHook {
public static String ads() {
return adsstories() ? "null" : "ads";
}
public static boolean showstories(){
public static boolean showstories() {
return stories();
}
}
@@ -1,8 +1,9 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.Preferences.*;
import static ru.vtosters.lite.utils.Preferences.feedcache;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Preferences.milkshake;
import static ru.vtosters.lite.utils.Preferences.miniapps;
import static ru.vtosters.lite.utils.Preferences.musicnewcatalog;
import static ru.vtosters.lite.utils.Preferences.postsredesign;
import static ru.vtosters.lite.utils.Preferences.superapp;
@@ -10,11 +11,9 @@ import static ru.vtosters.lite.utils.Preferences.superapp;
import com.vk.toggle.FeatureManager;
import com.vk.toggle.Features;
import ru.vtosters.lite.utils.Preferences;
public class TogglesHook{
public static boolean shouldPatch(Features.Type feature){
switch(feature) {
public class TogglesHook {
public static boolean shouldPatch(Features.Type feature) {
switch (feature) {
case AB_IM_LONGPOLL_MSG_BATCHING:
case AB_IM_VIEW_POOL:
case AB_MULTI_GIFTS:
@@ -44,7 +43,6 @@ public class TogglesHook{
case FEATURE_ML_FEATURES:
case FEATURE_ML_MODELS_LOADING:
case FEATURE_MONEY_TRANSFERS_VKPAY:
case FEATURE_MOZJPEG:
case FEATURE_MUSIC_ARTIST_CATALOG:
case FEATURE_MUSIC_NEW_CATALOG:
case FEATURE_NARRATIVE_SNIPPET_TYPE:
@@ -124,8 +122,8 @@ public class TogglesHook{
}
}
public static boolean redirect(Features.Type feature){
switch(feature) {
public static boolean redirect(Features.Type feature) {
switch (feature) {
case EXPERIMENT_NEWS_DISABLE_CACHE:
return !feedcache();
case FEATURE_SUPERAPP_MENU:
@@ -150,7 +148,7 @@ public class TogglesHook{
}
}
public static FeatureManager.b redirectStrings(Features.Type feature){
public static FeatureManager.b redirectStrings(Features.Type feature) {
return null;
}
}
@@ -1,15 +1,18 @@
package ru.vtosters.lite.hooks;
import static android.util.Base64.encodeToString;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.Globals.getPrefsValue;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Themes.getAccentColor;
import static ru.vtosters.lite.utils.Themes.getBackgroundContent;
import static ru.vtosters.lite.utils.Themes.getBackgroundPage;
import static ru.vtosters.lite.utils.Themes.getHeaderBackground;
import static ru.vtosters.lite.utils.Themes.getHeaderText;
import static ru.vtosters.lite.utils.Themes.getTextAttr;
import static ru.vtosters.lite.utils.Themes.hex;
import static ru.vtosters.lite.utils.ThemesUtils.getAccentColor;
import static ru.vtosters.lite.utils.ThemesUtils.getAttrId;
import static ru.vtosters.lite.utils.ThemesUtils.getBackgroundContent;
import static ru.vtosters.lite.utils.ThemesUtils.getBackgroundPage;
import static ru.vtosters.lite.utils.ThemesUtils.getColorFromAttr;
import static ru.vtosters.lite.utils.ThemesUtils.getHeaderBackground;
import static ru.vtosters.lite.utils.ThemesUtils.getHeaderText;
import static ru.vtosters.lite.utils.ThemesUtils.getTextAttr;
import static ru.vtosters.lite.utils.ThemesUtils.hex;
import android.webkit.WebView;
@@ -22,19 +25,19 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
public class VKUIHook{
public class VKUIHook {
public static boolean isLoaded = false;
private static String loadedCSS = "";
private static String loadedCSSAmoled = "";
private static String load(String str){
private static String load(String str) {
try {
InputStream open = getContext().getAssets().open(str);
InputStream open = getGlobalContext().getAssets().open(str);
StringBuilder sb = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(open, StandardCharsets.UTF_8));
while(true) {
while (true) {
String readLine = bufferedReader.readLine();
if (readLine != null) {
sb.append(readLine);
@@ -51,24 +54,29 @@ public class VKUIHook{
}
}
public static void load(){
public static void load() {
loadedCSS = load("vt_ui_accent.css")
.replace("%header_background%", hex(getHeaderBackground()))
.replace("%background_content%", hex(getBackgroundContent()))
.replace("%header_text%", hex(getHeaderText()))
.replace("%accent%", hex(getAccentColor()))
.replace("%background_page%", hex(getBackgroundPage()))
.replace("%content_tint_background%", hex(getColorFromAttr(getAttrId("content_tint_background"))))
.replace("%button_primary_background%", hex(getColorFromAttr(getAttrId("button_primary_background"))))
.replace("%button_outline_foreground%", hex(getColorFromAttr(getAttrId("button_outline_foreground"))))
.replace("%button_outline_border%", hex(getColorFromAttr(getAttrId("button_outline_border"))))
.replace("%text_primary%", hex(getTextAttr()));
loadedCSSAmoled = load("vt_ui_oled.css");
isLoaded = true;
}
private static void inject(WebView webView, String str){
private static void inject(WebView webView, String str) {
webView.loadUrl("javascript:(function() {var parent = document.getElementsByTagName('head').item(0);var style = document.createElement('style');style.type = 'text/css';style.innerHTML = window.atob('" + str + "');parent.appendChild(style)})()");
}
public static void inject(WebView webView){
public static void inject(WebView webView) {
String string = getPrefsValue("darktheme");
if (getBoolValue("VKUI_INJ", true)) {
@@ -93,10 +101,10 @@ public class VKUIHook{
}
}
public static void clearWebCache(){
public static void clearWebCache() {
ThemeTracker.a();
isLoaded = false;
new WebView(getContext()).clearCache(true);
new WebView(getGlobalContext()).clearCache(true);
WebCachePreloader.e();
}
}
@@ -1,6 +1,6 @@
package ru.vtosters.lite.music;
public interface Callback{
public interface Callback {
void onProgress(int progress);
void onSuccess();
@@ -11,21 +11,22 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import ru.vtosters.lite.utils.Globals;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.IOUtils;
public class FFMpeg{
public class FFMpeg {
private static final int BUFFER_SIZE = 2048;
private static void copyAssets(){
private static void copyAssets() {
try {
String[] files = Globals.getContext().getAssets().list("ffmpeg");
String[] files = AndroidUtils.getGlobalContext().getAssets().list("ffmpeg");
for (String file : files) {
if (file.endsWith(".so")) {
InputStream in = Globals.getContext().getAssets().open("ffmpeg" + File.separator + file);
FileOutputStream out = new FileOutputStream(Globals.getContext().getFilesDir() + File.separator + file);
InputStream in = AndroidUtils.getGlobalContext().getAssets().open("ffmpeg" + File.separator + file);
FileOutputStream out = new FileOutputStream(AndroidUtils.getGlobalContext().getFilesDir() + File.separator + file);
byte[] buffer = new byte[BUFFER_SIZE];
int read;
while((read = in.read(buffer)) != -1) {
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
@@ -37,15 +38,15 @@ public class FFMpeg{
}
}
private static void checkFFMpegLibs(){
var lib = new File(Globals.getContext().getFilesDir(), "libffmpegkit_abidetect.so");
private static void checkFFMpegLibs() {
var lib = new File(AndroidUtils.getGlobalContext().getFilesDir(), "libffmpegkit_abidetect.so");
if (!lib.exists()) {
ToastUtils.a("Копирование библиотеки ffmpegkit");
copyAssets();
}
}
public static boolean convert(String in, String out){
public static boolean convert(String in, String out) {
checkFFMpegLibs();
// write the list of all .ts files to a txt file in "in" directory
@@ -64,9 +65,8 @@ public class FFMpeg{
e.printStackTrace();
}
// concatenate .ts files to a single .ts file
var concat = FFmpegKit.execute("-f concat -safe 0 -i " + in + "/list.txt -c copy " + in + "/all.ts");
FFmpegKit.execute("-f concat -safe 0 -i " + in + "/list.txt -c copy " + in + "/all.ts");
// convert .ts file to .mp3 file via ffmpeg
var session = FFmpegKit.execute("-i " + in + "/all.ts -f mp3 -acodec mp3 -q:a 0 -y '" + out + "'");
@@ -74,17 +74,11 @@ public class FFMpeg{
if (ReturnCode.isSuccess(rc)) {
// remove temp files
deleteRecursively(new File(in));
IOUtils.deleteRecursive(new File(in));
return true;
} else {
Log.e("FFMpeg", "FFmpegKit failed with return code " + rc);
return false;
}
}
private static void deleteRecursively(File fileOrDirectory){
if (fileOrDirectory.isDirectory()) for (File child : fileOrDirectory.listFiles())
deleteRecursively(child);
fileOrDirectory.delete();
Log.e("FFMpeg", "FFmpegKit failed with return code " + rc);
return false;
}
}
@@ -16,64 +16,55 @@ import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import ru.vtosters.lite.utils.StreamUtils;
import ru.vtosters.lite.utils.IOUtils;
public class M3UDownloader{
public class M3UDownloader {
private final String mURL;
private final File mOutDir;
private final Callback mCallback;
private OkHttpClient mClient = new OkHttpClient();
private static OkHttpClient client = new OkHttpClient();
public M3UDownloader(String url, File outDir, Callback callback){
mURL = url;
mOutDir = outDir;
mCallback = callback;
}
public void execute(){
public static void execute(String url, File outDir, Callback callback) {
var request = new Request.a()
.b(mURL)
.b(url)
.a();
mClient.a(request).a(new okhttp3.Callback(){
client.a(request).a(new okhttp3.Callback() {
@Override
public void a(Call call, IOException e){
public void a(Call call, IOException e) {
}
@Override
public void a(Call call, Response response) throws IOException{
parse(response.a().g());
public void a(Call call, Response response) throws IOException {
parse(response.a().g(), outDir, callback);
}
});
}
private void parse(String payload){
private static void parse(String payload, File outDir, Callback callback) {
try {
VKM3UParser parser = new VKM3UParser(payload);
List<TransportStream> tses = parser.getTransportStreams();
mCallback.onProgress(5);
callback.onProgress(5);
for (TransportStream ts : tses) {
String tsURL = parser.getBaseUrl() + ts.getName();
Log.d("M3UDownloader", "Downloading " + tsURL);
InputStream is = StreamUtils.openStream(tsURL);
InputStream is = IOUtils.openStream(tsURL);
byte[] content;
if (TransportStream.METHOD_AES128.equals(ts.getMethod())) {
String key = StreamUtils.readAllLines(StreamUtils.openStream(ts.getKeyURL()));
content = StreamUtils.decodeStream(is, key);
String key = IOUtils.readAllLines(IOUtils.openStream(ts.getKeyURL()));
content = IOUtils.decodeStream(is, key);
} else {
content = StreamUtils.readAllBytes(is);
content = IOUtils.readAllBytes(is);
}
File tsDump = new File(mOutDir, ts.getName());
StreamUtils.writeToFile(tsDump, content);
mCallback.onSizeReceived((long) content.length * tses.size(), parser.getHeapSize());
mCallback.onProgress(10 + Math.round(80.0f * tses.indexOf(ts) / tses.size()));
File tsDump = new File(outDir, ts.getName());
IOUtils.writeToFile(tsDump, content);
callback.onSizeReceived((long) content.length * tses.size(), parser.getHeapSize());
callback.onProgress(10 + Math.round(80.0f * tses.indexOf(ts) / tses.size()));
}
} catch (IOException | NoSuchPaddingException | NoSuchAlgorithmException | InvalidAlgorithmParameterException | InvalidKeyException e) {
e.printStackTrace();
mCallback.onFailure();
callback.onFailure();
return;
}
mCallback.onSuccess();
callback.onSuccess();
}
}
@@ -1,11 +1,16 @@
package ru.vtosters.lite.music;
import static ru.vtosters.lite.utils.Preferences.getMusicDir;
import android.app.DownloadManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.RequiresApi;
import com.vk.dto.music.MusicTrack;
import org.json.JSONException;
@@ -19,20 +24,17 @@ import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import ru.vtosters.lite.downloaders.AudioDownloader;
import ru.vtosters.lite.utils.Globals;
import ru.vtosters.lite.utils.AndroidUtils;
public class MP3Downloader {
private static final String URL_FORMAT = "https://api.vk.com/method/audio.getById?v=5.131&access_token=%s&audios=%s&copyright=https://vtosters.app/";
private static final OkHttpClient client = new OkHttpClient();
public MP3Downloader() {
}
public void execute(MusicTrack track) {
var token = Globals.getPreferences().getString("vk_admin_token", "");
public static void execute(MusicTrack track) {
var token = AndroidUtils.getPreferences().getString("vk_admin_token", "");
if (token.isEmpty()) {
Toast.makeText(Globals.getContext(), "Обновите токен VK Admin в настройках", Toast.LENGTH_SHORT).show();
Toast.makeText(AndroidUtils.getGlobalContext(), "Обновите токен VK Admin в настройках", Toast.LENGTH_SHORT).show();
return;
}
var request = new Request.a()
@@ -41,7 +43,7 @@ public class MP3Downloader {
client.a(request).a(new Callback() {
@Override
public void a(Call call, IOException e) {
Log.d("MP3Downloader", e+"");
Log.d("MP3Downloader", e + "");
}
@Override
@@ -49,36 +51,35 @@ public class MP3Downloader {
var payload = response.a().g();
Log.d("MP3Downloader", payload);
try {
JSONObject jsonObj = new JSONObject(payload);
if (jsonObj.has("response")) {
JSONObject responseNode = new JSONObject(payload).getJSONArray("response")
.getJSONObject(0);
if (responseNode.has("url")) {
var url = responseNode.optString("url");
Log.d("MP3Downloader", url);
if (url != null) {
if (url.endsWith(".mp3")) {
downloadMP3(track.toString(), url);
} else if (VKM3UParser.isM3U8(url)) {
AudioDownloader.downloadM3U8(track);
}
}
}
}
JSONObject jsonObj = new JSONObject(payload);
if (jsonObj.has("response")) {
JSONObject responseNode = new JSONObject(payload).getJSONArray("response")
.getJSONObject(0);
if (responseNode.has("url")) {
var url = responseNode.optString("url");
Log.d("MP3Downloader", url);
if (url.endsWith(".mp3")) {
downloadMP3(track.toString(), url);
} else if (VKM3UParser.isM3U8(url)) {
AudioDownloader.downloadM3U8(track);
}
}
}
} catch (JSONException e) {
Log.d("MP3Downloader", e+"");
Log.d("MP3Downloader", e + "");
}
}
});
}
private void downloadMP3(String title, String url) {
var downloadManager = Globals.getContext().getSystemService(DownloadManager.class);
@RequiresApi(api = Build.VERSION_CODES.M)
private static void downloadMP3(String title, String url) {
var downloadManager = AndroidUtils.getGlobalContext().getSystemService(DownloadManager.class);
var request = new DownloadManager.Request(Uri.parse(url))
.setAllowedOverRoaming(true)
.setTitle("Downloading " + title)
.setDestinationInExternalFilesDir(Globals.getContext(),
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(),
.setDestinationInExternalFilesDir(AndroidUtils.getGlobalContext(),
getMusicDir().getAbsolutePath(),
title + ".mp3")
.setVisibleInDownloadsUi(true);
downloadManager.enqueue(request);
@@ -0,0 +1,176 @@
package ru.vtosters.lite.music;
import static java.lang.String.valueOf;
import static ru.vtosters.lite.utils.AndroidUtils.MD5;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.AndroidUtils.getDefaultPrefs;
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
import android.util.Log;
import com.vk.dto.music.MusicTrack;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import java.util.TreeMap;
import ru.vtosters.lite.net.NetCall;
import ru.vtosters.lite.net.NetCallback;
import ru.vtosters.lite.net.NetClient;
import ru.vtosters.lite.net.NetRequest;
import ru.vtosters.lite.net.NetResponse;
public class Scrobbler {
private static final String key = "5965d63402414776c54c266db0211746";
private static final String keysecret = "d982180eed13275bb948e41cf225f88f";
private static final String url = "https://ws.audioscrobbler.com/2.0/";
private static final NetClient client = new NetClient.Builder().build();
private static final ArrayList<String> scrobbled = new ArrayList<>();
public static void scrobbleTrack(long duration, String artist, String title, String uid) {
var string = getDefaultPrefs().getString("sessionKey", null);
var timestamp = System.currentTimeMillis() / 1000;
Log.d("Scrobbler", "scrobbleTrack: " + title + " - " + artist + " - " + duration + " - " + uid);
if (!needToBeScrobble(uid) ||
string == null ||
string.isEmpty() ||
artist == null ||
artist.isEmpty() ||
title == null ||
title.isEmpty() ||
duration == 0) return;
scrobbled.add(uid); // add to scrobbled list
TreeMap<String, String> treeMap = new TreeMap<>(); // create map for request
treeMap.put("method", "track.scrobble");
treeMap.put("sk", string);
treeMap.put("artist[0]", artist);
treeMap.put("track[0]", title);
treeMap.put("timestamp[0]", valueOf(timestamp));
treeMap.put("api_key", key);
treeMap.put("duration[0]", valueOf(duration));
treeMap.put("api_sig", signMD5(treeMap));
treeMap.put("format", "json");
client.newCall(new NetRequest.Builder().url(url).post().params(treeMap).build()).enqueue(new NetCallback() {
@Override
public void onFailure(NetCall call, IOException e) {
Log.d("Scrobbler", "Error: " + e.getMessage());
}
@Override
public void onResponse(NetCall call, NetResponse response) {
Log.d("Scrobbler", "Scrobbled: " + artist + " - " + title);
Log.d("Scrobbler", "Response scrobble: " + response.getDataString());
}
});
}
public static void grabMusicTrack(MusicTrack musictrack) {
var uid = musictrack.y1();
var artist = musictrack.C;
var title = musictrack.f;
var duration = musictrack.h;
if (uid.isEmpty() || artist == null || artist.isEmpty() || title == null || title.isEmpty() || duration == 0) {
Log.d("Scrobbler", "grabTrackInfo: " + "Empty track, info: " + artist + " - " + title + " - " + duration + " - " + uid);
return;
}
scrobbleTrack(duration, artist, title, uid);
}
private static String signMD5(Map<String, String> map) {
var sb = new StringBuilder();
for (Map.Entry<String, String> entry : map.entrySet()) {
sb.append(entry.getKey());
sb.append(entry.getValue());
}
sb.append(keysecret);
return MD5(sb.toString());
}
public static void auth(String login, String pass) {
if (login == null || pass == null) {
sendToast("Логин или пароль не заданы");
return;
}
TreeMap<String, String> treeMap = new TreeMap<>(); // create map for request
treeMap.put("method", "auth.getMobileSession");
treeMap.put("api_key", key);
treeMap.put("username", login);
treeMap.put("password", pass);
treeMap.put("api_sig", signMD5(treeMap));
treeMap.put("format", "json");
client.newCall(new NetRequest.Builder().url(url).post().params(treeMap).build()).enqueue(new NetCallback() {
@Override
public void onFailure(NetCall call, IOException e) {
Log.d("Scrobbler", "Auth failed", e);
sendToast("Ошибка входа");
}
@Override
public void onResponse(NetCall call, NetResponse response) {
try {
var jSONObject = new JSONObject(response.getDataString());
sessionFetcher(jSONObject);
Log.d("Scrobbler", "Auth response " + response.getDataString());
} catch (JSONException e) {
Log.d("Scrobbler", "Auth failed", e);
}
}
});
}
public static void sessionFetcher(JSONObject jsonObject) throws JSONException {
if (!jsonObject.has("session")) {
Log.d("Scrobbler", "Auth failed - no session");
return;
}
var session = jsonObject.getJSONObject("session");
var name = session.getString("name");
var key = session.getString("key");
getDefaultPrefs().edit().putString("username", name).
putString("sessionKey", key).apply();
Log.d("Scrobbler", "Auth success as " + name + ", key " + key);
}
public static void logout() {
edit().remove("username").apply();
edit().remove("sessionKey").apply();
scrobbled.clear();
sendToast("Вы успешно вышли из учетной записи");
}
public static boolean needToBeScrobble(String uid) {
return isLoggedIn() && isScrobblingEnabled() && !scrobbled.contains(uid);
}
public static boolean isLoggedIn() {
return getDefaultPrefs().getString("sessionKey", null) != null;
}
public static boolean isScrobblingEnabled() {
return getPreferences().getBoolean("lastfm_enabled", false);
}
public static String getUserName() {
return getDefaultPrefs().getString("username", null);
}
}
@@ -1,6 +1,6 @@
package ru.vtosters.lite.music;
public class TransportStream{
public class TransportStream {
public static final String METHOD_NONE = "NONE";
public static final String METHOD_AES128 = "AES-128";
@@ -9,28 +9,28 @@ public class TransportStream{
private String mName;
private String mKeyURL;
public TransportStream(){
public TransportStream() {
this.mMethod = METHOD_NONE;
}
public TransportStream(String method, String keyURL){
public TransportStream(String method, String keyURL) {
this.mMethod = method;
this.mKeyURL = keyURL;
}
public String getMethod(){
public String getMethod() {
return mMethod;
}
public String getName(){
public String getName() {
return mName;
}
public void setName(String name){
public void setName(String name) {
mName = name;
}
public String getKeyURL(){
public String getKeyURL() {
return mKeyURL;
}
}
@@ -4,7 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class VKM3UParser{
public class VKM3UParser {
private final String mData;
private final List<TransportStream> mTransportStreams = new ArrayList<>();
@@ -13,15 +13,15 @@ public class VKM3UParser{
private int mHeapSize = 0;
private String mBaseURL;
public VKM3UParser(String data){
public VKM3UParser(String data) {
mData = data;
init();
}
private void init(){
private void init() {
int i = 0;
Scanner scanner = new Scanner(mData);
while(scanner.hasNext()) {
while (scanner.hasNext()) {
String line = scanner.nextLine();
mHeapSize += line.getBytes().length;
if (line.startsWith("#EXT-X-TARGETDURATION")) {
@@ -47,7 +47,7 @@ public class VKM3UParser{
}
}
private String getDirectiveValue(String directive){
private String getDirectiveValue(String directive) {
return directive.substring(directive.indexOf(":") + 1);
}
@@ -55,15 +55,15 @@ public class VKM3UParser{
return str.endsWith(".ts") || str.endsWith(".tp") || str.endsWith(".mpeg-ts") || str.endsWith(".m2ts");
}
public int getHeapSize(){
public int getHeapSize() {
return mHeapSize;
}
public String getBaseUrl(){
public String getBaseUrl() {
return mBaseURL;
}
public List<TransportStream> getTransportStreams(){
public List<TransportStream> getTransportStreams() {
return mTransportStreams;
}
}
@@ -1,6 +1,7 @@
package ru.vtosters.lite.net;
import android.util.Base64;
import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -15,16 +16,16 @@ import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.TreeMap;
public final class NetCall{
public final class NetCall {
private final NetRequest req;
private final NetClient cl;
protected NetCall(NetClient cl, NetRequest req){
protected NetCall(NetClient cl, NetRequest req) {
this.req = req;
this.cl = cl;
}
private static String constructArgs(Map<String, String> args) throws UnsupportedEncodingException{
private static String constructArgs(Map<String, String> args) throws UnsupportedEncodingException {
args = new TreeMap<>(args);
String str = "";
for (Map.Entry<String, String> en : args.entrySet()) {
@@ -34,11 +35,11 @@ public final class NetCall{
return str;
}
public NetRequest request(){
public NetRequest request() {
return req;
}
public NetResponse execute() throws IOException{
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);
@@ -67,7 +68,7 @@ public final class NetCall{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024 * 1024];
int c;
while((c = in.read(buffer)) != -1) bos.write(buffer, 0, c);
while ((c = in.read(buffer)) != -1) bos.write(buffer, 0, c);
in.close();
bos.close();
NetResponse r = new NetResponse(bos.toByteArray());
@@ -75,10 +76,10 @@ public final class NetCall{
return r;
}
public void enqueue(NetCallback cb){
new Thread(){
public void enqueue(NetCallback cb) {
new Thread() {
@Override
public void run(){
public void run() {
try {
NetResponse resp = execute();
cb.onResponse(NetCall.this, resp);
@@ -89,6 +90,7 @@ public final class NetCall{
interrupt();
join();
} catch (Exception e) {
Log.e("NetCall", "Failed to interrupt and join thread", e);
}
}
}.start();
@@ -2,7 +2,7 @@ package ru.vtosters.lite.net;
import java.io.IOException;
public interface NetCallback{
public interface NetCallback {
void onFailure(NetCall netCall, IOException iOException);
void onResponse(NetCall netCall, NetResponse netResponse) throws IOException;
@@ -4,18 +4,18 @@ import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.util.concurrent.TimeUnit;
public class NetClient{
public class NetClient {
private final long timeout;
private final Proxy proxy;
private final PasswordAuthentication authenticator;
protected NetClient(Builder b){
protected NetClient(Builder b) {
timeout = b.timeout;
proxy = b.proxy;
authenticator = b.auth;
}
public Builder newBuilder(){
public Builder newBuilder() {
Builder b = new Builder();
b.timeout = timeout;
b.proxy = proxy;
@@ -23,30 +23,30 @@ public class NetClient{
return b;
}
public NetCall newCall(NetRequest req){
public NetCall newCall(NetRequest req) {
return new NetCall(this, req);
}
public PasswordAuthentication getAuthenticator(){
public PasswordAuthentication getAuthenticator() {
return authenticator;
}
public Proxy getProxy(){
public Proxy getProxy() {
return proxy;
}
public long getTimeout(){
public long getTimeout() {
return timeout;
}
public static final class Builder{
public static final class Builder {
private long timeout;
private Proxy proxy;
private PasswordAuthentication auth;
public Builder connectTimeout(long l, TimeUnit unit){
public Builder connectTimeout(long l, TimeUnit unit) {
int m;
switch(unit) {
switch (unit) {
case SECONDS:
m = 1000;
break;
@@ -70,17 +70,17 @@ public class NetClient{
return this;
}
public Builder proxyAuthenticator(PasswordAuthentication auth){
public Builder proxyAuthenticator(PasswordAuthentication auth) {
this.auth = auth;
return this;
}
public Builder proxy(Proxy proxy){
public Builder proxy(Proxy proxy) {
this.proxy = proxy;
return this;
}
public NetClient build(){
public NetClient build() {
return new NetClient(this);
}
}
@@ -3,59 +3,59 @@ package ru.vtosters.lite.net;
import java.util.Map;
import java.util.TreeMap;
public class NetRequest{
public class NetRequest {
private final String url;
private final String requestMethod;
private final Map<String, String> params;
protected NetRequest(Builder b){
protected NetRequest(Builder b) {
url = b.url;
requestMethod = b.req;
params = b.params;
}
public Map<String, String> getRequestParams(){
public Map<String, String> getRequestParams() {
return params;
}
public String url(){
public String url() {
return url;
}
public String getRequestMethod(){
public String getRequestMethod() {
return requestMethod;
}
public static final class Builder{
public static final class Builder {
private String url;
private String req = "GET";
private Map<String, String> params;
public NetRequest build(){
public NetRequest build() {
return new NetRequest(this);
}
public Builder url(String url){
public Builder url(String url) {
this.url = url;
return this;
}
public Builder get(){
public Builder get() {
req = "GET";
return this;
}
public Builder post(){
public Builder post() {
req = "POST";
return this;
}
public Builder params(Map<String, String> params){
public Builder params(Map<String, String> params) {
this.params = params;
return this;
}
public Builder param(String param, String value){
public Builder param(String param, String value) {
if (params == null) params = new TreeMap<>();
params.put(param, value);
return this;
@@ -4,35 +4,35 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
public final class NetResponse{
public final class NetResponse {
private final byte[] data;
private int code;
protected NetResponse(byte[] data){
protected NetResponse(byte[] data) {
this.data = data;
}
protected void setCode(int code){
protected void setCode(int code) {
this.code = code;
}
public boolean isSuccessful(){
public boolean isSuccessful() {
return code() == 200;
}
public int code(){
public int code() {
return code;
}
public byte[] getData(){
public byte[] getData() {
return data;
}
public InputStream getDataStream(){
public InputStream getDataStream() {
return new ByteArrayInputStream(data);
}
public String getDataString(){
public String getDataString() {
return new String(data, StandardCharsets.UTF_8);
}
}
@@ -1,6 +1,6 @@
package ru.vtosters.lite.net;
import static ru.vtosters.lite.utils.Globals.getUserToken;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
import android.os.AsyncTask;
@@ -11,33 +11,33 @@ import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class Request{
public static void makeRequest(byte[] bArr, RequestCallback RequestCallback){
public class Request {
public static void makeRequest(byte[] bArr, RequestCallback RequestCallback) {
new MakeRequestTask(bArr, RequestCallback).execute();
}
public static void makeRequest(String str, RequestCallback RequestCallback){
public static void makeRequest(String str, RequestCallback RequestCallback) {
new MakeRequestTask(str.getBytes(), RequestCallback).execute();
}
public interface RequestCallback{
public interface RequestCallback {
void onResponse(String str);
}
private static class MakeRequestTask extends AsyncTask<Void, Void, String>{
private static class MakeRequestTask extends AsyncTask<Void, Void, String> {
private final RequestCallback callback;
private final byte[] url;
private final boolean mIsPut;
private final boolean mIsVTostersRequest;
public MakeRequestTask(byte[] bArr, RequestCallback RequestCallback){
public MakeRequestTask(byte[] bArr, RequestCallback RequestCallback) {
mIsVTostersRequest = false;
mIsPut = false;
callback = RequestCallback;
url = bArr;
}
public String doInBackground(Void... voidArr){
public String doInBackground(Void... voidArr) {
try {
HttpURLConnection httpURLConnection = (HttpURLConnection) new URL(new String(url)).openConnection();
httpURLConnection.setRequestMethod(mIsPut ? "PUT" : "GET");
@@ -53,7 +53,7 @@ public class Request{
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
StringBuffer stringBuffer = new StringBuffer();
while(true) {
while (true) {
String readLine = bufferedReader.readLine();
if (readLine != null) {
stringBuffer.append(readLine);
@@ -68,7 +68,7 @@ public class Request{
}
}
public void onPostExecute(String str){
public void onPostExecute(String str) {
super.onPostExecute(str);
callback.onResponse(str);
}
@@ -1,8 +1,8 @@
package ru.vtosters.lite.f0x1d;
package ru.vtosters.lite.services;
import static android.widget.Toast.LENGTH_SHORT;
import static android.widget.Toast.makeText;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import android.app.NotificationManager;
import android.app.Service;
@@ -22,12 +22,12 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class LogWriterService extends Service{
public LogWriterService(){
public class LogWriterService extends Service {
public LogWriterService() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId){
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.d("LogWriterService", "The service has been started");
@@ -44,18 +44,18 @@ public class LogWriterService extends Service{
writeLog(intent, file);
} catch (Exception e) {
e.printStackTrace();
makeText(getContext(), "Не удалось сохранить лог-файл", LENGTH_SHORT).show();
makeText(getGlobalContext(), "Не удалось сохранить лог-файл", LENGTH_SHORT).show();
}
var notificationId = intent.getIntExtra("notificationId", 1);
var manager = (NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE);
var manager = (NotificationManager) getGlobalContext().getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(notificationId);
makeText(getContext(), "Лог-файл был сохранен", LENGTH_SHORT).show();
makeText(getGlobalContext(), "Лог-файл был сохранен", LENGTH_SHORT).show();
stopSelf();
return START_NOT_STICKY;
}
private void writeLog(Intent intent, File file) throws IOException{
private void writeLog(Intent intent, File file) throws IOException {
FileOutputStream stream;
stream = new FileOutputStream(file);
stream.write(intent.getStringExtra("log").getBytes(StandardCharsets.UTF_8));
@@ -65,7 +65,7 @@ public class LogWriterService extends Service{
@Nullable
@Override
public IBinder onBind(Intent intent){
public IBinder onBind(Intent intent) {
return null;
}
}
@@ -1,12 +1,12 @@
package ru.vtosters.lite.tgs;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
public class TGPref{
private static final SharedPreferences Prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
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";
@@ -16,55 +16,55 @@ public class TGPref{
private static final String TG_PROXYUSER = "VTGS:PUS";
private static final String TG_PROXYUSEPASS = "VTGS:PUsePassword";
public static int getTGConnectMethod(){
public static int getTGConnectMethod() {
return Integer.parseInt(Prefs.getString(CNCT_METHOD, "0"));
}
public static void setTGConnectMethod(int method){
public static void setTGConnectMethod(int method) {
Prefs.edit().putString(CNCT_METHOD, String.valueOf(method)).apply();
}
public static String getTGBotKey(){
public static String getTGBotKey() {
return Prefs.getString(TG_BOTKEY, null);
}
public static void setTGBotKey(String key){
public static void setTGBotKey(String key) {
Prefs.edit().putString(TG_BOTKEY, key).apply();
}
public static String getTGProxyIP(){
public static String getTGProxyIP() {
return Prefs.getString(TG_PROXYIP, null);
}
public static void setTGProxyIP(String ip){
public static void setTGProxyIP(String ip) {
Prefs.edit().putString(TG_PROXYIP, ip).apply();
}
public static int getTGProxyPort(){
public static int getTGProxyPort() {
return Prefs.getInt(TG_PROXYPORT, 0);
}
public static void setTGProxyPort(int port){
public static void setTGProxyPort(int port) {
Prefs.edit().putInt(TG_PROXYPORT, port).apply();
}
public static String getTGProxyPass(){
public static String getTGProxyPass() {
return Prefs.getString(TG_PROXYPASS, "");
}
public static String getTGProxyUser(){
public static String getTGProxyUser() {
return Prefs.getString(TG_PROXYUSER, "");
}
public static void setTGProxyUserPass(String user, String pass){
public static void setTGProxyUserPass(String user, String pass) {
Prefs.edit().putString(TG_PROXYUSER, user).putString(TG_PROXYPASS, pass).apply();
}
public static boolean isTGProxyPassEnabled(){
public static boolean isTGProxyPassEnabled() {
return Prefs.getBoolean(TG_PROXYUSEPASS, false);
}
public static void setTGProxyPassEnabled(boolean en){
public static void setTGProxyPassEnabled(boolean en) {
Prefs.edit().putBoolean(TG_PROXYUSEPASS, en).apply();
}
}
@@ -1,7 +1,7 @@
package ru.vtosters.lite.tgs;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.Globals.getString;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getString;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -23,14 +23,14 @@ import org.json.JSONObject;
import java.util.List;
import java.util.Stack;
public class TGRoot{
public class TGRoot {
public static final int N = 76820000;
public static final int X = 976820000;
private final static Stack<Integer> pendingStickers = new Stack<>();
private static final String TAG = "TGRoot";
public static String getSummary(){
switch(TGPref.getTGConnectMethod()) {
public static String getSummary() {
switch (TGPref.getTGConnectMethod()) {
case 0:
return getString("ctypedirect");
case 2:
@@ -40,7 +40,7 @@ public class TGRoot{
}
}
public static Attachment processSticker(StickerItem item){
public static Attachment processSticker(StickerItem item) {
int id = item.getId();
if (id < N) return null;
@@ -48,7 +48,7 @@ public class TGRoot{
int stickerId = (id - N) % 120;
TelegramStickersPack pack = null;
for (TelegramStickersPack p : TelegramStickersService.getInstance(getContext()).getActivePacksListReference()) {
for (TelegramStickersPack p : TelegramStickersService.getInstance(getGlobalContext()).getActivePacksListReference()) {
if (p.index == index) {
pack = p;
break;
@@ -67,9 +67,9 @@ public class TGRoot{
return att;
}
public static void injectStickers(List<StickerStockItem> list){
public static void injectStickers(List<StickerStockItem> list) {
try {
List<TelegramStickersPack> packs = TelegramStickersService.getInstance(getContext()).getActivePacksListReference();
List<TelegramStickersPack> packs = TelegramStickersService.getInstance(getGlobalContext()).getActivePacksListReference();
for (int i = packs.size() - 1; i >= 0; i--)
list.add(0, toStickerPack(packs.get(i)));
} catch (Exception e) {
@@ -77,12 +77,12 @@ public class TGRoot{
}
}
public static StickerStockItem getPackBySticker(int stickerId){
public static StickerStockItem getPackBySticker(int stickerId) {
if (stickerId < N) return null;
int index = (stickerId - N) / 120;
TelegramStickersPack p = null;
for (TelegramStickersPack p_ : TelegramStickersService.getInstance(getContext())
for (TelegramStickersPack p_ : TelegramStickersService.getInstance(getGlobalContext())
.getActivePacksListReference()) {
if (p_.index == index) {
p = p_;
@@ -99,7 +99,7 @@ public class TGRoot{
}
}
private static StickerStockItem toStickerPack(TelegramStickersPack p) throws JSONException{
private static StickerStockItem toStickerPack(TelegramStickersPack p) throws JSONException {
JSONArray arr = new JSONArray();
for (int j = 0; j < p.stickersCount; j++)
@@ -143,7 +143,7 @@ public class TGRoot{
.put("photo_592", photo), X + p.index);
}
public static Attach modifyStickerIM(int i, StickerItem stickerItem, String str){
public static Attach modifyStickerIM(int i, StickerItem stickerItem, String str) {
if (stickerItem.getId() < 76820000) {
return AppAttachToImAttachConverter.a.a(i, stickerItem, str);
}
@@ -0,0 +1,54 @@
package ru.vtosters.lite.translators;
import static ru.vtosters.lite.utils.Preferences.preferences;
import androidx.annotation.NonNull;
import androidx.collection.LruCache;
import java.util.Locale;
import ru.vtosters.lite.utils.AndroidUtils;
public abstract class BaseTranslator {
private final LruCache<String, String> cache = new LruCache<>(200);
private static final int YANDEX = 0;
private static final int GOOGLE = 1;
private static final int DEEPL = 2;
@NonNull
public abstract String translate(String text, String tl);
@NonNull
public final String getTranslation(String text) {
var val = cache.get(text);
if (val != null)
return val;
var translation = translate(text, getToLanguage());
cache.put(text, translation);
return translation;
}
public static String getToLanguage() {
var lang = preferences.getString("lang_target", "system");
var systemLang = Locale.getDefault().getLanguage();
if (lang.isEmpty() || lang.equals(systemLang) || lang.equals("system"))
return systemLang;
return lang;
}
public static BaseTranslator getInstance() {
switch (AndroidUtils.getPreferences().getInt("translator", 0)) {
case YANDEX:
return YandexTranslator.getInstance();
case GOOGLE:
return GoogleTranslator.getInstance();
case DEEPL:
return DeepLTranslator.getInstance();
}
return null;
}
}
@@ -0,0 +1,134 @@
package ru.vtosters.lite.translators;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import org.json.JSONObject;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Pattern;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
public class DeepLTranslator extends BaseTranslator {
private static final OkHttpClient client = new OkHttpClient();
private static final Pattern pattern = Pattern.compile("[i]");
private static final String REQUEST_BODY_FORMAT = "{\n" +
" \"method\": \"LMT_handle_texts\",\n" +
" \"id\": %s,\n" +
" \"jsonrpc\": \"2.0\",\n" +
" \"params\": {\n" +
" \"splitting\": \"newlines\",\n" +
" \"texts\": [{\n" +
" \"requestAlternatives\": 0,\n" +
" \"text\": \"%s\"\n" +
" }],\n" +
" \"lang\": {\n" +
" \"target_lang\": \"%s\",\n" +
" \"source_lang_user_selected\": \"\"\n" +
" },\n" +
" \"commonJobParams\": {\n" +
" \"regionalVariant\": null,\n" +
" \"wasSpoken\": false,\n" +
" \"formality\": \"informal\"\n" +
" },\n" +
" \"timestamp\": %s\n" +
" }\n" +
"}";
private static DeepLTranslator instance;
public static DeepLTranslator getInstance() {
if (instance == null)
instance = new DeepLTranslator();
return instance;
}
@NonNull
@Override
public String translate(String text, String tl) {
try {
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
if (tl.contains("-"))
tl = tl.toUpperCase();
var i = 1;
while (pattern.matcher(text).find()) {
i++;
}
var id = new AtomicLong(ThreadLocalRandom.current().nextLong(Long.parseLong("10000000000")));
var requestBody = String.format(REQUEST_BODY_FORMAT,
id.incrementAndGet(),
text,
tl,
getTimestamp(i)
);
requestBody = (id.get() + 3) % 13 == 0 || (id.get() + 5) % 29 == 0
? requestBody.replace("hod\":\"", "hod\" : \"")
: requestBody.replace("hod\":\"", "hod\": \"");
String uuid = UUID.randomUUID().toString();
var request = new Request.a()
.b("https://www2.deepl.com/jsonrpc")
.a("referer", "https://www.deepl.com/")
.a("user-agent", "DeepL-Android/VersionName(name=1.0.1) Android 10 (aarch64)")
.a("x-app-os-name", "Android")
.a("x-app-os-version", "10")
.a("x-app-version", "1.0.1")
.a("x-app-build", "13")
.a("x-app-device", "Pixel 5")
.a("x-app-instance-id", uuid)
.a("accept-encoding", "gzip")
.a(RequestBody.a(MediaType.a("application/json; charset=utf-8"), requestBody.getBytes(StandardCharsets.UTF_8)))
.a();
var response = client.a(request).execute();
var payload = response.a().g();
Log.d("DeepL", response.toString());
Log.d("DeepL", payload);
if (!TextUtils.isEmpty(payload)) {
var json = new JSONObject(payload);
if (!json.has("result"))
return text;
var result = json.getJSONObject("result");
if (!result.has("texts"))
return text;
var sb = new StringBuilder();
var texts = result.getJSONArray("texts");
for (int j = 0; j < texts.length(); j++) {
var value = texts.getJSONObject(j).getString("text");
Log.d("DeepL", value);
sb.append(value);
}
return sb.toString();
}
return text;
} catch (Throwable e) {
Log.d("DeepL", e + "");
}
return text;
}
private static Long getTimestamp(int iNumber) {
var now = System.currentTimeMillis();
return Long.valueOf((((long) iNumber) + now) - (now % ((long) iNumber)));
}
}
@@ -0,0 +1,74 @@
package ru.vtosters.lite.translators;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import org.json.JSONObject;
import java.net.URLEncoder;
import okhttp3.OkHttpClient;
import okhttp3.Request;
public class GoogleTranslator extends BaseTranslator {
private static final OkHttpClient client = new OkHttpClient();
private static final String[] devices = new String[]{
"Linux; U; Android 10; Pixel 4",
"Linux; U; Android 10; Pixel 4 XL",
"Linux; U; Android 10; Pixel 4a",
"Linux; U; Android 10; Pixel 4a XL",
"Linux; U; Android 11; Pixel 4",
"Linux; U; Android 11; Pixel 4 XL",
"Linux; U; Android 11; Pixel 4a",
"Linux; U; Android 11; Pixel 4a XL",
"Linux; U; Android 11; Pixel 5",
"Linux; U; Android 11; Pixel 5a",
"Linux; U; Android 12; Pixel 4",
"Linux; U; Android 12; Pixel 4 XL",
"Linux; U; Android 12; Pixel 4a",
"Linux; U; Android 12; Pixel 4a XL",
"Linux; U; Android 12; Pixel 5",
"Linux; U; Android 12; Pixel 5a",
"Linux; U; Android 12; Pixel 6",
"Linux; U; Android 12; Pixel 6 Pro",
};
private static GoogleTranslator instance;
public static GoogleTranslator getInstance() {
if (instance == null)
instance = new GoogleTranslator();
return instance;
}
@NonNull
@Override
public String translate(String text, String tl) {
try {
var request = new Request.a()
.b("https://translate.googleapis.com/translate_a/single?dj=1" +
"&q=" + URLEncoder.encode(text, "UTF-8") +
"&sl=auto" +
"&tl=" + tl +
"&ie=UTF-8&oe=UTF-8&client=at&dt=t&otf=2")
.a("User-Agent",
"GoogleTranslate/6.28.0.05.421483610 (" + devices[(int) Math.round(Math.random() * (devices.length - 1))] + ")")
.a();
var payload = client.a(request).execute().a().g();
if (!TextUtils.isEmpty(payload)) {
var sb = new StringBuilder();
var object = new JSONObject(payload);
var array = object.getJSONArray("sentences");
for (int i = 0; i < array.length(); i++) {
sb.append(array.getJSONObject(i).getString("trans"));
}
return sb.toString();
}
} catch (Throwable e) {
e.printStackTrace();
}
return text;
}
}
@@ -0,0 +1,58 @@
package ru.vtosters.lite.translators;
import android.util.Log;
import androidx.annotation.NonNull;
import org.json.JSONObject;
import java.net.URLEncoder;
import java.util.UUID;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
public class YandexTranslator extends BaseTranslator {
private static final OkHttpClient client = new OkHttpClient();
private static final String uuid = UUID.randomUUID().toString().replace("-", "");
private static YandexTranslator instance;
public static YandexTranslator getInstance() {
if (instance == null)
instance = new YandexTranslator();
return instance;
}
@NonNull
@Override
public String translate(String text, String tl) {
try {
var request = new Request.a()
.b("https://translate.yandex.net/api/v1/tr.json/translate?&srv=android&id=" + uuid + "-0-0")
.a("User-Agent", "ru.yandex.translate/21.15.4.21402814 (Xiaomi Redmi K20 Pro; Android 11)")
.a(RequestBody.a(MediaType.a("application/x-www-form-urlencoded"),
"lang=" + tl + "&text=" + URLEncoder.encode(text, "UTF-8")))
.a();
var payload = client.a(request).execute().a().g();
var json = new JSONObject(payload);
if (!json.has("text") && json.has("message")) {
Log.d("YandexTranslator", json.getString("message"));
return text;
}
var array = json.getJSONArray("text");
var sb = new StringBuilder();
var length = array.length();
for (int i = 0; i < length; i++) {
sb.append(array.getString(i));
}
return sb.toString();
} catch (Throwable e) {
e.printStackTrace();
}
return text;
}
}
@@ -1,16 +1,16 @@
package ru.vtosters.lite.ui;
import static ru.vtosters.lite.utils.Globals.convertDpToPixel;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.Themes.getAccentColor;
import static ru.vtosters.lite.utils.Themes.getSTextAttr;
import static ru.vtosters.lite.utils.Themes.getTextAttr;
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.ImageUtils.setTint;
import static ru.vtosters.lite.utils.ThemesUtils.getAccentColor;
import static ru.vtosters.lite.utils.ThemesUtils.getSTextAttr;
import static ru.vtosters.lite.utils.ThemesUtils.getTextAttr;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.ColorStateList;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.preference.PreferenceManager;
import android.util.TypedValue;
@@ -29,15 +29,10 @@ import com.vtosters.lite.ui.MaterialSwitchPreference;
import java.util.Objects;
public class PreferencesUtil{
public class PreferencesUtil {
public static Drawable setTint(Context ctx, Drawable d){
d.setColorFilter(getAccentColor(), PorterDuff.Mode.SRC_ATOP);
return d;
}
public static void addListPreference(MaterialPreferenceToolbarFragment fragment, String key, String def, CharSequence title, CharSequence[] entries, CharSequence[] entriesValue){
ListPreference preference = new ListPreference(getContext());
public static void addListPreference(MaterialPreferenceToolbarFragment fragment, String key, String def, CharSequence title, CharSequence[] entries, CharSequence[] entriesValue) {
ListPreference preference = new ListPreference(getGlobalContext());
preference.setEntries(entries);
preference.setEntryValues(entriesValue);
preference.setTitle(title); // setTitle
@@ -47,8 +42,8 @@ public class PreferencesUtil{
fragment.getPreferenceScreen().addPreference(preference); // fragment.getPreferenceScreen().addPreference(preference)
}
public static void addListPreferenceIcon(MaterialPreferenceToolbarFragment fragment, String key, String def, CharSequence title, String icon, CharSequence summary, CharSequence[] entries, CharSequence[] entriesValue, Preference.OnPreferenceChangeListener listener){
ListPreference preference = new ListPreference(getContext());
public static void addListPreferenceIcon(MaterialPreferenceToolbarFragment fragment, String key, String def, CharSequence title, String icon, CharSequence summary, CharSequence[] entries, CharSequence[] entriesValue, Preference.OnPreferenceChangeListener listener) {
ListPreference preference = new ListPreference(getGlobalContext());
preference.setEntries(entries);
preference.setEntryValues(entriesValue);
preference.setSummary(summary); // setSummary
@@ -59,12 +54,12 @@ public class PreferencesUtil{
preference.setOnPreferenceChangeListener(listener);
if (icon != null)
preference.setIcon(setTint(getContext(), getDrawable(getContext(), icon))); // preference.setIcon
preference.setIcon(setTint(getGlobalContext(), getDrawable(getGlobalContext(), icon))); // preference.setIcon
fragment.getPreferenceScreen().addPreference(preference); // fragment.getPreferenceScreen().addPreference(preference)
}
public static void addMaterialSwitchPreference(MaterialPreferenceToolbarFragment materialPreferenceToolbarFragment, String key, CharSequence title, CharSequence summary, boolean defValue){
MaterialSwitchPreference materialSwitchPreference = new MaterialSwitchPreference(getContext());
public static void addMaterialSwitchPreference(MaterialPreferenceToolbarFragment materialPreferenceToolbarFragment, String key, CharSequence title, CharSequence summary, boolean defValue) {
MaterialSwitchPreference materialSwitchPreference = new MaterialSwitchPreference(getGlobalContext());
materialSwitchPreference.setTitle(title); // setTitle
materialSwitchPreference.setSummary(summary); // setSummary
materialSwitchPreference.setKey(key); // setKey
@@ -73,8 +68,8 @@ public class PreferencesUtil{
materialPreferenceToolbarFragment.getPreferenceScreen().addPreference(materialSwitchPreference); // materialPreferenceToolbarFragment.getPreferenceScreen().addPreference(preference)
}
public static void addMaterialSwitchPreference(MaterialPreferenceToolbarFragment fragment, String key, CharSequence title, CharSequence summary, int icon, boolean defValue, Preference.OnPreferenceChangeListener listener){
MaterialSwitchPreference materialSwitchPreference = new MaterialSwitchPreference(getContext());
public static void addMaterialSwitchPreference(MaterialPreferenceToolbarFragment fragment, String key, CharSequence title, CharSequence summary, int icon, boolean defValue, Preference.OnPreferenceChangeListener listener) {
MaterialSwitchPreference materialSwitchPreference = new MaterialSwitchPreference(getGlobalContext());
materialSwitchPreference.setTitle(title); // setTitle
materialSwitchPreference.setSummary(summary); // setSummary
materialSwitchPreference.setKey(key); // setKey
@@ -82,13 +77,13 @@ public class PreferencesUtil{
materialSwitchPreference.setOnPreferenceChangeListener(listener); // setOnPreferenceClickListener
if (icon != 1)
materialSwitchPreference.setIcon(setTint(getContext(), Objects.requireNonNull(ContextCompat.getDrawable(getContext(), icon)))); // preference.setIcon
materialSwitchPreference.setIcon(setTint(getGlobalContext(), Objects.requireNonNull(ContextCompat.getDrawable(getGlobalContext(), icon)))); // preference.setIcon
fragment.getPreferenceScreen().addPreference(materialSwitchPreference); // fragment.getPreferenceScreen().addPreference(preference)
}
public static void addMaterialSwitchPreference(MaterialPreferenceToolbarFragment fragment, String key, CharSequence title, CharSequence summary, String icon, boolean defValue, Preference.OnPreferenceChangeListener listener){
MaterialSwitchPreference materialSwitchPreference = new MaterialSwitchPreference(getContext());
public static void addMaterialSwitchPreference(MaterialPreferenceToolbarFragment fragment, String key, CharSequence title, CharSequence summary, String icon, boolean defValue, Preference.OnPreferenceChangeListener listener) {
MaterialSwitchPreference materialSwitchPreference = new MaterialSwitchPreference(getGlobalContext());
materialSwitchPreference.setTitle(title); // setTitle
materialSwitchPreference.setSummary(summary); // setSummary
materialSwitchPreference.setKey(key); // setKey
@@ -96,14 +91,14 @@ public class PreferencesUtil{
fragment.getPreferenceScreen().addPreference(materialSwitchPreference); // materialPreferenceToolbarFragment.getPreferenceScreen().addPreference(preference)
if (icon != null)
materialSwitchPreference.setIcon(setTint(getContext(), getDrawable(getContext(), icon))); // preference.setIcon
materialSwitchPreference.setIcon(setTint(getGlobalContext(), getDrawable(getGlobalContext(), icon))); // preference.setIcon
materialSwitchPreference.setOnPreferenceChangeListener(listener); // setOnPreferenceClickListener(listener)
fragment.getPreferenceScreen().addPreference(materialSwitchPreference); // fragment.getPreferenceScreen().addPreference(preference)
}
public static void addPreference(MaterialPreferenceToolbarFragment fragment, String key, CharSequence title, CharSequence summary){
Preference preference = new Preference(getContext());
public static void addPreference(MaterialPreferenceToolbarFragment fragment, String key, CharSequence title, CharSequence summary) {
Preference preference = new Preference(getGlobalContext());
preference.setSummary(summary); // setSummary
preference.setTitle(title); // setTitle
preference.setKey(key); // setKey
@@ -111,33 +106,33 @@ public class PreferencesUtil{
fragment.getPreferenceScreen().addPreference(preference); // fragment.getPreferenceScreen().addPreference(preference)
}
public static void addPreference(MaterialPreferenceToolbarFragment fragment, CharSequence title, CharSequence summary, @Nullable String icon, Preference.OnPreferenceClickListener listener){
Preference preference = new Preference(getContext());
public static void addPreference(MaterialPreferenceToolbarFragment fragment, CharSequence title, CharSequence summary, @Nullable String icon, Preference.OnPreferenceClickListener listener) {
Preference preference = new Preference(getGlobalContext());
preference.setSummary(summary); // setSummary
preference.setTitle(title); // setTitle
if (icon != null)
preference.setIcon(setTint(getContext(), getDrawable(getContext(), icon))); // preference.setIcon
preference.setIcon(setTint(getGlobalContext(), getDrawable(getGlobalContext(), icon))); // preference.setIcon
preference.setOnPreferenceClickListener(listener); // preference.setOnPreferenceClickListener(listener)
fragment.getPreferenceScreen().addPreference(preference); // fragment.getPreferenceScreen().addPreference(preference)
}
public static void addPreference(MaterialPreferenceToolbarFragment fragment, String key, CharSequence title, CharSequence summary, @Nullable String icon, Preference.OnPreferenceClickListener listener){
Preference preference = new Preference(getContext());
public static void addPreference(MaterialPreferenceToolbarFragment fragment, String key, CharSequence title, CharSequence summary, @Nullable String icon, Preference.OnPreferenceClickListener listener) {
Preference preference = new Preference(getGlobalContext());
preference.setSummary(summary); // setSummary
preference.setTitle(title); // setTitle
preference.setKey(key); // setKey
if (icon != null)
preference.setIcon(setTint(getContext(), getDrawable(getContext(), icon))); // preference.setIcon
preference.setIcon(setTint(getGlobalContext(), getDrawable(getGlobalContext(), icon))); // preference.setIcon
preference.setOnPreferenceClickListener(listener); // preference.setOnPreferenceClickListener(listener)
fragment.getPreferenceScreen().addPreference(preference); // fragment.getPreferenceScreen().addPreference(preference)
}
public static void addPreferenceDrawable(MaterialPreferenceToolbarFragment fragment, String key, CharSequence title, CharSequence summary, @Nullable Drawable icon, Preference.OnPreferenceClickListener listener){
Preference preference = new Preference(getContext());
public static void addPreferenceDrawable(MaterialPreferenceToolbarFragment fragment, String key, CharSequence title, CharSequence summary, @Nullable Drawable icon, Preference.OnPreferenceClickListener listener) {
Preference preference = new Preference(getGlobalContext());
preference.setSummary(summary); // setSummary
preference.setTitle(title); // setTitle
preference.setKey(key); // setKey
@@ -149,38 +144,38 @@ public class PreferencesUtil{
fragment.getPreferenceScreen().addPreference(preference); // fragment.getPreferenceScreen().addPreference(preference)
}
public static void addPreferenceCategory(MaterialPreferenceToolbarFragment fragment, CharSequence title){
PreferenceCategory preference = new PreferenceCategory(getContext(), null);
public static void addPreferenceCategory(MaterialPreferenceToolbarFragment fragment, CharSequence title) {
PreferenceCategory preference = new PreferenceCategory(getGlobalContext(), null);
preference.setTitle(title); // setTitle
fragment.getPreferenceScreen().addPreference(preference); // fragment.getPreferenceScreen().addPreference(preference)
}
public static void addPreferenceCategory(MaterialPreferenceToolbarFragment fragment, CharSequence title, int collapsedSize){
PreferenceCategory preference = new PreferenceCategory(getContext(), null);
public static void addPreferenceCategory(MaterialPreferenceToolbarFragment fragment, CharSequence title, int collapsedSize) {
PreferenceCategory preference = new PreferenceCategory(getGlobalContext(), null);
preference.setTitle(title); // setTitle
fragment.getPreferenceScreen().addPreference(preference); // fragment.getPreferenceScreen().addPreference(preference)
}
public static void addEditTextPreference(MaterialPreferenceToolbarFragment fragment, String key, CharSequence title, EditTextPrefChangeListener editTextPrefChangeListener){
Preference preference = new Preference(getContext());
public static void addEditTextPreference(MaterialPreferenceToolbarFragment fragment, String key, CharSequence title, EditTextPrefChangeListener editTextPrefChangeListener) {
Preference preference = new Preference(getGlobalContext());
preference.setTitle(title); // setTitle
preference.setKey(key); // setKey
preference.setOnPreferenceClickListener(preference1 -> {
LinearLayout linearLayout = new LinearLayout(getContext());
LinearLayout linearLayout = new LinearLayout(getGlobalContext());
final EditText editText = new EditText(getContext());
editText.setText(PreferenceManager.getDefaultSharedPreferences(getContext()).getString(key, ""));
final EditText editText = new EditText(getGlobalContext());
editText.setText(PreferenceManager.getDefaultSharedPreferences(getGlobalContext()).getString(key, ""));
editText.setHint(title);
editText.setTextColor(getTextAttr());
editText.setHintTextColor(getSTextColor(getContext()));
editText.setHintTextColor(getSTextAttr());
editText.setBackgroundTintList(ColorStateList.valueOf(getAccentColor()));
linearLayout.addView(editText);
editText.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
ViewGroup.MarginLayoutParams margin = ((ViewGroup.MarginLayoutParams) editText.getLayoutParams());
margin.setMargins(convertDpToPixel(20f), 0, convertDpToPixel(20f), 0);
margin.setMargins(dp2px(20f), 0, dp2px(20f), 0);
editText.setLayoutParams(margin);
AlertDialog.Builder builder = new AlertDialog.Builder(fragment.getContext());
@@ -191,7 +186,7 @@ public class PreferencesUtil{
if (!change)
return;
PreferenceManager.getDefaultSharedPreferences(getContext())
PreferenceManager.getDefaultSharedPreferences(getGlobalContext())
.edit()
.putString(key, editText.getText().toString())
.apply();
@@ -206,24 +201,24 @@ public class PreferencesUtil{
fragment.getPreferenceScreen().addPreference(preference); // fragment.getPreferenceScreen().addPreference(preference)
}
public static int getTextColor(Context ctx){
public static int getTextColor(Context ctx) {
TypedValue typedValue = new TypedValue();
ctx.getTheme().resolveAttribute(getTextAttr(), typedValue, true);
return typedValue.data;
}
public static int getSTextColor(Context ctx){
public static int getSTextColor(Context ctx) {
TypedValue typedValue = new TypedValue();
ctx.getTheme().resolveAttribute(getSTextAttr(), typedValue, true);
return typedValue.data;
}
private static Drawable getDrawable(Context ctx, String name){
private static Drawable getDrawable(Context ctx, String name) {
var id = ctx.getResources().getIdentifier(name, "drawable", ctx.getPackageName());
return ContextCompat.getDrawable(ctx, id);
}
public interface EditTextPrefChangeListener{
public interface EditTextPrefChangeListener {
boolean onChanged(Preference preference, Object obj);
}
}

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