Compare commits

..
1592 Commits
Author SHA1 Message Date
gdlbo 1e0e432d57 Update ContactsUtils.java 2022-09-15 17:24:35 +03:00
gdlbo 3a1c93d4d0 fix params media frag 2022-09-15 16:46:49 +03:00
gdlbo 378e6192c7 hide system anims 2022-09-15 16:38:29 +03:00
gdlbo 67d0a4c88d added dialog for clear vid history 2022-09-15 16:28:44 +03:00
gdlbo d59297d348 deleted old video frag 2022-09-15 16:15:55 +03:00
gdlbo 1da12a02b6 Create update_jars_brew.sh 2022-09-15 15:58:39 +03:00
gdlbo 9ceee0b3d9 disabled anim sett for a13 2022-09-15 15:56:45 +03:00
aliveoutside 281b4d9773 allow to change order of telegram stickers 2022-09-15 00:34:48 +03:00
aliveoutside 18714288d7 partially fix contacts import 2022-09-14 00:24:12 +03:00
aliveoutside 8ac098e4f8 Merge pull request #739
Remove old music catalog
2022-09-13 22:02:24 +03:00
inotflying eda5ab139e Remove old music catalog 2022-09-13 20:23:50 +03:00
gdlbo ab3221cc01 getInfo -> execute + VKMeHandler codebase 2022-09-11 14:31:58 +03:00
gdlbo 92d4ff2027 tablet fixes 2022-09-11 02:35:59 +03:00
gdlbo cedf5d263a tablet fixes 2022-09-11 02:29:47 +03:00
gdlbo 08909baf2f no shopping anymore 2022-09-11 02:01:36 +03:00
gdlbo 383bafae92 fixed splash 2022-09-11 01:54:03 +03:00
gdlbo c2661e11ec Update JsonInjectors.java 2022-09-11 01:33:16 +03:00
gdlbo 9c4ccce409 test upload contacts 2022-09-11 01:18:48 +03:00
gdlbo c1b2409baa contacts hack v2 2022-09-11 00:46:54 +03:00
gdlbo 54ee9f6c5b Update ContactsUtils.java 2022-09-10 23:55:05 +03:00
gdlbo d83033e983 contacts hack 2022-09-10 23:49:32 +03:00
Vologhat 92c0369332 added system theme warning dialog 2022-09-10 22:45:15 +03:00
gdlbo d796455bbe fix crash with unsupported msg 2022-09-10 21:35:25 +03:00
gdlbo dc4743f2a3 fix restart sett 2022-09-10 19:54:20 +03:00
aliveoutside 94c8736bc1 android:configChanges - uiMode 2022-09-10 19:36:01 +03:00
aliveoutside e05255263b remove useless log 2022-09-10 18:58:54 +03:00
aliveoutside e916b5fcc8 check the system theme on app start 2022-09-10 18:52:49 +03:00
aliveoutside 09e0dbd01d switch theme when "Use system theme" switch changed to true 2022-09-10 18:48:30 +03:00
aliveoutside 84e5ce6dc2 add system theme switch to settings 2022-09-10 18:42:47 +03:00
aliveoutside 2520b709bd remove dead code in ThemesUtils 2022-09-10 17:47:41 +03:00
aliveoutside 0ed16b0836 follow system theme (light/dark) 2022-09-10 17:35:41 +03:00
aliveoutside 6e55514edf Update README.md 2022-09-10 16:55:14 +03:00
aliveoutside 93d515b423 add russian string for play_in_vkx 2022-09-10 16:49:14 +03:00
aliveoutside b88ecd97fc pass playlist and action id to the hook 2022-09-10 16:46:05 +03:00
aliveoutside 5c1b39c79f pass playback context to vk x 2022-09-10 16:33:34 +03:00
aliveoutside bae7263554 implement "Play in VK X" quick action in track bottomsheet
resolves #723
2022-09-10 16:09:38 +03:00
aliveoutside 63f4ed3885 fix AudioDownloader 2022-09-06 14:00:35 +03:00
aliveoutside ad90c522ac move image downloader to IOExecutor 2022-09-06 13:57:24 +03:00
aliveoutside 374b221f0d fix #627
also fix wrong mime-types for downloaded files
2022-09-06 13:39:39 +03:00
Erik Kiznov 99adb95816 download fix 2022-09-06 12:38:00 +05:00
gdlbo e96a3b304f Update AdBlockHook.java 2022-09-04 16:39:29 +03:00
gdlbo cf4855bdd1 fixed newsfeed issues 2022-09-04 16:32:22 +03:00
gdlbo 8c8c574a4e Update OnlineFormatterHook.java 2022-09-04 14:55:23 +03:00
gdlbo 653afd69b6 Fix null dialog.getId() 2022-09-04 13:44:30 +03:00
aliveoutside 0660c9664d fix #713 2022-09-04 11:56:37 +03:00
aliveoutside a72ef8570a simplify post != null in AdBlockHook 2022-09-04 11:23:42 +03:00
gdlbo 4ce55a22f9 removed custom folders path feature 2022-09-03 23:37:00 +03:00
gdlbo 910c991adb Update CacheUtils.java 2022-09-03 23:23:56 +03:00
gdlbo b746594b1d some adblock refactoring 2022-09-03 23:18:12 +03:00
Erik Kiznov 0698985623 discover adblock logging fix 2022-09-02 21:45:04 +05:00
gdlbo 859d9dd2b8 discoverAdBlock + try catch hack
trying to find bug
2022-09-02 19:03:21 +03:00
gdlbo 341d1b6e70 Update JsonInjectors.java 2022-09-02 17:40:50 +03:00
gdlbo cbdf33f253 discover adblock 2022-09-02 17:40:04 +03:00
Erik Kiznov 536dd9ea51 i hate vk api error codes
v=5.187 -> "error_msg": "Access token has expired"

v=5.186 -> "response": "..."
2022-09-02 00:11:49 +05:00
gdlbo 624b4d4724 Update RequestDumper.java 2022-09-01 21:45:27 +03:00
k1zn 0e604c81c7 params to map<string, string> 2022-09-01 23:42:21 +05:00
gdlbo 3175fe3af2 Update WallGetById.smali 2022-09-01 21:40:47 +03:00
gdlbo 9f37390d59 removed legacy ad remover 2022-09-01 21:26:39 +03:00
gdlbo 2dfcc9096f Revert "speedup chats opening with wp"
This reverts commit 00d8e60d1e.
2022-09-01 21:03:09 +03:00
gdlbo 00d8e60d1e speedup chats opening with wp 2022-09-01 21:00:08 +03:00
Erik Kiznov 010a71ecca remove file remove 2022-09-01 22:40:07 +05:00
gdlbo e82547ddbb deleted 2/3 compressing shit 2022-09-01 20:37:07 +03:00
gdlbo 484b0f5850 fix deleting 2022-09-01 19:55:50 +03:00
gdlbo fd9837aee4 some shitcode for saving wp + true compressing + moved to webp format of file 2022-09-01 19:54:49 +03:00
aliveoutside 255e5e62db fix discover tab #481 2022-09-01 15:08:28 +03:00
gdlbo 4da1ec3b76 some theme fixes 2022-08-31 13:48:45 +03:00
gdlbo 296b717891 Update ServerDialog.java 2022-08-30 13:51:33 +03:00
gdlbo e709f6ac68 some fixes
force updates + setup filters fixes
2022-08-30 13:45:54 +03:00
aliveoutside e231e4a2b4 Revert "Update Preferences.java"
This reverts commit 2e8f168d9f.
2022-08-30 12:07:43 +03:00
Erik Kiznov 2e8f168d9f Update Preferences.java 2022-08-30 13:49:30 +05:00
Erik Kiznov e75eb4caa5 remove adblock from create new post
пост все равно создается, а фрагмент создания новой записи не закрывается, так что удалим отсюда фильтрацию
2022-08-30 01:02:14 +05:00
Erik Kiznov 58905bbc59 fix default filters value
все фильтры из mFilters при первом запуске VTLite работали и удаляли посты, даже если фильтры не были включены
2022-08-30 00:45:51 +05:00
k1zn ae9d89c6c6 update README.md to v0.4.12-beta 2022-08-28 21:20:34 +05:00
gdlbo 41ac03a7e1 speedup setupfilters and cache 2022-08-27 16:30:45 +03:00
gdlbo 4bded5c565 nigg 2022-08-27 16:09:25 +03:00
gdlbo 652f5e665f wp disabled 2022-08-27 15:53:56 +03:00
gdlbo 05e118ff31 Update ApiProxy.java 2022-08-27 13:36:31 +03:00
gdlbo c63457674d Update ApiProxy.java 2022-08-27 13:36:01 +03:00
gdlbo c9b8dbc8dd support vk.ru at opening links 2022-08-27 13:34:03 +03:00
gdlbo 34c6a7f8b1 i hate my life 2022-08-27 13:30:12 +03:00
aliveoutside 74d4a5368a move slow tasks from MainActivityInjector to executors 2022-08-27 12:49:01 +03:00
aliveoutside b2256d20e0 Revert "notif counter for newsfeed if enabled milk"
This reverts commit c8c8678785.
2022-08-27 12:48:40 +03:00
gdlbo f887648f48 I love NullPointerException
NullPointerException
NullPointerException
NullPointerException
NullPointerException
NullPointerException
2022-08-26 23:03:35 +03:00
gdlbo 8ee29b4b83 Update WallpapersHooks.java 2022-08-26 22:10:43 +03:00
gdlbo a4c6af8ace Update WallpapersHooks.java 2022-08-26 22:05:47 +03:00
gdlbo 9ec4e52eba newsfeed improves 2022-08-26 21:56:11 +03:00
gdlbo b756bfa622 proxy fixes 2022-08-26 21:33:29 +03:00
Erik Kiznov f96baa58ac wallpapers hooks: fix (maybe)
- close outputstream > release dedicated memory
- delete temp file on exit
- improved check"compress" for null
2022-08-26 23:12:48 +05:00
Erik Kiznov d9f03a5d0e msg downloader: VK_DOMAIN -> private 2022-08-26 21:13:58 +05:00
Erik Kiznov 15d2daa887 msg downloader: update
- add wall_reply support
- add story support
- add podcast support
- add gift support
- add miniapp support
- add audio playlist support
- add poll support
- add market support
- add VK_DOMAIN constant (idk why но пусть будет)
2022-08-26 21:09:01 +05:00
gdlbo 8e12f50a7f updated todo in msgdl 2022-08-26 17:00:42 +03:00
Erik Kiznov 9ff220475d msg downloader: update
- fix group links
2022-08-26 18:39:35 +05:00
Erik Kiznov 2c6619a512 msg downloader: update
- add geo support
- add chat screenshot support
- add custom action support
- add audio message support
- add audio support
- add video support
2022-08-26 18:09:18 +05:00
Erik Kiznov 5ea599b61e msg downloader: update
- replace "get" to "opt" for avoid errors
- fix vmoji sticker resolution
2022-08-26 03:11:09 +05:00
Erik Kiznov 4eea4e2011 msg downloader: update
- decrypt replies & forward messages
- fix html bug
2022-08-26 02:41:16 +05:00
Erik Kiznov f1a7816e69 msg downloader: remove some returns 2022-08-26 01:16:01 +05:00
Erik Kiznov 12c01133e1 msg downloader: update
- fix photo attach size
- replace mentions to links
- add sticker support
- add reply support
- add forward messages support
- add chat actions support
2022-08-26 01:13:20 +05:00
gdlbo 3856932a3f some proxy fixes (vkui dead idk why) 2022-08-24 22:36:22 +03:00
gdlbo a10c333cc6 deleted duplicate of profile 2022-08-24 14:11:31 +03:00
gdlbo 4d950e5c68 deleted duplicate of profile 2022-08-24 14:06:33 +03:00
gdlbo c72e102076 dl icon for msg dl 2022-08-24 14:00:24 +03:00
gdlbo 43f3df487b msg downloader test 2022-08-24 13:15:37 +03:00
Erik Kiznov ca48f97d83 remove send toast
fix messages load
2022-08-23 19:52:25 +03:00
gdlbo b69beff4d2 fix https://github.com/vtosters/lite/issues/643 2022-08-23 16:15:22 +03:00
gdlbo 67401c6868 disabled vk api ping url (cringe and dead already) 2022-08-23 16:08:17 +03:00
gdlbo 9fa8df30eb wp compress 2022-08-23 15:40:35 +03:00
gdlbo ecf896e44e maybe fix 649 2022-08-23 14:04:14 +03:00
gdlbo 58a9b69dd9 fix https://github.com/vtosters/lite/issues/669 2022-08-23 13:38:56 +03:00
Erik Kiznov 26a64545ff translate strings
translate all new untranslated strings, removed useless cast to WithUserContent in ReplyMsgHook.java
2022-08-22 18:09:35 +03:00
gdlbo 05c557a8f7 fix whitelist toast 2022-08-22 16:17:54 +03:00
gdlbo c8c8678785 notif counter for newsfeed if enabled milk 2022-08-22 04:41:25 +03:00
gdlbo 4e6eb74a8e fix bg color 2022-08-22 03:52:01 +03:00
gdlbo 52cb007a67 code improvements 2022-08-22 03:44:16 +03:00
gdlbo 657d038d9c groups filters whitelist 2022-08-22 03:31:44 +03:00
gdlbo de4d283f75 fix open vk.com links 2022-08-21 16:37:12 +03:00
gdlbo 3b37412a58 gmsless frag fixes 2022-08-21 16:23:16 +03:00
gdlbo dd6b9b32b8 some link fixes 2022-08-21 15:15:27 +03:00
gdlbo 31a456582b vk.com -> vk.ru 2022-08-21 14:54:14 +03:00
gdlbo 6ab317cbf5 fix ded wp 2022-08-20 23:33:51 +03:00
gdlbo 32c469d870 fix https://github.com/vtosters/lite/issues/657 2022-08-20 23:26:15 +03:00
gdlbo e0f09cea24 fix strange miui 13 bug 2022-08-20 22:31:43 +03:00
gdlbo e668cfb2a3 Update NewsfeedHook.java 2022-08-20 21:13:49 +03:00
gdlbo 857b63a356 Update FoafBase.java 2022-08-20 19:12:36 +03:00
gdlbo 0c03406774 fixed null list + fix reset items 2022-08-20 18:49:32 +03:00
gdlbo ac3cb847f4 refactored conversation_bar inj 2022-08-20 16:58:39 +03:00
gdlbo 05ed60b86d added vika support to start proxy dialog 2022-08-20 16:14:58 +03:00
gdlbo 020ec70221 fixed stories and vid downloading 2022-08-20 15:24:08 +03:00
Erik Kiznov 478825e708 reply 🔒 decrypt fix [pt. 2] 2022-08-20 13:31:47 +03:00
Erik Kiznov 6ce0e630db reply 🔒 decrypt fix 2022-08-20 13:31:47 +03:00
gdlbo 6e538f44b5 some pix fixes 2022-08-20 12:17:22 +03:00
gdlbo bd3bec2a31 fixed m3u8 path downloading 2022-08-19 16:00:24 +03:00
gdlbo cf25e39485 Update .gitignore 2022-08-19 15:56:40 +03:00
gdlbo 1f87d7a403 fix default ad bool 2022-08-19 15:55:40 +03:00
gdlbo 10da74285c Update build.gradle 2022-08-19 14:33:17 +03:00
aliveoutside 3a2607274f fix libs 2022-08-19 12:50:14 +03:00
gdlbo 6cbe7caec1 added compressing of wallpaper
speedup chat open
fix crash if file is too large
2022-08-18 23:22:48 +03:00
gdlbo 452b4aa667 fix settings crash on sdk < 24 2022-08-18 22:53:02 +03:00
gdlbo c4d77e40f4 removed globalUsersOnline + some code fixes 2022-08-18 22:24:28 +03:00
spiky-s 3c9a787a77 improved online hook 2022-08-18 22:13:11 +03:00
spiky-s d400da3ab9 improved online hook 2022-08-18 22:13:11 +03:00
spiky-s ded67ac699 improved online hook 2022-08-18 22:13:11 +03:00
spiky-s 2c3d78b0b4 improved online hook 2022-08-18 22:13:11 +03:00
spiky-s ed9701a04b improved online hook 2022-08-18 22:13:11 +03:00
spiky-s 9af33a4a01 improved online hook 2022-08-18 22:13:11 +03:00
spiky-s 481abbc3d8 improved online hook 2022-08-18 22:13:11 +03:00
spiky-s d9065c3073 improved online hook 2022-08-18 22:13:11 +03:00
spiky-s 46295e5216 improved online hook 2022-08-18 22:13:11 +03:00
spiky-s 5eeff2f08d Add files via upload 2022-08-18 22:13:11 +03:00
spiky-s 341a368656 improved online hooks 2022-08-18 22:13:11 +03:00
gdlbo f9657af36c fix decrypt copy 2022-08-18 21:45:38 +03:00
gdlbo 5bead1b88f clipboard decrypt from header 2022-08-18 21:29:27 +03:00
Erik Kiznov c4d915e60d support 🔒 decrypt messages in reply window 2022-08-18 20:03:43 +03:00
gdlbo 834f70b585 fixes 2022-08-18 16:03:35 +03:00
gdlbo a5243e6839 Update EncryptProvider.java 2022-08-18 15:17:32 +03:00
gdlbo 03487678ac fixed decrypt in dialogs 2022-08-18 15:07:18 +03:00
k1zn c482e82ebe Update EncryptProvider.java 2022-08-18 14:29:15 +03:00
Erik Kiznov 14ecc21937 fix remove "🔒" bug 2022-08-18 14:24:29 +03:00
k1zn 65aa04a7e3 fix bug in decryptMessage 2022-08-18 14:24:29 +03:00
gdlbo d8e1ce12f7 copy msg decryption 2022-08-18 14:14:15 +03:00
k1zn 9a84b5b87d [2] support for decrypt message in writebar_edit 2022-08-18 13:10:32 +03:00
k1zn 0a42040188 [1] support for decrypt message in writebar_edit 2022-08-18 13:10:32 +03:00
gdlbo 8e66f75baf Proxy fixes 2022-08-18 00:01:22 +03:00
Erik Kiznov 72e1371fe0 translate strings 2022-08-17 22:46:35 +03:00
gdlbo e9c8170ee4 proxy fixes 2022-08-17 22:30:02 +03:00
gdlbo 330793f8bc Added saving key state 2022-08-17 21:18:58 +03:00
gdlbo 45015c571f some refactoring 2022-08-17 20:26:22 +03:00
gdlbo b6fcf0330d Proxy services inj 2022-08-17 20:09:59 +03:00
gdlbo cc95856e47 Proxy Refactoring 2022-08-17 17:11:50 +03:00
gdlbo cbab131610 random socks5 test 2022-08-17 13:45:39 +03:00
gdlbo 879c218f0c fix vk appname selection 2022-08-17 13:21:39 +03:00
gdlbo ef0e2caabf dockbar updates + updated gradle ver 2022-08-16 23:51:34 +03:00
Erik Kiznov d4ab0a1366 direct link 2022-08-16 18:57:05 +03:00
Erik Kiznov 9cbc45dea3 try ... catch in OTADownloader.java 2022-08-16 18:57:05 +03:00
aliveoutside b6133da808 fix #624
added a check if an attachment is instance of an attachment type where we could get the original link to the photo
2022-08-16 04:24:30 +03:00
aliveoutside 59fb11dbaa remove useless logs from MediaFragment 2022-08-16 04:10:15 +03:00
gdlbo 3de88254f6 dialog can be null........... 2022-08-15 21:13:42 +03:00
gdlbo 306338992e New device id generator for webview auth 2022-08-15 20:44:22 +03:00
Erik Kiznov 370ee53bde fix donate urls 2022-08-15 18:47:08 +03:00
gdlbo ccc61ebb92 code fixes 2022-08-15 18:26:27 +03:00
Erik Kiznov 522cac34b0 fix spaces in .xml 2022-08-15 16:44:43 +03:00
gdlbo 282c2e3ed7 text pin fix 2022-08-15 16:30:35 +03:00
gdlbo 97453703e1 fixed null decrypt msg 2022-08-15 15:30:49 +03:00
gdlbo dfeff9903d fixed translator dialog 2022-08-15 14:50:00 +03:00
gdlbo 208e601f08 fixed translator 2022-08-15 14:35:33 +03:00
gdlbo e9d63463c5 fixed translator 2022-08-15 14:34:22 +03:00
gdlbo c86a1533e4 fixed registerActivities 2022-08-15 14:31:57 +03:00
gdlbo a1332043a1 Update CryptImHook.java 2022-08-15 14:21:32 +03:00
gdlbo 86e41aef7f Crypt hook 2022-08-15 14:19:12 +03:00
Erik Kiznov a1937420e8 translate encryption settings 2022-08-15 14:17:37 +03:00
gdlbo f5383a58e1 fixed init + added enc buttons (without hooks) 2022-08-15 13:39:26 +03:00
gdlbo 3476e4eed4 fix proxy
https://github.com/vtosters/lite/issues/505
2022-08-14 21:21:21 +03:00
gdlbo 9f01927bd1 fix proxy
https://github.com/vtosters/lite/issues/505
2022-08-14 21:21:21 +03:00
Erik Kiznov be2b7c99fc [c] -> c
this commit fix russian letter "c" in variables to english letter "c"
2022-08-14 17:55:18 +03:00
Erik Kiznov d4410a1b85 [c] -> c
this commit fix russian letter "c" in variables to english letter "c"
2022-08-14 17:55:18 +03:00
k1zn 1e16a43b1e fix "vk pay" logo in superapp widget 2022-08-13 22:30:43 +03:00
k1zn 5b70beceeb fix "vk pay" logo in superapp widget 2022-08-13 22:30:43 +03:00
gdlbo e8dea04d5d Fixed rename bug 2022-08-13 21:36:35 +03:00
gdlbo 1dc000f8f5 Fixed rename bug 2022-08-13 21:36:35 +03:00
Erik Kiznov 7d3c4ce4a6 translate layouts 2022-08-13 21:29:03 +03:00
Erik Kiznov 92159a9242 translate layouts 2022-08-13 21:29:03 +03:00
gdlbo b49813e2b1 translation fixes 2022-08-13 20:57:29 +03:00
gdlbo c977cd5bdf translation fixes 2022-08-13 20:57:29 +03:00
Erik Kiznov 9bd5cafc2d delete slashes 2022-08-13 20:46:17 +03:00
Erik Kiznov b96fbc5a5f delete slashes 2022-08-13 20:46:17 +03:00
Erik Kiznov 433801a9d0 fix bug 2022-08-13 20:46:17 +03:00
Erik Kiznov ed115442dc fix bug 2022-08-13 20:46:17 +03:00
Erik Kiznov 3dd4e4df38 translate all strings to RU/EN 2022-08-13 20:46:17 +03:00
Erik Kiznov 8925e85bb4 translate all strings to RU/EN 2022-08-13 20:46:17 +03:00
gdlbo 3c90940695 added buttons to header of dialog 2022-08-13 20:13:48 +03:00
gdlbo d2e9968829 added buttons to header of dialog 2022-08-13 20:13:48 +03:00
gdlbo c7e5c57248 updated jars 2022-08-13 20:13:18 +03:00
gdlbo 7c820b7207 updated jars 2022-08-13 20:13:18 +03:00
gdlbo 0fbdccbecc Update issue templates 2022-08-13 15:44:45 +03:00
gdlbo 61d63d574b Update issue templates 2022-08-13 15:44:45 +03:00
gdlbo c5a0d7d05c Update issue templates 2022-08-13 14:28:22 +03:00
gdlbo d07bf40dc3 Update issue templates 2022-08-13 14:28:22 +03:00
gdlbo d365cd9068 Update issue templates 2022-08-13 14:24:07 +03:00
gdlbo d8a7b451c0 Update issue templates 2022-08-13 14:24:07 +03:00
gdlbo 6ea4822f41 Update issue templates 2022-08-13 14:23:31 +03:00
gdlbo 28ab01cbff Update issue templates 2022-08-13 14:23:31 +03:00
gdlbo cc16f4727f updated gradle to 7.2.2 2022-08-13 13:31:59 +03:00
gdlbo 244bae71e2 updated gradle to 7.2.2 2022-08-13 13:31:59 +03:00
gdlbo 79c2fc9010 some code reformat 2022-08-12 22:08:16 +03:00
gdlbo 66951fa826 some code reformat 2022-08-12 22:08:16 +03:00
gdlbo e9047274b3 StoryCircleImageView + CommunityBorderedImageView java
80 and 136
radius unread 2 read 1
2022-08-12 22:01:58 +03:00
gdlbo ac364f1ae2 StoryCircleImageView + CommunityBorderedImageView java
80 and 136
radius unread 2 read 1
2022-08-12 22:01:58 +03:00
gdlbo 5f57558c52 some rounding improvements 2022-08-12 17:44:40 +03:00
gdlbo 01f956477b some rounding improvements 2022-08-12 17:44:40 +03:00
gdlbo 3c8b394a4b fixed abbr avatar rounding 2022-08-12 17:32:22 +03:00
gdlbo c525427594 fixed abbr avatar rounding 2022-08-12 17:32:22 +03:00
gdlbo f5037dced3 some settings improvements 2022-08-12 02:38:59 +03:00
gdlbo 8a83052941 some settings improvements 2022-08-12 02:38:59 +03:00
gdlbo 274e1bd0df fixed some paths 2022-08-12 01:40:21 +03:00
gdlbo 0bcbf2b4f8 fixed some paths 2022-08-12 01:40:21 +03:00
gdlbo 32daac436e updated jars 2022-08-12 01:39:51 +03:00
gdlbo a7d8e7294f updated jars 2022-08-12 01:39:51 +03:00
gdlbo 820ca12c3e fixed DownloadUtils + added custom folders reset 2022-08-12 01:07:54 +03:00
gdlbo 38aa6c1905 fixed DownloadUtils + added custom folders reset 2022-08-12 01:07:54 +03:00
gdlbo f3cda292e0 fixed superapp crash 2022-08-11 23:50:03 +03:00
gdlbo 91bd29cf93 fixed superapp crash 2022-08-11 23:50:03 +03:00
gdlbo 75c98b98dd mb fix crash sdk 21+ 2022-08-11 23:29:40 +03:00
gdlbo 186a807d54 mb fix crash sdk 21+ 2022-08-11 23:29:40 +03:00
gdlbo cc6e3c2dd8 fix bug 2022-08-11 22:29:11 +03:00
gdlbo 48ba199613 fix bug 2022-08-11 22:29:11 +03:00
Vologhat 9a9a73e89a refactor newsfeed manager 2022-08-11 21:03:35 +03:00
Vologhat df3b374f3a refactor newsfeed manager 2022-08-11 21:03:35 +03:00
gdlbo a6f52af5d1 newsfeedlist manager 2022-08-11 16:05:04 +03:00
gdlbo 5c26dd8ea4 newsfeedlist manager 2022-08-11 16:05:04 +03:00
gdlbo fa12e8f7e0 cache fixes 2022-08-10 13:17:38 +03:00
gdlbo 14cf129435 cache fixes 2022-08-10 13:17:38 +03:00
aliveoutside 3a7a05e630 fix not loading recommended posts page 2022-08-09 19:47:54 +03:00
aliveoutside 073c80d1b0 fix not loading recommended posts page 2022-08-09 19:47:54 +03:00
gdlbo e05fe77fb4 fixed default undel prefix 2022-08-06 23:19:47 +03:00
gdlbo b0856d6232 fixed default undel prefix 2022-08-06 23:19:47 +03:00
gdlbo b86128ac66 TargetImageView 2022-08-06 17:39:34 +03:00
gdlbo 0cdccd6a54 TargetImageView 2022-08-06 17:39:34 +03:00
gdlbo 3e9058002b disabled pinned msg buttons 2022-08-06 15:26:29 +03:00
gdlbo 829a333d7f disabled pinned msg buttons 2022-08-06 15:26:29 +03:00
gdlbo 76775f0ad4 max dp 10 2022-08-06 14:00:24 +03:00
gdlbo 42984efe25 max dp 10 2022-08-06 14:00:24 +03:00
gdlbo 086210718c rounding hook fixes 2022-08-06 13:40:40 +03:00
gdlbo 7656468636 rounding hook fixes 2022-08-06 13:40:40 +03:00
gdlbo bc1f11da61 code imp 2022-08-06 12:49:56 +03:00
gdlbo 448a169bc3 code imp 2022-08-06 12:49:56 +03:00
gdlbo 63075ca216 code imp 2022-08-05 23:13:35 +03:00
gdlbo 27cacc03a2 code imp 2022-08-05 23:13:35 +03:00
gdlbo 4876a881d2 DownloadUtils fixes 2022-08-05 22:24:29 +03:00
gdlbo 2002db57d9 DownloadUtils fixes 2022-08-05 22:24:29 +03:00
gdlbo fef7082e66 DownloadUtils 2022-08-05 21:41:34 +03:00
gdlbo 0aad1ef358 DownloadUtils 2022-08-05 21:41:34 +03:00
gdlbo 4dc7223629 dir fixes 2022-08-05 21:21:18 +03:00
gdlbo d8f5b5e910 dir fixes 2022-08-05 21:21:18 +03:00
aliveoutside 9fbb2fada4 use different request codes for different download types 2022-08-05 21:07:30 +03:00
aliveoutside 3d5c832cec use different request codes for different download types 2022-08-05 21:07:30 +03:00
gdlbo a31d75ea41 more folders picker 2022-08-05 20:49:09 +03:00
gdlbo bc467ac335 more folders picker 2022-08-05 20:49:09 +03:00
gdlbo efa28aa3d6 more folders picker 2022-08-05 20:39:24 +03:00
gdlbo aee5f38fb5 more folders picker 2022-08-05 20:39:24 +03:00
aliveoutside 9dd3a26bab implement download folder picker 2022-08-05 19:53:02 +03:00
aliveoutside a4612a127d implement download folder picker 2022-08-05 19:53:02 +03:00
gdlbo f49bc4d05d some code imp 2022-08-05 19:48:31 +03:00
gdlbo 7a21f11b64 some code imp 2022-08-05 19:48:31 +03:00
gdlbo 0ca4ba2697 some code imp 2022-08-05 19:47:53 +03:00
gdlbo 4775715b66 some code imp 2022-08-05 19:47:53 +03:00
gdlbo 09333dc64d some code imp 2022-08-05 19:28:27 +03:00
gdlbo c481d5fca9 some code imp 2022-08-05 19:28:27 +03:00
aliveoutside 91bfea9917 fix #571
also get rid of java reflection
2022-08-05 03:03:40 +03:00
aliveoutside be65e6816d fix #571
also get rid of java reflection
2022-08-05 03:03:40 +03:00
gdlbo 042595f238 come imp 2022-08-04 15:49:48 +03:00
gdlbo 1f2200c584 come imp 2022-08-04 15:49:48 +03:00
gdlbo 174151b52b some code imp 2022-08-04 14:47:36 +03:00
gdlbo 52b58dc79b some code imp 2022-08-04 14:47:36 +03:00
gdlbo 7fed263a0e DialogItemView converted to java
i am dead inside tbh
2022-08-04 14:30:29 +03:00
gdlbo de92e4670c DialogItemView converted to java
i am dead inside tbh
2022-08-04 14:30:29 +03:00
gdlbo 79fd0350e4 Merge pull request #566 from k1zn/vtl-remaster 2022-08-04 01:24:22 +03:00
gdlbo 4806bb89eb Merge pull request #566 from k1zn/vtl-remaster 2022-08-04 01:24:22 +03:00
Erik Kiznov 4f760b5a4d another renaming 2022-08-04 02:02:44 +05:00
Erik Kiznov 0cdbf9ce99 another renaming 2022-08-04 02:02:44 +05:00
Erik Kiznov f19a4275de Merge branch 'vtl-remaster' of https://github.com/k1zn/lite into vtl-remaster 2022-08-04 02:01:18 +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 7e36bbf83e edit some strings about filters 2022-08-04 01:59:47 +05:00
Erik Kiznov e461b4654e edit some strings about filters 2022-08-04 01:59:47 +05:00
k1zn 0a7338bf89 Fix lower case bug 2022-08-04 01:55:18 +05:00
k1zn 8d7f2dfee8 Fix lower case bug 2022-08-04 01:55:18 +05:00
k1zn c1197e461b Renaming 2022-08-04 01:22:06 +05:00
k1zn bf5bc08671 Renaming 2022-08-04 01:22:06 +05:00
Erik Kiznov 7baaf08167 Add filter for source name 2022-08-04 01:08:30 +05:00
Erik Kiznov 437bef3d03 Add filter for source name 2022-08-04 01:08:30 +05:00
gdlbo 0d75bec938 fixed def catalog music 2022-08-01 22:34:14 +03:00
gdlbo 024079c4bc fixed def catalog music 2022-08-01 22:34:14 +03:00
gdlbo 0af00ab7d1 ads_tracking_disabled true 2022-08-01 22:17:38 +03:00
gdlbo ed53f509ee ads_tracking_disabled true 2022-08-01 22:17:38 +03:00
gdlbo 2011901666 adblock lmao 2022-08-01 21:36:47 +03:00
gdlbo 6b90aedae8 adblock lmao 2022-08-01 21:36:47 +03:00
gdlbo b75ce047df Reducing the size of news traffic by disabling the ad request 2022-08-01 21:09:08 +03:00
gdlbo 4db73ff3d1 Reducing the size of news traffic by disabling the ad request 2022-08-01 21:09:08 +03:00
aliveoutside bfd258ba54 fix #465
added a check for "Music" folder existence
2022-08-01 16:50:29 +03:00
aliveoutside 4a092f0920 fix #465
added a check for "Music" folder existence
2022-08-01 16:50:29 +03:00
Vologhat e499d98050 added "likes on right" displaying mode for posts and viewers 2022-08-01 13:33:58 +03:00
Vologhat 186c1f80e6 added "likes on right" displaying mode for posts and viewers 2022-08-01 13:33:58 +03:00
gdlbo 7299c9e33a some vkui improvements 2022-08-01 01:53:50 +03:00
gdlbo 59c8be9ac2 some vkui improvements 2022-08-01 01:53:50 +03:00
gdlbo 4d0573ffe5 some fixes 2022-08-01 00:48:58 +03:00
gdlbo eb2c4c02d2 some fixes 2022-08-01 00:48:58 +03:00
gdlbo 83d13dce1e read to feature 2022-08-01 00:39:02 +03:00
gdlbo fe2fd354fd read to feature 2022-08-01 00:39:02 +03:00
k1zn 55dbb029c0 Add translate function to catch 2022-07-31 23:01:30 +03:00
k1zn 16fd8925ff Add translate function to catch 2022-07-31 23:01:30 +03:00
k1zn 3df51d0685 Remove %
The percentage in the text breaks the translation process, so I remove it.
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 9bc87a1d79 Another refactoring... 2022-07-31 23:01:30 +03:00
Erik Kiznov 2c8dd6e89a Another refactoring... 2022-07-31 23:01:30 +03:00
Erik Kiznov 94667ac741 Add @ support 2022-07-31 23:01:30 +03:00
Erik Kiznov 91fe8a8fb4 Add @ support 2022-07-31 23:01:30 +03:00
Erik Kiznov 3a354b359a Fix bug 2022-07-31 23:01:30 +03:00
Erik Kiznov cc3456758e Fix bug 2022-07-31 23:01:30 +03:00
Erik Kiznov 09443d6ec1 Refactoring 2022-07-31 23:01:30 +03:00
Erik Kiznov c2dc772905 Refactoring 2022-07-31 23:01:30 +03:00
Erik Kiznov ca27776aaf Don't translate mentions
Don't translate mentions in MessagesHook
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 3b6cdacf96 req dumper 2022-07-31 22:26:36 +03:00
gdlbo 5c79dbe1c2 req dumper 2022-07-31 22:26:36 +03:00
gdlbo c7621c44d5 video history delete 2022-07-31 18:33:37 +03:00
gdlbo f83e97404a video history delete 2022-07-31 18:33:37 +03:00
aliveoutside 89997317bf fix #450 / #547 and speed up logout 2022-07-31 18:10:30 +03:00
aliveoutside f704d54178 fix #450 / #547 and speed up logout 2022-07-31 18:10:30 +03:00
gdlbo c87be6c9b8 about debug activation 2022-07-31 16:58:39 +03:00
gdlbo 3577e3b70c about debug activation 2022-07-31 16:58:39 +03:00
gdlbo 4ae5ea8e57 settings moment 2022-07-31 14:04:23 +03:00
gdlbo 000bd5e7d3 settings moment 2022-07-31 14:04:23 +03:00
gdlbo b967e72a04 cache moment 2022-07-31 13:42:50 +03:00
gdlbo 4d3e8d4354 cache moment 2022-07-31 13:42:50 +03:00
gdlbo cc66af3e3a deepl ded 2022-07-31 13:34:24 +03:00
gdlbo 0d51b40676 deepl ded 2022-07-31 13:34:24 +03:00
Erik Kiznov f82ef2f64e Fix strings about bombs 2022-07-31 13:34:24 +03:00
Erik Kiznov 054f03480e Fix strings about bombs 2022-07-31 13:34:24 +03:00
Vologhat 646329f93b added translation language as argument 2022-07-31 13:34:24 +03:00
Vologhat 114b46ccee added translation language as argument 2022-07-31 13:34:24 +03:00
gdlbo 3f7b9eb796 some imp 2022-07-31 13:34:24 +03:00
gdlbo 0715c0cfcf some imp 2022-07-31 13:34:24 +03:00
gdlbo a3d8a9ba70 fixed gtranslate + added reply’s translate 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 8d05973848 some imp 2022-07-31 13:34:24 +03:00
gdlbo c2c3ea68fa some imp 2022-07-31 13:34:24 +03:00
gdlbo 2b553d263c compiling fix 2022-07-31 13:34:23 +03:00
gdlbo 8e40da9fb4 compiling fix 2022-07-31 13:34:23 +03:00
gdlbo 265d3afbff compiling fix 2022-07-31 13:34:23 +03:00
gdlbo d6b744533b compiling fix 2022-07-31 13:34:23 +03:00
Vologhat 858fced1aa added new translators and choicing of that 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 a01d12b012 Update MessagesSendApiCmd.smali 2022-07-31 13:34:23 +03:00
gdlbo 2904616d67 Update MessagesSendApiCmd.smali 2022-07-31 13:34:23 +03:00
gdlbo 8bde61b059 some fixes 2022-07-31 13:34:23 +03:00
gdlbo 61eac6feca some fixes 2022-07-31 13:34:23 +03:00
gdlbo 05eec57058 fixed dialog 2022-07-31 13:34:23 +03:00
gdlbo 1f29f2ddc5 fixed dialog 2022-07-31 13:34:23 +03:00
gdlbo c2a1a4bb5f dialog fixes 2022-07-31 13:34:23 +03:00
gdlbo fbff3eadde dialog fixes 2022-07-31 13:34:23 +03:00
gdlbo 5e01ebcff6 added bombs 2022-07-31 13:34:23 +03:00
gdlbo 7c8a76616c added bombs 2022-07-31 13:34:23 +03:00
gdlbo ffe0955ef1 updated icons 2022-07-31 13:34:23 +03:00
gdlbo 465d52df67 updated icons 2022-07-31 13:34:23 +03:00
gdlbo f4ca7c9e66 Create ic_deepl_logo_icon.xml 2022-07-31 13:34:22 +03:00
gdlbo 57e69b0d98 Create ic_deepl_logo_icon.xml 2022-07-31 13:34:22 +03:00
gdlbo 57b19369a0 some icons 2022-07-31 13:34:22 +03:00
gdlbo a799828de0 some icons 2022-07-31 13:34:22 +03:00
gdlbo 4019219293 migrated to vkalertdialog 2022-07-31 13:34:22 +03:00
gdlbo e6ad306e24 migrated to vkalertdialog 2022-07-31 13:34:22 +03:00
gdlbo 5d6c001dfb Update DNRInjector.java 2022-07-31 13:34:22 +03:00
gdlbo 5ff1e0a0a6 Update DNRInjector.java 2022-07-31 13:34:22 +03:00
gdlbo 1f2b1b1180 china number one 2022-07-31 13:34:22 +03:00
gdlbo 09048a7a21 china number one 2022-07-31 13:34:22 +03:00
gdlbo cb7862a0e2 updated translate dialog 2022-07-31 13:34:22 +03:00
gdlbo 2e2e890875 updated translate dialog 2022-07-31 13:34:22 +03:00
gdlbo 1cd23341e2 Update Translate.java 2022-07-31 13:34:08 +03:00
gdlbo 271b1cdfee Update Translate.java 2022-07-31 13:34:08 +03:00
gdlbo f85dac2ff8 fixed onclick 2022-07-31 13:34:08 +03:00
gdlbo bc06512250 fixed onclick 2022-07-31 13:34:08 +03:00
gdlbo 992b29894e message hook 2022-07-31 13:34:08 +03:00
gdlbo a94af3a4db message hook 2022-07-31 13:34:08 +03:00
gdlbo 9e67ded6bd code imp 2022-07-31 13:34:07 +03:00
gdlbo 924a34b458 code imp 2022-07-31 13:34:07 +03:00
Vologhat 24607e1ea5 added messages hook and base class for translators 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 8e260a9de4 fixed errors 2022-07-31 13:34:07 +03:00
Vologhat a53a9eaeaa fixed errors 2022-07-31 13:34:07 +03:00
gdlbo de045f749a dialog 2022-07-31 13:33:42 +03:00
gdlbo 88390f0fc9 dialog 2022-07-31 13:33:42 +03:00
gdlbo fde1628fac rebase 2022-07-31 13:33:31 +03:00
gdlbo c6721841ac rebase 2022-07-31 13:33:31 +03:00
Vologhat fdeaa05360 removed deepl and added yandex 2022-07-31 13:32:49 +03:00
Vologhat dfa77311f2 removed deepl and added yandex 2022-07-31 13:32:49 +03:00
Vologhat d0197142cd replace net to okhttp 2022-07-31 13:32:48 +03:00
Vologhat 57e241ab7d replace net to okhttp 2022-07-31 13:32:48 +03:00
gdlbo 8257393909 DeepLApi test 2022-07-31 13:32:48 +03:00
gdlbo 50b97aac8a DeepLApi test 2022-07-31 13:32:48 +03:00
k1zn 9542317b23 Update README.md 2022-07-30 18:32:54 +03:00
k1zn 6166b29b29 Update README.md 2022-07-30 18:32:54 +03:00
gdlbo de595c93f4 fixed msg 2022-07-30 17:54:26 +03:00
gdlbo 7ee1331263 fixed msg 2022-07-30 17:54:26 +03:00
gdlbo 7596b4117a deviceinfo and geodata hide feature 2022-07-30 17:37:28 +03:00
gdlbo 0cc0299215 deviceinfo and geodata hide feature 2022-07-30 17:37:28 +03:00
iNotFlying 8b6ef6d3af Update README.md 2022-07-30 15:48:05 +03:00
iNotFlying a7e0f2ae2b Update README.md 2022-07-30 15:48:05 +03:00
gdlbo 1d71def416 fixed adding music catalog bug 2022-07-30 13:59:54 +03:00
gdlbo c38e0aa61e fixed adding music catalog bug 2022-07-30 13:59:54 +03:00
iNotFlying 18799ce11c Refactoring 2022-07-30 02:33:23 +03:00
iNotFlying 9496da151a Refactoring 2022-07-30 02:33:23 +03:00
gdlbo b4e34e34b1 dialog pin/unpin system (api) 2022-07-30 01:13:52 +03:00
gdlbo 5cec11c6dd dialog pin/unpin system (api) 2022-07-30 01:13:52 +03:00
gdlbo cd6f975e56 updated stock icon 2022-07-29 23:54:37 +03:00
gdlbo a285bf4270 updated stock icon 2022-07-29 23:54:37 +03:00
aliveoutside de73c6216b Merge pull request #539 from ricoshett/vtl-remaster
добавлена быстрая навигация
размер изображений в блоке Линукса и Винды теперь одинаков
2022-07-29 18:30:14 +03:00
aliveoutside 344c418412 Merge pull request #539 from ricoshett/vtl-remaster
добавлена быстрая навигация
размер изображений в блоке Линукса и Винды теперь одинаков
2022-07-29 18:30:14 +03:00
gdlbo 129ae95121 code beautifying 2022-07-29 16:28:49 +03:00
gdlbo 5464053fa0 code beautifying 2022-07-29 16:28:49 +03:00
ricoshett 78cd5cac9a update README.md 2022-07-29 16:23:44 +03:00
aliveoutside f7fab596ba update ffmpeg-kit 2022-07-29 18:39:39 +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 85afaa5057 some java moments 2022-07-29 16:14:24 +03:00
gdlbo dbb25fbabd some java moments 2022-07-29 16:14:24 +03:00
k1zn f1ed0fc221 Fix README.md 2022-07-29 15:20:07 +03:00
k1zn d75a339a02 Fix README.md 2022-07-29 15:20:07 +03:00
aliveoutside b64b17038d Merge pull request #536 from k1zn/vtl-remaster
<!> Ignore *.md files in Github Actions
2022-07-29 14:49:54 +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 e5b5bf9d48 Update README.md (Update README.md)
Update README.md (Update README.md) (Update README.md)
2022-07-29 14:49:44 +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 c58e511040 Update build.yml 2022-07-29 16:41:30 +05:00
k1zn 5264a397a0 Update build.yml 2022-07-29 16:41:30 +05:00
iNotFlying a067a35040 Update README.md 2022-07-29 12:52:35 +04:00
iNotFlying c2fe5e6c3c Update README.md 2022-07-29 12:52:35 +04:00
iNotFlying dbee2a5a42 Update README.md 2022-07-29 12:50:27 +04:00
iNotFlying 7c232b70ed Update README.md 2022-07-29 12:50:27 +04:00
iNotFlying 104ca05772 Update README.md 2022-07-29 12:30:41 +04:00
iNotFlying 8761d23bda Update README.md 2022-07-29 12:30:41 +04:00
iNotFlying ad5eca635a Update README.md 2022-07-29 12:29:31 +04:00
iNotFlying 81203ef531 Update README.md 2022-07-29 12:29:31 +04:00
iNotFlying 6c86b49e97 Update README.md 2022-07-29 12:17:27 +04:00
iNotFlying 743356af01 Update README.md 2022-07-29 12:17:27 +04:00
iNotFlying ad8f2b5b5a Update README.md 2022-07-29 12:15:21 +04:00
iNotFlying 036cf4846c Update README.md 2022-07-29 12:15:21 +04:00
iNotFlying 3058c220a8 Update README.md 2022-07-29 12:13:31 +04:00
iNotFlying 7f97394861 Update README.md 2022-07-29 12:13:31 +04:00
aliveoutside 6531a21fb4 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
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 3366d28e7e Fix locals + fix fields 2022-07-29 03:13:58 +05:00
k1zn 8ec891d0bc Fix locals + fix fields 2022-07-29 03:13:58 +05:00
k1zn 39b08702d5 Set MessagesGetConversationsApiCmd fields to public 2022-07-29 02:29:00 +05:00
k1zn bb318aeeb1 Set MessagesGetConversationsApiCmd fields to public 2022-07-29 02:29:00 +05:00
k1zn b90b27e8ce 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
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 9b03299c7b Update README.md 2022-07-28 23:15:47 +03:00
iNotFlying 108e212c56 Update README.md 2022-07-28 23:15:47 +03:00
iNotFlying a9343c6777 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 a03505f27f 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 b9126aa184 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 613a101c82 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 43fe0577cd 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 6208c966d0 added music grabber 2022-07-28 20:16:01 +03:00
gdlbo 0803e73949 added music grabber 2022-07-28 20:16:01 +03:00
gdlbo 636341b4f2 icon changed 2022-07-28 18:02:20 +03:00
gdlbo e7b8dd56fe icon changed 2022-07-28 18:02:20 +03:00
gdlbo 576ce7d6b0 Revert "Temporary fix for pinned dialogs"
This reverts commit e74001e17e.
2022-07-28 17:48:31 +03:00
gdlbo add56248e1 Revert "Temporary fix for pinned dialogs"
This reverts commit 90a539d361.
2022-07-28 17:48:31 +03:00
k1zn e74001e17e 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
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 48f6b35abe cache sett refactoring 2022-07-28 15:49:24 +03:00
gdlbo ed2645e3ff cache sett refactoring 2022-07-28 15:49:24 +03:00
gdlbo 5beea5d273 screenshot detect 2022-07-28 13:21:37 +03:00
gdlbo cdc8d2eaf2 screenshot detect 2022-07-28 13:21:37 +03:00
gdlbo 842130628e some code improvements 2022-07-28 11:46:08 +03:00
gdlbo bdb9dc670c some code improvements 2022-07-28 11:46:08 +03:00
gdlbo ab26bab35d some settings logic reworked 2022-07-28 02:24:38 +03:00
gdlbo 32b3a035a8 some settings logic reworked 2022-07-28 02:24:38 +03:00
gdlbo 6ffcbe8329 some improvements of scrobbler 2022-07-28 01:41:21 +03:00
gdlbo c44aea13d6 some improvements of scrobbler 2022-07-28 01:41:21 +03:00
gdlbo ca3d1e9585 fixed hint text 2022-07-28 01:40:51 +03:00
gdlbo ce4bb21782 fixed hint text 2022-07-28 01:40:51 +03:00
gdlbo 05a9e9a12c Update Scrobbler.java 2022-07-28 00:49:39 +03:00
gdlbo fa5716d651 Update Scrobbler.java 2022-07-28 00:49:39 +03:00
gdlbo 9e2f3bb048 Update Scrobbler.java 2022-07-28 00:46:52 +03:00
gdlbo c7971c9860 Update Scrobbler.java 2022-07-28 00:46:52 +03:00
gdlbo 91aef33725 lastfm test 2022-07-28 00:15:41 +03:00
gdlbo 9d3e7c53de lastfm test 2022-07-28 00:15:41 +03:00
gdlbo 32c5aa9ac2 fixed crashreporter 2022-07-28 00:15:41 +03:00
gdlbo 81c4e1c019 fixed crashreporter 2022-07-28 00:15:41 +03:00
Vologhat e32c3ec74b The great refactoring 2022-07-27 21:05:15 +03:00
Vologhat a4125653cf The great refactoring 2022-07-27 21:05:15 +03:00
gdlbo 3fea0e9c40 podcasts are dead + returned old vk pay 2022-07-27 18:03:45 +03:00
gdlbo 3c3b51d6ab podcasts are dead + returned old vk pay 2022-07-27 18:03:45 +03:00
gdlbo c9c5c96d63 some pic fixes 2022-07-27 16:42:50 +03:00
gdlbo 9e21dee290 some pic fixes 2022-07-27 16:42:50 +03:00
gdlbo 2a91238b4f upped conv api ver 2022-07-27 15:51:30 +03:00
gdlbo c341e493f8 upped conv api ver 2022-07-27 15:51:30 +03:00
gdlbo e4d740061d upped vk hardcoded build number 2022-07-27 13:52:12 +03:00
gdlbo e6325c74d8 upped vk hardcoded build number 2022-07-27 13:52:12 +03:00
gdlbo f96f2cb7d7 some music fixes 2022-07-27 13:33:47 +03:00
gdlbo e703adb168 some music fixes 2022-07-27 13:33:47 +03:00
gdlbo 0482f75172 some default prefs fix 2022-07-26 19:21:08 +03:00
gdlbo ae2b9e0cce some default prefs fix 2022-07-26 19:21:08 +03:00
gdlbo eaed8fc752 default prefs + fix default fragment 2022-07-26 19:09:38 +03:00
gdlbo 6db84cbc12 default prefs + fix default fragment 2022-07-26 19:09:38 +03:00
gdlbo f871e63002 temp fix for a10+ 2022-07-26 18:50:45 +03:00
gdlbo db41faee3e temp fix for a10+ 2022-07-26 18:50:45 +03:00
gdlbo 189d699d48 some deobf FileUtils (why?) 2022-07-26 18:42:13 +03:00
gdlbo 905158bb07 some deobf FileUtils (why?) 2022-07-26 18:42:13 +03:00
k1zn f3b6b3c1b0 Fix access_token regex (again) 2022-07-26 18:14:32 +03:00
k1zn a08782de4e Fix access_token regex (again) 2022-07-26 18:14:32 +03:00
k1zn 519722d613 Fix access_token regex 2022-07-26 18:14:32 +03:00
k1zn 0fcbffab26 Fix access_token regex 2022-07-26 18:14:32 +03:00
gdlbo 3aaca80da1 fix comments 2022-07-26 18:13:40 +03:00
gdlbo 30d6ccbd9a fix comments 2022-07-26 18:13:40 +03:00
gdlbo b889015368 fixed video catalog + deleted useless feature 2022-07-25 21:59:55 +03:00
gdlbo cd7f3f8b52 fixed video catalog + deleted useless feature 2022-07-25 21:59:55 +03:00
Erik Kiznov 1d3463df0c Add VK Video new icon 2022-07-25 21:49:54 +03:00
Erik Kiznov 4b57fa9414 Add VK Video new icon 2022-07-25 21:49:54 +03:00
Erik Kiznov 60ac497e6d Updated VK Music icon for all DPI 2022-07-25 21:49:54 +03:00
Erik Kiznov 9d3099f816 Updated VK Music icon for all DPI 2022-07-25 21:49:54 +03:00
Erik Kiznov f8192c7169 VK Rebranding (Part 2.1)
Founded and updated some VK logos (in notification, in app-icon)
2022-07-25 21:49:54 +03:00
Erik Kiznov a0c02b2fd1 VK Rebranding (Part 2.1)
Founded and updated some VK logos (in notification, in app-icon)
2022-07-25 21:49:54 +03:00
Erik Kiznov 3f2e0c9b98 New "Music" logo in dockbar 2022-07-25 21:49:54 +03:00
Erik Kiznov df8c86fe4c New "Music" logo in dockbar 2022-07-25 21:49:54 +03:00
Erik Kiznov 2a9ea90df5 VK Rebranding (Part 2)
* Updated VK Logo
* Updated VK Music logo
* Updated VK Pay logo
2022-07-25 21:49:54 +03:00
Erik Kiznov 008a24bfff VK Rebranding (Part 2)
* Updated VK Logo
* Updated VK Music logo
* Updated VK Pay logo
2022-07-25 21:49:54 +03:00
gdlbo aa40bbb390 dockbar improved 2022-07-25 21:19:18 +03:00
gdlbo 5484766ef1 dockbar improved 2022-07-25 21:19:18 +03:00
gdlbo 4782401f0a speedup settings 2022-07-25 21:19:18 +03:00
gdlbo b36a3bfbdb speedup settings 2022-07-25 21:19:18 +03:00
gdlbo 0255cfb1b9 fixed open music catalog 2022-07-25 21:19:18 +03:00
gdlbo 7fc842c9ef fixed open music catalog 2022-07-25 21:19:18 +03:00
gdlbo 764b68d47f fixed tgs dialog 2022-07-25 21:19:18 +03:00
gdlbo 8615faff4a fixed tgs dialog 2022-07-25 21:19:18 +03:00
gdlbo 126154fc9b deleted getAdvertisingId check + deleted vigo tracker 2022-07-25 21:19:18 +03:00
gdlbo ba05c831cc deleted getAdvertisingId check + deleted vigo tracker 2022-07-25 21:19:18 +03:00
gdlbo ec2df87e42 deleted my target lib (fully) 2022-07-25 21:19:18 +03:00
gdlbo 3f11a14d92 deleted my target lib (fully) 2022-07-25 21:19:18 +03:00
gdlbo e963080385 del ad audio lib 2022-07-25 21:19:18 +03:00
gdlbo 0284dec33a del ad audio lib 2022-07-25 21:19:18 +03:00
Erik Kiznov 23286a21f0 VK Rebranding
This commit updates VK logo in all (maybe) pictures
2022-07-25 18:50:25 +03:00
Erik Kiznov 8d376d9e5a VK Rebranding
This commit updates VK logo in all (maybe) pictures
2022-07-25 18:50:25 +03:00
gdlbo 4e48faec16 dockbar fixes 2022-07-25 01:53:12 +03:00
gdlbo ce731b1832 dockbar fixes 2022-07-25 01:53:12 +03:00
gdlbo 666c562092 some migration to VkAlertDialog 2022-07-25 01:45:32 +03:00
gdlbo 64a8552647 some migration to VkAlertDialog 2022-07-25 01:45:32 +03:00
gdlbo 4f5cbe426a dockbar fixes 2022-07-24 22:32:35 +03:00
gdlbo e0b06449ec dockbar fixes 2022-07-24 22:32:35 +03:00
gdlbo 5635cd4139 size text labels 2022-07-24 20:35:56 +03:00
gdlbo 64d62b10a1 size text labels 2022-07-24 20:35:56 +03:00
gdlbo 4bb31d492a bold text labels 2022-07-24 20:11:11 +03:00
gdlbo 1a3cf8695d bold text labels 2022-07-24 20:11:11 +03:00
gdlbo f85fe81881 dockbar colors fix 2022-07-24 19:43:26 +03:00
gdlbo 1251dd1d2d dockbar colors fix 2022-07-24 19:43:26 +03:00
gdlbo 5295e465e9 some profile inj fixes 2022-07-24 16:16:17 +03:00
gdlbo 06d5b1a779 some profile inj fixes 2022-07-24 16:16:17 +03:00
gdlbo 7f30e66c0c new profile buttons injector 2022-07-24 15:24:21 +03:00
gdlbo c18a3dde9e new profile buttons injector 2022-07-24 15:24:21 +03:00
Vologhat d55361fd72 added new way of music downloading 2022-07-24 02:17:20 +03:00
Vologhat 6961bc073a added new way of music downloading 2022-07-24 02:17:20 +03:00
gdlbo 63d1c1a3b0 unlocked dockbar_tab_titles 2022-07-24 00:31:21 +03:00
gdlbo e1b6f8d66f unlocked dockbar_tab_titles 2022-07-24 00:31:21 +03:00
gdlbo 4cc6bfabd0 fixes
foaf time is now with local timezone
fixed music starting
2022-07-24 00:02:46 +03:00
gdlbo b95edec916 fixes
foaf time is now with local timezone
fixed music starting
2022-07-24 00:02:46 +03:00
gdlbo 802f639633 foaf online 2022-07-23 21:36:37 +03:00
gdlbo 8756cd1f20 foaf online 2022-07-23 21:36:37 +03:00
Vologhat 8a90602328 Update JsonInjectors.java 2022-07-22 15:52:04 +03:00
Vologhat 8122c92bbf Update JsonInjectors.java 2022-07-22 15:52:04 +03:00
gdlbo 6f607e9ae8 Update StandartFilter.txt 2022-07-22 15:06:28 +03:00
gdlbo 3e53455a05 Update StandartFilter.txt 2022-07-22 15:06:28 +03:00
gdlbo dd0f238701 fixed parseRepostItem fetch bug 2022-07-22 15:01:09 +03:00
gdlbo 07ddb66264 fixed parseRepostItem fetch bug 2022-07-22 15:01:09 +03:00
gdlbo 600a9da953 speedup adblock 2022-07-22 14:42:25 +03:00
gdlbo 4fef230a06 speedup adblock 2022-07-22 14:42:25 +03:00
gdlbo d14dec88bc speedup adblock + logs 2022-07-22 13:55:43 +03:00
gdlbo 2d73131863 speedup adblock + logs 2022-07-22 13:55:43 +03:00
Vologhat 6e216830d1 optimized new newsfeed adblocker 2022-07-22 02:31:20 +03:00
Vologhat f90ae6bade optimized new newsfeed adblocker 2022-07-22 02:31:20 +03:00
Vologhat 2b6012b1e7 optimized new newsfeed adblocker 2022-07-22 01:42:32 +03:00
Vologhat b4a45a17c7 optimized new newsfeed adblocker 2022-07-22 01:42:32 +03:00
gdlbo ded283df35 speedup stories adblock 2022-07-22 00:34:47 +03:00
gdlbo 8767540164 speedup stories adblock 2022-07-22 00:34:47 +03:00
gdlbo 86a5c60f7f some fixes 2022-07-22 00:29:56 +03:00
gdlbo fb8e327856 some fixes 2022-07-22 00:29:56 +03:00
gdlbo 1d964762ca new adblock (alpha) 2022-07-21 23:35:03 +03:00
gdlbo 344b30aa62 new adblock (alpha) 2022-07-21 23:35:03 +03:00
gdlbo 4a2d2b23f2 unlocked custom newsfeed 2022-07-21 22:08:26 +03:00
gdlbo d776693aea unlocked custom newsfeed 2022-07-21 22:08:26 +03:00
gdlbo a06d129c8d fuck vk 2022-07-21 21:45:23 +03:00
gdlbo aaf2f9c6c9 fuck vk 2022-07-21 21:45:23 +03:00
gdlbo a0b1adbfe9 some ad fixes 2022-07-21 19:38:20 +03:00
gdlbo 5fbabfbe23 some ad fixes 2022-07-21 19:38:20 +03:00
Vologhat 0093463fae fixes in stories adblocker 2022-07-21 16:56:05 +03:00
Vologhat 42645a5414 fixes in stories adblocker 2022-07-21 16:56:05 +03:00
gdlbo 9e572d7844 some ad fixes 2022-07-21 16:34:55 +03:00
gdlbo 5af63e0adf some ad fixes 2022-07-21 16:34:55 +03:00
gdlbo 900dbcfe0a some ad fixes 2022-07-21 15:35:13 +03:00
gdlbo ba430052de some ad fixes 2022-07-21 15:35:13 +03:00
gdlbo e3e06d1638 new stories adblock 2022-07-21 15:30:21 +03:00
gdlbo a81ebed663 new stories adblock 2022-07-21 15:30:21 +03:00
gdlbo 69a4cfa715 def catalog music 2022-07-21 14:16:22 +03:00
gdlbo 920883ada1 def catalog music 2022-07-21 14:16:22 +03:00
gdlbo 21d9c13fdf convBarRecomm 2022-07-21 12:50:46 +03:00
gdlbo 41c5f57ccc convBarRecomm 2022-07-21 12:50:46 +03:00
gdlbo 09bf8e26ce whatsnew block hide 2022-07-21 12:24:09 +03:00
gdlbo 2aa7862fe1 whatsnew block hide 2022-07-21 12:24:09 +03:00
Vologhat 21c0ccd9fc added feature of item state changing by swipe to dockbar and superapp editors 2022-07-21 12:00:46 +03:00
Vologhat 22795bab81 added feature of item state changing by swipe to dockbar and superapp editors 2022-07-21 12:00:46 +03:00
gdlbo aa95b368f8 fix superapp 2022-07-20 23:12:28 +03:00
gdlbo 9ae1c0c1bb fix superapp 2022-07-20 23:12:28 +03:00
Vologhat 4be234632c fixed chat preview 2022-07-20 22:30:23 +03:00
gdlbo 00d37e3721 some settings sorting 2022-07-20 18:40:19 +03:00
gdlbo 4c4a3ae11c vkme warn 2022-07-20 18:21:35 +03:00
gdlbo 7e09e6d4e6 google moment fix 2022-07-20 18:08:07 +03:00
Vologhat b92fa69628 added state changing by swipe for unmoved items to adapter 2022-07-20 17:55:54 +03:00
gdlbo d127a84b07 dockbar_accent is true 2022-07-20 16:50:00 +03:00
gdlbo 95916b4289 some dockbar fixes + accent 2022-07-20 16:42:28 +03:00
gdlbo 5cb5d06993 hide beta feature (need to rework tbh) 2022-07-20 15:54:32 +03:00
gdlbo f0da269968 some dockbar and superapp editor fixes 2022-07-20 15:50:37 +03:00
Vologhat 2fb021ad05 added superapp editor, added titles in dockbar and some changes
-Added new SuperApp editor
-Added titles in dockbar and option for it in settings
-Refactored DockBarAdapter
2022-07-20 15:05:17 +03:00
gdlbo 1981bc9d14 vkpay/games/miniapps hide feature 2022-07-20 12:24:58 +03:00
gdlbo c60cce5467 fixed vkx cringe logging 2022-07-19 21:46:38 +03:00
gdlbo 2035d513f1 updated some wrappers 2022-07-19 21:39:27 +03:00
gdlbo 3849569794 updated some wrappers 2022-07-19 21:38:17 +03:00
gdlbo 9f2f6d6f60 added playlists 2022-07-19 20:58:30 +03:00
gdlbo 586a82a15f disabled stats 2022-07-19 19:02:55 +03:00
gdlbo eba922871f music tricks kekw 2022-07-19 19:02:30 +03:00
gdlbo 337aa7493e music tricks 2022-07-19 16:52:59 +03:00
gdlbo 1ed9f871c3 Update LogWriterService.java 2022-07-19 16:52:59 +03:00
aliveoutside 083d96707c fix #453 2022-07-19 17:21:35 +03:00
aliveoutside 10e0bd50da update .gitignore 2022-07-19 15:58:57 +03:00
gdlbo 2864056186 IconsFragment fixes 2022-07-18 22:42:52 +03:00
gdlbo 8876a66449 icooooooooons! 2022-07-18 22:27:28 +03:00
gdlbo 41a1d29c4b some fixes 2022-07-18 21:44:03 +03:00
gdlbo 1bb10807c4 fix superappitems counter 2022-07-18 21:25:44 +03:00
gdlbo 7f8100660a icons 2022-07-18 15:31:25 +03:00
Vologhat 274a1b9fa8 temporary hooks disabling 2022-07-18 14:26:27 +03:00
gdlbo 03c5f83a42 fix proxy? 2022-07-18 12:50:41 +03:00
gdlbo f394bdfec5 fixed vk me mode 2022-07-18 10:38:05 +03:00
gdlbo 19c9dd102f added some new counters 2022-07-18 03:21:48 +03:00
gdlbo d38038f848 fixed friends hide with birthday 2022-07-18 01:53:56 +03:00
Vologhat 8ab5cdd860 fixed dockbar counters #449 2022-07-18 01:35:26 +03:00
Vologhat 2f30d070ec fixed scroll to top feature 2022-07-18 01:13:14 +03:00
gdlbo 401fc44e91 fixed ExternalLinkHandler 2022-07-17 23:31:43 +03:00
Vologhat 028b3aad59 fix external player crash in vkplayer 2022-07-17 22:31:29 +03:00
gdlbo 8a7c21c549 updated some strings 2022-07-17 21:18:27 +03:00
Vologhat 918967f502 added some features to photo viewer #411
-Added image searching in the internet with feature of selecting search engine
-Added copying image file url to the clipboard
-Added opening image file url in the browsers
2022-07-17 21:15:23 +03:00
gdlbo 95636ad4f4 some settings summ fixes 2022-07-17 16:59:36 +03:00
gdlbo 561afe8765 counters 2022-07-17 15:21:19 +03:00
gdlbo 929e481b3d fixed stickers dialog 2022-07-17 15:21:06 +03:00
gdlbo 69266ed31f fixed live tab + imports 2022-07-17 13:54:23 +03:00
gdlbo 742e0c46b3 some dockbar fixes 2022-07-17 13:21:46 +03:00
gdlbo 319f3c421a updated StandartFilter.txt 2022-07-17 11:37:18 +03:00
gdlbo 3b5eb3cd10 some dockbar fixes 2022-07-17 11:14:45 +03:00
gdlbo 55f71bfd8b added tgsbotkey check if not valid 2022-07-17 11:08:32 +03:00
gdlbo 1ac755a98b some dockbar fixes 2022-07-17 11:03:45 +03:00
gdlbo 00d0b9d237 fixed saving settings 2022-07-17 10:56:04 +03:00
Vologhat edd04586ea make shorter external player string in action menu 2022-07-17 08:42:17 +03:00
gdlbo 98b1cf8db3 some settings fixes 2022-07-17 00:18:22 +03:00
gdlbo d20296d4b8 some settings fixes 2022-07-16 23:42:10 +03:00
gdlbo 7c8627f9f6 dockbar fixes 2022-07-16 23:26:19 +03:00
gdlbo 2e2be2fe4a added disabler of OnlineFormatter 2022-07-16 23:02:38 +03:00
Vologhat 673d5fe16c fix #443 2022-07-16 18:07:54 +03:00
aliveoutside 4a949e7d45 [musicdownloader] increase the audio quality 2022-07-16 20:01:25 +03:00
aliveoutside 39391a4ace [musicdownloader] fix previous commit 2022-07-16 19:43:16 +03:00
aliveoutside 9a9552c369 [musicdownloader] show the download progress in notifications 2022-07-16 19:39:10 +03:00
Vologhat 6b9f80284c dockbar editor fixes 2022-07-15 17:39:25 +03:00
gdlbo 15dd2b2fde some hooks refactoring 2022-07-15 11:09:15 +03:00
aliveoutside 4b2a537e3b fix vkx integration 2022-07-15 02:39:17 +03:00
gdlbo a94ca687eb Update CopyrightAds.txt 2022-07-14 23:00:00 +03:00
gdlbo 06f0864cc3 fix getVoiceListened 2022-07-14 22:33:13 +03:00
gdlbo 1ddc2f6b14 fixed dialog style in tgs and PreferencesUtil 2022-07-14 22:12:23 +03:00
Vologhat ad6c350e69 changed dockbar editor logic
- Changed data storage method
- Added json config check
- Some optimizations
2022-07-14 22:10:37 +03:00
gdlbo dadbc37189 Update MsgMarkAsListenedJob.smali 2022-07-14 21:50:40 +03:00
gdlbo d646a0cd19 getVoiceListened inj 2022-07-14 21:48:58 +03:00
gdlbo ae145691c5 Fixed vkx inj + some fixes 2022-07-14 21:15:29 +03:00
Vologhat a6cbf35350 fix #416 2022-07-14 20:09:46 +03:00
Vologhat aba12ad48a added base fragment with toolbar implementation 2022-07-14 20:09:20 +03:00
Vologhat 32ebf0e4f4 added layout helper 2022-07-14 20:08:52 +03:00
gdlbo 099de74ac1 miniapps hide feature 2022-07-14 19:27:53 +03:00
gdlbo dd490abf69 hide friends recomm in friends 2022-07-14 18:27:10 +03:00
gdlbo 3468b9352e android:debuggable="false" 2022-07-14 12:15:00 +03:00
gdlbo af0efb7184 Update build.gradle 2022-07-14 02:44:53 +03:00
gdlbo 592d25bf6d Update build.gradle 2022-07-14 02:36:36 +03:00
gdlbo a53f1d7299 disabled force miui dark theme 2022-07-14 01:43:15 +03:00
gdlbo ea3707cebd added check for android sdk 26 to get adaptive icon 2022-07-14 01:37:27 +03:00
gdlbo b2ba9774bc some codebase to future update with support no adaptive icons 2022-07-14 01:34:11 +03:00
gdlbo 7205c78839 Update DockBarEditorFragment.java 2022-07-14 01:12:55 +03:00
gdlbo 26672cfbc2 Update build.gradle 2022-07-14 01:12:52 +03:00
gdlbo 941335ec02 added splashscreen for < Android 12
pls check
2022-07-14 00:35:14 +03:00
gdlbo 8bbf0ebb1f added cleaning web cache for theme changing 2022-07-14 00:13:56 +03:00
gdlbo 9d16d4e57e deleted some useless and dead vk features 2022-07-13 23:45:57 +03:00
gdlbo cece5a2a55 disabled feature 2022-07-13 19:07:42 +03:00
gdlbo fb907d68a4 dnt inj 2022-07-13 19:03:44 +03:00
gdlbo dac2e10a52 recomm disabler 2022-07-13 18:49:45 +03:00
gdlbo 0e472e985b fixed crash + added notifs about verif 2022-07-13 18:41:41 +03:00
gdlbo e349193afb Update IconsFragment.java 2022-07-13 18:06:31 +03:00
Vologhat 066beb14f1 Update IconsFragment.java 2022-07-13 17:57:48 +03:00
gdlbo 15f8af1e3e icon manager test dead 2022-07-13 17:41:44 +03:00
gdlbo 599ee3dfab VideoDownloader fix 2022-07-13 17:26:29 +03:00
gdlbo 9d005cd2e0 Update TokenConfirmationHandlerChainCall.smali 2022-07-13 15:29:07 +03:00
gdlbo c8747ea957 fix 2022-07-13 15:18:31 +03:00
gdlbo 6bc33dbb31 some connection fixes 2022-07-13 15:05:13 +03:00
Vologhat 303fe83ff9 added vk video opening externally 2022-07-13 13:21:40 +03:00
Vologhat cb122bb6c8 added external player redirection 2022-07-13 05:34:22 +03:00
Vologhat bb73aaa580 fixed toolbar visibility 2022-07-13 04:20:02 +03:00
gdlbo 7e7730e825 codebase for future multiple list pref with appnames and icons 2022-07-13 01:28:15 +03:00
aliveoutside 8f291b058f [musicdownloader] hook track bottomsheet 2022-07-13 04:23:58 +03:00
gdlbo 0f9ab88e68 Update OtherFragment.java 2022-07-13 01:10:50 +03:00
gdlbo 36c244be15 some backup fixes 2022-07-13 01:03:04 +03:00
gdlbo 71d4cd09fc added some icons 2022-07-13 00:50:17 +03:00
Vologhat 037f1809e8 added restore prefs from file 2022-07-13 00:30:37 +03:00
Vologhat 3513844ca5 optimizations 2022-07-12 23:58:00 +03:00
Vologhat 2e180d2c9c added vkme mode checker 2022-07-12 23:49:53 +03:00
Vologhat fd3eae0283 fixed dockbar counter 2022-07-12 23:14:51 +03:00
gdlbo 048a835b2b icons fix 2022-07-12 23:11:45 +03:00
Vologhat e144390d4f refactored icon switcher 2022-07-12 23:08:41 +03:00
gdlbo 320892cdf5 added all to manifest 2022-07-12 23:04:29 +03:00
gdlbo 1716aa51dd some fixes 2022-07-12 22:45:14 +03:00
gdlbo 7157a0c664 icon changer test
appname cursed
2022-07-12 21:55:20 +03:00
gdlbo 34787ffb5b added resources 2022-07-12 19:32:50 +03:00
gdlbo d44b363d1d null check 2022-07-12 18:29:59 +03:00
gdlbo 3972ceba5b network check 2022-07-12 18:27:35 +03:00
gdlbo 505a2d4553 some fragments in dockbar fixes 2022-07-12 17:42:46 +03:00
gdlbo 84da0b422a superapp disabler fix 2022-07-12 17:34:04 +03:00
gdlbo ab19f6b71a new vkpay lol 2022-07-12 17:25:02 +03:00
gdlbo 9c8f962e5f some sticker fixes 2022-07-12 16:28:00 +03:00
gdlbo ad706355cd some filter fixes 2022-07-12 16:15:11 +03:00
gdlbo efac38a871 added some effects) 2022-07-12 15:49:02 +03:00
gdlbo 049940f3bb some filters fix + added more filters codebase 2022-07-12 15:21:05 +03:00
aliveoutside 5f68809d9c use track id as a temp folder name 2022-07-12 17:37:08 +03:00
gdlbo 930792f983 monochrome wp 2022-07-12 14:14:10 +03:00
gdlbo 5e7eb51127 mosaic effect 2022-07-12 13:46:04 +03:00
gdlbo 99a387f9a0 fixed crash 2022-07-12 12:42:09 +03:00
gdlbo 679960045a some fragments fixes 2022-07-12 12:12:48 +03:00
gdlbo 1dc1436082 restart app when dark theme changed to amoled 2022-07-12 11:11:47 +03:00
gdlbo 2ba602ae9f restart app when milkshake val changed 2022-07-12 11:00:18 +03:00
gdlbo 98aa6ef0f8 disabled force dark theme for miui 2022-07-12 10:58:17 +03:00
gdlbo b8f5b0179a fixed milkshake changer 2022-07-12 00:00:54 +03:00
gdlbo 877670bb84 Update DockBarManager.java 2022-07-11 23:21:48 +03:00
Vologhat 5859b93612 Update DockBarManager.java 2022-07-11 21:59:05 +03:00
gdlbo 0f33dfc395 codesyle cringe 2022-07-11 21:14:02 +03:00
gdlbo 0330b8ad8e lmao 2022-07-11 21:11:17 +03:00
gdlbo 7d85d61eb5 fix dockbar 2022-07-11 20:58:45 +03:00
aliveoutside 28ee64fc30 create notifications for music downloading 2022-07-11 23:02:10 +03:00
gdlbo 19bc27059d Update BottomNavigationMenu.smali 2022-07-11 20:00:53 +03:00
gdlbo 457822de7d Update CopyrightAds.txt 2022-07-11 19:57:37 +03:00
Vologhat 4c5d83fccc refactored dockbar editor 2022-07-11 19:57:03 +03:00
gdlbo 92c9ea2222 Update WallpaperMenuFragment.java 2022-07-11 19:35:07 +03:00
gdlbo e6b7ea8c2c Update WallpaperMenuFragment.java 2022-07-11 19:34:28 +03:00
gdlbo 81bc85a0aa added stickers background if wallpaper is not null 2022-07-11 19:28:48 +03:00
gdlbo f9b02b1cce fix dark toast lmao 2022-07-11 19:17:23 +03:00
gdlbo 2cb6321776 fixed dialog style 2022-07-11 19:11:51 +03:00
gdlbo bbf0ada834 fixed auth proxy dialog 2022-07-11 17:56:03 +03:00
aliveoutside 8c63ff69c7 check if ffmpeg converted successfully 2022-07-11 20:14:34 +03:00
aliveoutside 94c72eb490 finish music downloader 2022-07-11 19:55:04 +03:00
aliveoutside d1f2a78a48 fix ts to mp3 converter 2022-07-11 19:26:05 +03:00
aliveoutside 2983afcda5 update ffmpeg libs for mp3 support 2022-07-11 19:25:41 +03:00
aliveoutside fe87a5dd64 fix ffmpeg loading 2022-07-11 18:07:22 +03:00
gdlbo 9daa346e31 dialog design fixes 2022-07-11 14:36:22 +03:00
gdlbo 816683ac8a disabled dockbar hook 2022-07-11 13:30:02 +03:00
gdlbo b90fd41bf2 added dev ver mark 2022-07-11 13:18:32 +03:00
gdlbo 991f1f9eb8 Update Globals.java 2022-07-11 13:13:17 +03:00
gdlbo 2ae9df03e1 fixed player on gappless phones 2022-07-11 13:08:37 +03:00
gdlbo 665e2dda05 added proxy button at start 2022-07-11 13:02:31 +03:00
gdlbo a5134f1cd5 writebar coloring 2022-07-11 11:26:05 +03:00
gdlbo 3680ff44a2 Some animation fixes 2022-07-11 02:58:43 +03:00
gdlbo 34ae44016d some wp fixes 2022-07-11 02:20:19 +03:00
gdlbo a0ebc913d1 fixed some cringe blur 2022-07-11 01:38:22 +03:00
gdlbo 1afa317e7b Wallpaper in msg
Upgraded dialogs opening
2022-07-11 01:29:55 +03:00
aliveoutside 84c194d318 try to do ffmpeg convert 2022-07-11 01:34:28 +03:00
aliveoutside 56cd2b2d39 add some missing classes 2022-07-11 01:34:28 +03:00
aliveoutside b001517a63 add some missing classes 2022-07-11 01:34:27 +03:00
aliveoutside cd389af2bd update build.gradle 2022-07-11 01:34:27 +03:00
aliveoutside 69a2f03656 add ffmpeg wrapper 2022-07-11 01:34:27 +03:00
aliveoutside 047b547449 add ffmpeg lib 2022-07-11 01:34:27 +03:00
aliveoutside 0912f57184 add libs to assets 2022-07-11 01:34:27 +03:00
gdlbo 568f69db60 Update GroupApiParser.smali 2022-07-10 19:16:43 +03:00
aliveoutside 511c16771d fix permissions in AudioDownloader 2022-07-10 22:08:58 +03:00
gdlbo 321273c54a Renames for profiles and groups 2022-07-10 19:01:25 +03:00
gdlbo f6e0a7edb4 Fix 2022-07-10 17:49:59 +03:00
gdlbo dd9b2a8a58 menu inj test 2022-07-10 17:48:39 +03:00
Vologhat 77f80883ae add method check 2022-07-10 17:31:09 +03:00
Vologhat ec5b8b3455 added asyns downloading 2022-07-10 16:37:31 +03:00
gdlbo cd611afbd3 Update vt_ui_oled.css 2022-07-10 16:03:42 +03:00
gdlbo 943c612581 amoled theme wtf 2022-07-10 16:01:04 +03:00
aliveoutside 2ed8082df2 test m3u8 downloader 2022-07-10 18:32:02 +03:00
gdlbo 4806d97e29 fixed crash at start 2022-07-10 15:25:19 +03:00
gdlbo c603c9844a updated jars + added amoled theme values to code 2022-07-10 14:52:23 +03:00
aliveoutside a3b1220f18 move some stuff to music package 2022-07-10 17:35:10 +03:00
gdlbo 18582c535a reformated code 2022-07-10 14:32:27 +03:00
Vologhat d002d05b2a M3U8 Dumper 2022-07-10 14:11:27 +03:00
gdlbo c198a14e0c Some online fixes 2022-07-10 10:54:25 +03:00
gdlbo deda04cbf8 Update OnlineFormatter.java 2022-07-10 04:05:03 +03:00
gdlbo 021e85d5b8 Update OnlineFormatter.java 2022-07-10 03:21:35 +03:00
gdlbo 0921485959 added appid saving + some fixes 2022-07-10 01:38:14 +03:00
aliveoutside 82aacf32b7 - Дашь списать домашку?
- Да, только не списывай точь-в-точь
-
2022-07-10 04:14:55 +03:00
gdlbo e7b0ae0225 Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-07-10 01:08:41 +03:00
aliveoutside 2fb7778717 m3u8 shit 2022-07-10 04:07:02 +03:00
gdlbo a993993773 imports 2022-07-10 01:08:19 +03:00
gdlbo 6f49e35b22 Added local caching appid names 2022-07-10 01:07:55 +03:00
gdlbo ea277c303f VideoDownloader inj 2022-07-09 22:40:56 +03:00
gdlbo a7652e4e71 Fixed bug with reload mgs on old design on sdk 28+ 2022-07-09 22:18:28 +03:00
gdlbo 5cb7306613 Update StoryDownloader.java 2022-07-09 22:03:20 +03:00
gdlbo 1ddecb47af Stories video downloader 2022-07-09 21:59:42 +03:00
gdlbo ac2c972b9b some stories download fixes 2022-07-09 21:24:35 +03:00
gdlbo 86798ffb59 disabled fixGapps 2022-07-09 20:47:18 +03:00
gdlbo a85a7d84b2 isMusicRestricted must be true by default 2022-07-09 20:26:49 +03:00
gdlbo 1ed90da1b8 Update VideoDownloader.java 2022-07-09 20:22:38 +03:00
gdlbo a2b231f365 Update VideoDownloader.java 2022-07-09 20:19:05 +03:00
gdlbo a618b2cc5b check if link is not valid 2022-07-09 20:18:31 +03:00
gdlbo 4e4c287111 Video downloader in settings 2022-07-09 20:09:02 +03:00
gdlbo 060f24b6c6 updated jars 2022-07-09 19:48:22 +03:00
gdlbo d3840bf9fd renamed music to media settings + some settings refactoring 2022-07-09 19:48:06 +03:00
gdlbo ba216cb06b Update Newsfeed.java 2022-07-09 19:31:11 +03:00
gdlbo 917f5b565f Some settings logic fixes 2022-07-09 18:47:32 +03:00
gdlbo 938c6ff633 fixed poll if 2022-07-09 16:03:28 +03:00
gdlbo 56bf382618 show poll results 2022-07-09 15:58:38 +03:00
gdlbo eb3cc75a98 updated jars 2022-07-09 15:58:18 +03:00
gdlbo f3e3cdf79a fix msg db 2022-07-09 15:26:37 +03:00
gdlbo ad808263d1 Story downloader test
video download dead xd
2022-07-09 15:13:13 +03:00
gdlbo 53616c8bc6 updated jars 2022-07-09 15:12:45 +03:00
gdlbo 466105d69c Update NavigationDelegateBottom.smali 2022-07-08 14:29:07 +03:00
gdlbo 64c9cff0bb VK Me mode inject 2022-07-08 14:10:27 +03:00
gdlbo 8fbbf8b6be kostil for dockbak lol 2022-07-08 13:58:26 +03:00
gdlbo 6c0d5619e4 inj dockbar 2022-07-08 13:36:25 +03:00
gdlbo c3c41f9d2e Fixed feed cache toggle 2022-07-08 11:03:15 +03:00
gdlbo a154138fb5 Video redesign optional 2022-07-08 11:00:03 +03:00
gdlbo 0bf6821a4b Update Toggles.java 2022-07-08 10:55:08 +03:00
gdlbo 470ac9dd4d VTSettings fixes
fixed design
fixed proxy type null
2022-07-08 10:49:12 +03:00
gdlbo b68b10f776 Update DockBarManager.java 2022-07-08 10:35:26 +03:00
gdlbo c06f2588a8 Update DockBarManager.java 2022-07-08 10:31:35 +03:00
gdlbo f6ade7a059 Update DockBarManager.java 2022-07-07 21:38:42 +03:00
gdlbo 08d7851de3 Fixed dockbar color?, fixed double vt icons 2022-07-07 20:37:49 +03:00
gdlbo 78902110eb fixed R.java.......... 2022-07-07 20:14:37 +03:00
gdlbo b7b9de4ba4 Revert "Update public.xml"
This reverts commit 487cb6c076.
2022-07-07 19:48:48 +03:00
gdlbo 83014931dc IconManager manifest inject 2022-07-07 19:18:02 +03:00
gdlbo 46edd53cb6 Fixed AndroidManifest 2022-07-07 19:12:31 +03:00
Vologhat 87b1251f5a Update R.java 2022-07-07 19:02:00 +03:00
gdlbo 4ce73d9e55 Update IconManager.java
fixed logic
2022-07-07 16:41:58 +03:00
gdlbo 4541ef61c1 Update IconManager.java 2022-07-07 16:40:40 +03:00
gdlbo 4f3f26e3f5 Update IconManager.java 2022-07-07 16:33:14 +03:00
gdlbo 1f235bfc4a Update IconManager.java 2022-07-07 16:30:24 +03:00
gdlbo 548a029db2 IconManager codebase 2022-07-07 16:26:19 +03:00
aliveoutside 6d1b964239 hook dockbar 2022-07-07 16:37:26 +03:00
gdlbo 487cb6c076 Update public.xml 2022-07-07 13:16:36 +03:00
gdlbo 5a372f6c60 Update R.java 2022-07-07 11:51:39 +03:00
gdlbo 81f954d25a fix download icon for tgs 2022-07-07 11:39:29 +03:00
aliveoutside ec3248f5c3 telegram stickers doesn't look like shit now 2022-07-07 04:58:27 +03:00
gdlbo c959d5e5d6 tgs inj 2022-07-06 18:07:49 +03:00
Vologhat 49798694b2 fixed crashes in StickersFragment 2022-07-06 17:39:39 +03:00
gdlbo 3879555297 some music fixes 2022-07-06 11:40:02 +03:00
gdlbo fc11e2d055 Update VTSettings.java 2022-07-06 10:04:57 +03:00
gdlbo 4905e8fed0 updated superapp in settings 2022-07-06 09:58:04 +03:00
Vologhat 9a02f2a7c3 fixed superapp injector 2022-07-05 20:51:02 +03:00
Vologhat 03014f245c fixed profile hiding 2022-07-05 20:43:20 +03:00
Vologhat 13f247467c optimizations 2022-07-05 20:11:06 +03:00
gdlbo 5116f507c5 Update ProfileHide.java 2022-07-05 16:28:17 +03:00
gdlbo 228e6ea282 profile hide inj test
profiles dead lmao
2022-07-05 16:25:01 +03:00
gdlbo 7663d4cee2 Update JsonInjectors.java 2022-07-05 15:11:24 +03:00
gdlbo 4e003d355e Update JsonInjectors.java 2022-07-05 15:00:31 +03:00
gdlbo 75982656b1 upgraded convBar ext + added debug link 2022-07-05 14:51:44 +03:00
gdlbo 2f12cb188f Update Proxy.java 2022-07-05 13:11:24 +03:00
gdlbo 46cd9c0582 Update Proxy.java 2022-07-05 13:07:32 +03:00
gdlbo 8be76aa871 proxy fixes 2022-07-05 13:02:24 +03:00
gdlbo 9d9c02bec5 Some settings + proxy fixes 2022-07-03 14:11:33 +03:00
gdlbo 30faa329e9 Fix proxy summ for vt settings 2022-07-03 13:39:22 +03:00
gdlbo 0a9322741c Fix crash for android 5, 5.1, 6 + added cute icon for superapp editor 2022-07-03 13:33:27 +03:00
gdlbo f68cc4a6bd fixed scaling pic 2022-07-02 14:00:54 +03:00
gdlbo 0717fd960e Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-07-02 12:55:27 +03:00
gdlbo 0dcb2b8fd7 fixed rounding pic 2022-07-02 12:55:17 +03:00
gdlbo 2581b5a1a2 Merge pull request #410 from k1zn/vtl-remaster 2022-07-02 08:19:27 +03:00
k1zn 36cd21f7f6 Fix Russian music subscription string 2022-07-02 02:00:06 +05:00
k1zn e09a6291fe Fix Ukrainian music subscription string 2022-07-02 01:59:30 +05:00
gdlbo f800dffb5f music subs warning 2022-07-01 15:41:35 +03:00
gdlbo 86ba91a77e deleted useless feature 2022-07-01 15:37:59 +03:00
gdlbo 6aade65b4b fixed loopedanimstickers pref 2022-07-01 14:55:31 +03:00
gdlbo ba1aeeb4b1 Loop anim stickers test 2022-07-01 14:45:05 +03:00
gdlbo 4467abc181 added more font sizes 2022-07-01 14:29:52 +03:00
gdlbo 75960a7631 Fixes
Deleted unused code
Fixed some settings
Sorted toggles features
2022-07-01 14:24:16 +03:00
Vologhat 8209aa6fdf added backup settings in test mode 2022-06-30 19:47:11 +03:00
gdlbo 38bcd40ad6 fixed some toggles 2022-06-30 17:55:09 +03:00
gdlbo dbc358d0a0 superapp editor test 2022-06-30 17:40:20 +03:00
gdlbo dcb2244498 Update JsonInjectors.java 2022-06-30 14:33:05 +03:00
Vologhat e3b6bd8219 fixed fox1d code 2022-06-30 14:20:31 +03:00
aliveoutside 07f1f62fb7 fix ne4italki popup menu 2022-06-30 01:59:33 +03:00
aliveoutside 89f94df42b yes milkshake 2022-06-30 01:44:28 +03:00
gdlbo b3197aa921 startfragment inj 2022-06-29 20:31:31 +03:00
gdlbo cfc2c67efc Update SuperAppPresenter.smali 2022-06-29 20:29:27 +03:00
gdlbo d3b1e6e075 superapp inj
without superapp editor
2022-06-29 20:20:49 +03:00
gdlbo b221a8d55d no shopping v2 2022-06-29 18:49:15 +03:00
gdlbo 9cc6d4f8e0 no shopping anymore in stock menu 2022-06-29 18:03:02 +03:00
gdlbo 1a0a24df45 Fixed crash in interface sett 2022-06-29 17:56:32 +03:00
gdlbo f74b2b1acf fixed translation 2022-06-29 17:46:33 +03:00
gdlbo c7b5b7d6ca More animations :) 2022-06-29 17:42:51 +03:00
gdlbo 215d747dad Test fix anim crash in My Stickers 2022-06-29 17:41:29 +03:00
gdlbo c10b3e5619 anim inj 2022-06-29 17:08:51 +03:00
gdlbo f03d4892a2 fixed imports 2022-06-29 16:49:15 +03:00
gdlbo 6c84540a5d fix 2022-06-29 16:40:44 +03:00
gdlbo 664e1fe428 deleted some unused code 2022-06-29 16:08:29 +03:00
gdlbo 328b2caecb do not seen stories inj 2022-06-29 16:03:17 +03:00
gdlbo 0799757097 showmenu inj 2022-06-29 15:46:25 +03:00
gdlbo 8c9fee306f disable videofeed inj 2022-06-29 15:39:50 +03:00
gdlbo c23624ab11 milkshake disabled by default + disabled welcome banner on milkshake 2022-06-29 15:29:13 +03:00
gdlbo ea4315274b fixed msgs 2022-06-29 13:49:43 +03:00
gdlbo 947183ff02 Maybe fix msg 2022-06-29 13:28:22 +03:00
gdlbo dbe80696d6 Update StandartFilter.txt 2022-06-29 12:02:39 +03:00
gdlbo 1296ab56a7 Refactored reposts adblock + updated filter 2022-06-29 11:53:24 +03:00
gdlbo bda751e692 updated filters 2022-06-29 11:47:44 +03:00
gdlbo 5135cfa347 some important fixes 2022-06-29 01:21:05 +03:00
aliveoutside c450ef7f87 update apktool 2022-06-28 19:57:25 +03:00
aliveoutside bd470aba41 inject ne4italki into dialog menu 2022-06-28 19:57:25 +03:00
gdlbo 3435531cb2 Updated Toggles 2022-06-28 01:27:44 +03:00
gdlbo e784f8a27b Update Toggles.java 2022-06-28 01:05:45 +03:00
gdlbo 96e9579bbf fixed crash in music + added disabler milkshake 2022-06-27 23:55:57 +03:00
aliveoutside 36432e0c80 ne4italki 2022-06-27 20:54:04 +03:00
gdlbo b58a918f27 toggles redirect 2022-06-27 19:45:51 +03:00
gdlbo e8753831b6 ServerDialog disabler 2022-06-27 18:40:11 +03:00
gdlbo 7068600d3d covbar inj test 2 2022-06-27 17:58:30 +03:00
gdlbo b9443f0d78 covbar inj test 2022-06-27 16:47:41 +03:00
gdlbo 3ca54043d8 fixed adfilter 2022-06-27 15:26:37 +03:00
gdlbo e672a6dcf4 upgraded newsfeed ad posts detection
added support for reposts
refactored copyright posts detection
updated adblock filters
2022-06-27 15:15:42 +03:00
gdlbo 453d90827b Update build.yml 2022-06-26 20:55:30 +03:00
gdlbo 13f68a3b12 Messages -> Chats 2022-06-26 20:50:36 +03:00
gdlbo 07a26092ae Merge pull request #392 from iNotFlying/vtl-remaster 2022-06-26 17:49:40 +03:00
iNotFlying 57b6ba04b3 Telegram icon fix 2022-06-26 18:47:55 +04:00
gdlbo cf744757b6 Update FriendsGetRecommendationsWithMutual.smali 2022-06-26 17:04:33 +03:00
gdlbo 59afe0a412 Merge pull request #391 from iNotFlying/vtl-remaster 2022-06-26 16:40:12 +03:00
iNotFlying 488eb7c0ea New icons 2022-06-26 16:35:03 +04:00
gdlbo 2a7af94f10 Update OnlineFormatter.java 2022-06-25 20:29:41 +03:00
gdlbo 1922863723 Update OnlineFormatter.java 2022-06-25 20:27:02 +03:00
gdlbo 1259231653 Update OnlineFormatter.java 2022-06-25 20:15:28 +03:00
gdlbo ba8d3c42a1 updated Online Formatter 2022-06-25 20:13:58 +03:00
gdlbo ab851d3600 Custom online detection
need to do make requests to get appid name from vk
2022-06-25 19:39:34 +03:00
gdlbo b80213a017 ServerDialog upgraded 2022-06-25 15:36:44 +03:00
gdlbo 8cb4bb0a55 ServerDialog upgraded 2022-06-25 15:36:10 +03:00
gdlbo 58cddd18e2 ServerDialog null check 2022-06-25 14:50:12 +03:00
gdlbo 67c0a3eed4 ServerDialog impl 2022-06-25 14:41:42 +03:00
gdlbo e7c7dae411 fixed verifications 2022-06-25 12:39:17 +03:00
gdlbo f66d2af98a fixed number rounding in groups 2022-06-25 12:28:12 +03:00
gdlbo dc3e6293ee fixed number rounding in groups 2022-06-25 12:24:31 +03:00
gdlbo 05397f69d0 fixed crash 2022-06-25 12:13:18 +03:00
gdlbo 9f341eb485 fixes of music and debug 2022-06-25 12:05:22 +03:00
gdlbo e944f5bdf5 fixes of music and debug 2022-06-25 12:05:15 +03:00
gdlbo a0a34d138f fixed crashreport icon 2022-06-25 12:01:26 +03:00
gdlbo 4b55279c84 added install permission 2022-06-25 11:57:57 +03:00
gdlbo b5a7852f2e fixed ota requests 2022-06-25 11:55:56 +03:00
gdlbo b675834a6f deleted benchmark tracker + fixes 2022-06-25 11:46:05 +03:00
gdlbo 09e509e48f deleted music tracker 2022-06-25 11:33:37 +03:00
gdlbo e2b6a3a75e fixed profile open 2022-06-25 11:11:34 +03:00
gdlbo dc4c31d66a fixed libvoip lib 2022-06-25 11:00:11 +03:00
gdlbo abeb31f4f0 fixes of LinkProcessorKt 2022-06-25 10:52:05 +03:00
gdlbo c7b91b62e6 added some redirects to settings 2022-06-25 10:30:56 +03:00
gdlbo 648369b7cd added support to open links from m.vk.com 2022-06-25 09:23:01 +03:00
gdlbo 3f834cc83b Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-06-25 09:19:06 +03:00
gdlbo 4dd5f13b3a gmap fix + added needed activities and services 2022-06-25 09:18:56 +03:00
gdlbo faea96a786 gmap fix 2022-06-25 09:11:33 +03:00
aliveoutside 7882968a05 vkx integration 2022-06-25 04:05:11 +03:00
gdlbo d6595f54f1 newsfeed filter inj to NewsfeedCustomGet 2022-06-25 01:06:00 +03:00
gdlbo 6f1ba0ca9f stories ads inj 2022-06-25 00:30:01 +03:00
gdlbo daee7c8665 awayphp inj 2022-06-25 00:28:08 +03:00
gdlbo dd591ee78b added donate button 2022-06-25 00:22:15 +03:00
gdlbo f72ff25ebe inj refresh newsfeed 2022-06-24 23:44:39 +03:00
gdlbo 04cf3b1b8a swipe stories inj 2022-06-24 23:41:28 +03:00
gdlbo 0cd82deaa6 dockcounter inj 2022-06-24 23:41:13 +03:00
gdlbo 826b566540 alteremoji inj 2022-06-24 23:33:31 +03:00
gdlbo a2018f85b4 system emoji inj 2022-06-24 23:26:06 +03:00
aliveoutside f48e05badb fix init 2022-06-24 23:21:45 +03:00
gdlbo 21ad47b45b fixed some settings logic for stupid users 2022-06-24 23:20:43 +03:00
gdlbo ea54706e8b added date formatter + deleted some unused code 2022-06-24 23:14:51 +03:00
gdlbo db6c23d511 chat count load inj + fixes 2022-06-24 22:54:56 +03:00
gdlbo d06396a51d date formatter in chats 2022-06-24 22:53:28 +03:00
gdlbo bc5cc9b6f6 Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-06-24 22:37:47 +03:00
gdlbo b05d6fb22b value rounding 2022-06-24 22:37:40 +03:00
aliveoutside 3144dd07e8 hooked stories disabler 2022-06-24 22:13:48 +03:00
gdlbo 247627fe08 shortpost 2022-06-24 22:07:18 +03:00
gdlbo 32668111e1 fixed dialogs load 2022-06-24 20:27:43 +03:00
gdlbo c3848fdbba upped vk ver 2022-06-24 20:02:23 +03:00
gdlbo 834367ea65 getDrawableFromUrl fix 2022-06-24 19:41:08 +03:00
gdlbo 7f9e5aa11e fix summ in feed 2022-06-24 13:31:16 +03:00
gdlbo 5554b5197a added filter for copyright links 2022-06-24 13:27:59 +03:00
aliveoutside a0e504a834 Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-06-24 13:03:11 +03:00
gdlbo f5d4892ba6 added filter for copyright links 2022-06-24 11:54:35 +03:00
gdlbo 32e807e130 fixed ads in discover 2022-06-24 11:43:38 +03:00
gdlbo d7ff759cde added app version to about 2022-06-24 10:49:25 +03:00
gdlbo fc4f8056c5 renamed some strings 2022-06-24 10:39:31 +03:00
gdlbo 7b073523fa added proxied static and oauth + refactored by copilot 2022-06-24 10:37:49 +03:00
gdlbo 7205be3749 vk api proxy inj 2022-06-24 09:38:57 +03:00
gdlbo e1915e19a3 voice inject 2022-06-24 09:31:29 +03:00
gdlbo 4da341ccf8 pic compress inject 2022-06-24 09:27:27 +03:00
gdlbo 6ef958a606 pic compress inject 2022-06-24 09:27:18 +03:00
aliveoutside a5811047d9 implement messages undeleter (via reflection for now) 2022-06-24 03:56:12 +03:00
gdlbo 75e562e92f changed codestyle 2022-06-23 17:31:32 +03:00
gdlbo 75d537f36a added reload msg feature 2022-06-23 00:56:32 +03:00
gdlbo b68812109c added multiacc + updated jars 2022-06-23 00:19:57 +03:00
gdlbo 44d0f31f93 fixed ru locale 2022-06-22 23:27:42 +03:00
gdlbo b5d5b87779 fixed ssl by default 2022-06-22 23:22:14 +03:00
gdlbo cf180f5146 fixed some settings 2022-06-22 23:21:02 +03:00
gdlbo 430c1686c0 ru locale 2022-06-22 23:20:32 +03:00
gdlbo d1d4bb1f5b fixed auto detect theme + fixes of debug 2022-06-22 23:09:05 +03:00
gdlbo 03561407a3 fixed workflow compiling 2022-06-22 23:00:55 +03:00
gdlbo a9c2c6945b fixed windows compiling 2022-06-22 23:00:26 +03:00
gdlbo 6ae59e0557 fixed proxy tab 2022-06-22 22:59:33 +03:00
gdlbo b1c2c785f3 fixed auth + added old prefs to debug 2022-06-22 22:52:28 +03:00
gdlbo aa0c2a7093 updated jars 2022-06-22 20:44:08 +03:00
gdlbo 987379b7a2 updated themes and disabled auto theme (dead) 2022-06-22 20:43:57 +03:00
gdlbo 7ee38e27d3 fixes themes 2022-06-22 19:34:20 +03:00
gdlbo 60be976861 fixed cringe logs 2022-06-22 19:16:13 +03:00
gdlbo 14e1c736b3 added vkui inj + upgraded vkui coloring and theme changing 2022-06-22 18:55:45 +03:00
gdlbo fc6945a72d fixed opening vk id and bugtracker 2022-06-22 18:33:00 +03:00
aliveoutside b73e8b5c99 fix crashing tgstickers fragment 2022-06-22 18:12:17 +03:00
gdlbo 7fad5f2db8 fixed icons 2022-06-22 18:04:46 +03:00
gdlbo 6119610d7f added new params 2022-06-22 17:58:57 +03:00
gdlbo 401685c1b6 added old icons 2022-06-22 17:56:34 +03:00
aliveoutside bf0f78b391 update icons in settings 2022-06-22 17:29:51 +03:00
gdlbo 0f40e271db fixed FriendsGetRecommendationsWithMutual.smali 2022-06-22 16:49:13 +03:00
gdlbo 990a392b83 newsfeed inj 2022-06-22 16:43:18 +03:00
gdlbo 9e1d0077f6 added offline and news injector 2022-06-22 16:41:41 +03:00
gdlbo 68c3619f7f fixed auto cleaning cache 2022-06-22 14:51:22 +03:00
gdlbo 0419316f32 fixed settings opening 2022-06-22 14:47:26 +03:00
gdlbo fb8252eebe verifications 2022-06-22 14:21:52 +03:00
gdlbo 8a7763c356 navbar coloring (s0v@ killer tbh) 2022-06-22 12:37:44 +03:00
gdlbo 6187eecac5 deleted video/msg reporter 2022-06-22 12:14:22 +03:00
gdlbo 4d3f262d59 fix network 2022-06-22 12:08:56 +03:00
gdlbo 95feb481a9 deleted vk ui analytics and anr 2022-06-22 11:52:38 +03:00
gdlbo 1a42c24dab deleted app start duration checker 2022-06-22 11:41:29 +03:00
gdlbo 833e02bfb2 deleted vk analytics reporter 2022-06-22 11:35:00 +03:00
gdlbo 705d6bf639 deleted my tracker 2022-06-22 11:29:40 +03:00
gdlbo 1186cd4a8d Deleted crashlytics 2022-06-22 11:17:00 +03:00
gdlbo 4b19b59b3a fixed strings compiling 2022-06-22 10:25:27 +03:00
gdlbo 066a1ed161 Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-06-22 10:21:33 +03:00
gdlbo cc9a826f1d inited new version + app name 2022-06-22 10:21:17 +03:00
aliveoutside 8dd7b2d368 add settings 2022-06-22 04:58:42 +03:00
gdlbo d82609304a added Toggles.java with hook 2022-06-22 01:23:00 +03:00
aliveoutside 831ba0a774 fix not loading messages 2022-06-22 04:06:51 +03:00
aliveoutside 15fe52d83f update jars 2022-06-22 03:55:21 +03:00
aliveoutside bce20b9ad6 hide DeletedMessagesHandler for now 2022-06-22 03:54:57 +03:00
aliveoutside 291273aef5 update buildscripts 2022-06-22 03:54:34 +03:00
aliveoutside 8248418fe2 fix ModalBottomSheetWrapper 2022-06-22 03:44:08 +03:00
gdlbo 99629f0a3e added Toggles.java with hook 2022-06-22 00:42:42 +03:00
gdlbo 9405ee352d fix Toggles.java 2022-06-22 00:17:14 +03:00
gdlbo 4dd055b9b1 added Toggles.java 2022-06-22 00:13:13 +03:00
aliveoutside 7769a76bea fix galo4ki 2022-06-22 02:07:39 +03:00
aliveoutside 27b8b57625 fix OTAHelper 2022-06-22 02:07:39 +03:00
gdlbo 682ed1c8c5 fixed imports and Themes.java 2022-06-21 23:05:33 +03:00
Vologhat f6c30a4953 Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-06-21 22:55:08 +03:00
aliveoutside 4c352713ca fix DeletedMessagesHandler 2022-06-22 01:52:15 +03:00
Vologhat 20efb909ae extended ReflectionUtils 2022-06-21 22:54:44 +03:00
gdlbo fc6f528541 Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-06-21 22:38:15 +03:00
aliveoutside 1d97000bef fix DockBarFragment 2022-06-22 01:31:01 +03:00
aliveoutside ade116fa03 fix otadownloader 2022-06-22 01:24:48 +03:00
aliveoutside ec40c99c95 fix net/request 2022-06-22 01:18:00 +03:00
aliveoutside ab66804d87 fix ExternalLinkHandler 2022-06-22 01:13:58 +03:00
gdlbo 126d8c7926 debuggable true 2022-06-21 22:36:49 +03:00
gdlbo b936327eec fixed setup with official vk 2022-06-21 22:36:18 +03:00
gdlbo 7499aadec6 Merge branch 'vtl-remaster' of https://github.com/vtosters/lite into vtl-remaster 2022-06-21 20:40:46 +03:00
aliveoutside ed5f82cbd2 fix dnr and dnt 2022-06-21 23:39:00 +03:00
aliveoutside 596b71ce56 remove okhttp request 2022-06-21 23:39:00 +03:00
aliveoutside af6aaf341e fix foaf 2022-06-21 23:39:00 +03:00
gdlbo 4f51cdec0a fixes refl theme 2022-06-21 20:40:29 +03:00
gdlbo e4f68f4024 fixes refl theme 2022-06-21 20:38:10 +03:00
aliveoutside b2f78987f7 fix materialfragment is settings 2022-06-21 23:14:56 +03:00
aliveoutside a567d044c6 add activity to manifest 2022-06-21 23:14:56 +03:00
aliveoutside 5e6fff7b8d fix materialfragment 2022-06-21 23:14:56 +03:00
gdlbo f4766d0a11 Update R.java 2022-06-21 20:14:42 +03:00
aliveoutside 5b95b17703 update jars 2022-06-21 23:00:13 +03:00
aliveoutside 534e33ee46 Revert "fixes private/public"
This reverts commit 94a6b5aa96.
2022-06-21 22:51:21 +03:00
aliveoutside 3d0b8cf0a2 dev mode 2022-06-21 22:37:24 +03:00
aliveoutside 764f026ab9 ssl 2022-06-21 22:28:30 +03:00
gdlbo 056fdc3b2c Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-06-21 19:16:12 +03:00
aliveoutside d4641d88c0 enable music 2022-06-21 22:13:58 +03:00
aliveoutside 6a82aee5cc disable calls 2022-06-21 22:13:57 +03:00
gdlbo ffa64a0125 fixes analytics 2022-06-21 19:16:07 +03:00
gdlbo 856eafe8de fixes private/public 2022-06-21 19:11:41 +03:00
gdlbo 94a6b5aa96 fixes private/public 2022-06-21 19:08:51 +03:00
aliveoutside 42b02add89 Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-06-21 22:01:12 +03:00
aliveoutside 034bf2dd2c спустя два дня пофиксили 2022-06-21 21:58:55 +03:00
aliveoutside 0eccfbf5ea Revert "deobf"
This reverts commit 755268de
2022-06-20 00:31:48 +03:00
aliveoutside 23c3bd8852 partially ifx 2022-06-20 00:19:11 +03:00
gdlbo 037444d813 fixes 2022-06-19 23:37:59 +03:00
gdlbo 44de228f9f fixes 2022-06-19 20:44:33 +03:00
gdlbo 7b25221fee fixes 2022-06-19 20:13:27 +03:00
gdlbo 363afa251a added new fonts 2022-06-19 20:13:18 +03:00
gdlbo 052e3114bf fix 2022-06-19 19:28:04 +03:00
gdlbo d73c5133d3 fix 2022-06-19 19:17:30 +03:00
gdlbo 8d0b63ad72 fixes 2022-06-19 15:32:24 +03:00
aliveoutside 5766d03767 update r.java 2022-06-19 18:21:48 +03:00
gdlbo 7ee2f8ab46 fixes 2022-06-19 14:52:27 +03:00
gdlbo 1840c76a26 fixes 2022-06-19 14:38:22 +03:00
aliveoutside 51e8219306 Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-06-19 17:17:50 +03:00
aliveoutside 82d16c6a0c Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-06-19 17:01:32 +03:00
aliveoutside da087054cc fix preferences 2022-06-19 16:57:53 +03:00
aliveoutside 5781df15d3 fix preferences 2022-06-19 16:54:07 +03:00
gdlbo 4c1cb174b8 fixes 2022-06-19 14:17:37 +03:00
gdlbo fa1ef6dfa5 Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-06-19 14:01:28 +03:00
gdlbo 1389a39bea fixes 2022-06-19 14:01:24 +03:00
gdlbo 0491afacec fixed all res 2022-06-19 13:11:07 +03:00
gdlbo de62447522 added resources + fixed animfrag 2022-06-19 12:47:35 +03:00
aliveoutside 3ba9b8c4e4 add assests 2022-06-19 07:05:35 +03:00
aliveoutside c1760a48ca update jars 2022-06-19 07:03:08 +03:00
aliveoutside 32b854baf8 remove multiacc (it's already in the client) 2022-06-19 07:02:55 +03:00
aliveoutside 5b91699c69 fix StickersPreferencesFragment 2022-06-19 06:59:52 +03:00
aliveoutside 1f42bb9ec6 fix DeletedMessagesHandler 2022-06-19 06:52:32 +03:00
aliveoutside 8330f7fe89 add update jars script 2022-06-19 06:49:32 +03:00
aliveoutside 74bbb9eed9 fix verifications 2022-06-19 05:57:58 +03:00
aliveoutside 78960e7827 fix vkx 2022-06-19 05:53:17 +03:00
aliveoutside 3dfe10fc87 fix settings 2022-06-19 05:49:10 +03:00
aliveoutside 807c3b95c4 Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-06-19 05:44:34 +03:00
aliveoutside 4f408e4cfa Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-06-19 05:30:56 +03:00
aliveoutside 0d0caa9d83 fix messages settings 2022-06-19 05:03:00 +03:00
aliveoutside d33e382b49 fix 2022-06-19 04:54:56 +03:00
aliveoutside 20b7e77be2 Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-06-19 04:48:03 +03:00
aliveoutside 3652e8c593 fix video downloader 2022-06-19 04:42:43 +03:00
aliveoutside 755268de6b deobf 2022-06-19 04:32:02 +03:00
gdlbo 4473e68f7e fixes 2022-06-19 02:44:29 +03:00
gdlbo 65aac426b2 fixes 2022-06-19 02:13:23 +03:00
gdlbo a186fd35be Merge remote-tracking branch 'origin/vtl-remaster' into vtl-remaster 2022-06-19 02:06:52 +03:00
gdlbo c651074d91 fixes 2022-06-19 02:06:47 +03:00
gdlbo 34335d723a fixes 2022-06-19 01:47:55 +03:00
gdlbo 6cd0cd4730 fixes 2022-06-19 00:27:34 +03:00
gdlbo 3125ba2f8a dev mode 2022-06-18 23:52:54 +03:00
gdlbo 638ddd0518 music + ssl v2 2022-06-18 23:29:48 +03:00
gdlbo 429f8214b0 ssl + debug check 2022-06-18 23:29:05 +03:00
aliveoutside bdd5c80504 rename 2022-06-18 23:01:03 +03:00
aliveoutside c11d763760 disable calls 2022-06-18 20:04:41 +03:00
aliveoutside d2df533c1d fix music 2022-06-18 20:01:17 +03:00
aliveoutside db3944b8d6 fix buildscripts 2022-06-18 20:01:07 +03:00
aliveoutside 0d0e5fdd37 add new files 2022-06-18 19:27:15 +03:00
aliveoutside 2273d2f346 init new ver 2022-06-18 19:12:50 +03:00
gdlbo 7df03fd5e6 fixed deleting acc 2022-06-17 22:52:50 +03:00
gdlbo 7dd30d5169 shakal mode 2022-06-17 19:49:41 +03:00
gdlbo c7820e2571 fixed multi account 2022-06-17 19:27:35 +03:00
gdlbo cf058d65fd updated gh actions script 2022-06-17 19:13:27 +03:00
gdlbo 3eabe1f659 added compress disabler 2022-06-17 19:10:57 +03:00
gdlbo f442f089bf added compress disabler 2022-06-17 19:08:37 +03:00
gdlbo 82abf48b18 Merge remote-tracking branch 'origin/master' 2022-06-17 18:35:06 +03:00
gdlbo 7729614f8b added auto cleaning cache 2022-06-17 18:35:01 +03:00
gdlbo 9b86678daf Merge pull request #342 from k1zn/master
Fix avatar position on tablet
2022-06-17 18:27:20 +03:00
gdlbo 9d356e7d9d added auto cleaning cache 2022-06-17 18:21:10 +03:00
Erik Kiznov 6ac6819d5d Fix README.md 2022-06-17 20:09:03 +05:00
Erik Kiznov e859baf6e5 Fix avatar position on tablet 2022-06-17 19:36:42 +05:00
Vologhat ac137e1fb6 changed buttons style 2022-06-17 17:12:26 +03:00
gdlbo 997d861f83 fix foxbin.f0x1d.com/enotik 2022-06-17 15:12:59 +03:00
gdlbo 91cde36777 fix 2022-06-17 14:54:47 +03:00
gdlbo ebf7a4070c fix 99% problems on android 11 and lower 2022-06-17 14:19:27 +03:00
gdlbo c63a31ddd8 fixed colors 2022-06-17 13:58:41 +03:00
gdlbo 8a0000b678 fix vk icon in menu 2022-06-17 13:53:17 +03:00
gdlbo 2fc79dbdb8 fixed crash android 5.1 2022-06-17 13:34:40 +03:00
gdlbo 037ea45448 fix crash MusicFragment 2022-06-16 23:30:08 +03:00
gdlbo e389f7d353 gcmfix v2 is here 2022-06-16 22:46:07 +03:00
gdlbo 6cdba67118 gcmfix v2 is here 2022-06-16 22:32:00 +03:00
gdlbo 3bb32dfd44 gcmfix v2 is here 2022-06-16 22:30:00 +03:00
gdlbo d7d3ef7549 counters is back 2022-06-16 21:58:13 +03:00
gdlbo 95a029ab6f fix rounded msg + improved vkme msg mode 2022-06-16 21:25:41 +03:00
gdlbo f284a96587 fixed bg stickers issue 2022-06-16 21:14:13 +03:00
gdlbo ca91b16647 VKID Protection alert in music settings 2022-06-16 20:25:02 +03:00
gdlbo 35e5a97266 VKID Protection alert 2022-06-16 19:38:18 +03:00
gdlbo 6678a361ba VKID Protection alert 2022-06-16 19:35:45 +03:00
gdlbo 1e8bd2afc7 fix sharing action buttons 2022-06-16 17:05:42 +03:00
gdlbo ad5f658423 small fixes 2022-06-16 16:51:27 +03:00
gdlbo 24e81159f3 small fixes 2022-06-16 16:37:35 +03:00
gdlbo b6e60e3461 verif icon coloring in dialogs 2022-06-16 16:24:23 +03:00
gdlbo 203b4b166b toolbar fixes 2022-06-16 16:02:19 +03:00
gdlbo d586eea977 writebar fix 2022-06-16 14:16:46 +03:00
gdlbo d33e25f95d fix msg loading 2022-06-16 14:03:39 +03:00
gdlbo b9508d9be4 online fixes 2022-06-16 13:18:09 +03:00
gdlbo 5b39f797b1 fix 2022-06-16 09:12:39 +03:00
gdlbo 6ceb91e8b6 added signature check to detect github actions builds and etc 2022-06-16 01:26:07 +03:00
gdlbo 94259ce68c fixes 2022-06-16 01:06:11 +03:00
gdlbo 0f035ebc13 fixes 2022-06-16 00:33:40 +03:00
gdlbo dc605a7292 fixed toast 2022-06-16 00:15:31 +03:00
Vologhat 15ef4b5419 Merge branch 'ota' 2022-06-16 00:09:40 +03:00
Vologhat fc6cf416dc Final fixes 2022-06-16 00:04:34 +03:00
gdlbo 0a28430c5a impossible color fix 2022-06-15 23:08:58 +03:00
gdlbo 3207290d77 kill androidx 2022-06-15 21:47:21 +03:00
Vologhat b0fa321606 final changes
added apk downloading and installing features, bottomshit wrapper with mirroring
2022-06-15 21:29:09 +03:00
gdlbo 2bffa59a10 color fixes 2022-06-15 21:11:30 +03:00
gdlbo 7f080970e4 wtf debuggable must be false 2022-06-15 17:20:01 +03:00
gdlbo f1c2527ca3 fixes 2022-06-15 17:13:18 +03:00
Vologhat 33d210af7f added ota 2022-06-15 16:41:21 +03:00
gdlbo d7378e4674 fixed auto theme 2022-06-15 07:59:10 +03:00
gdlbo 8e40b622f7 fixes 2022-06-15 02:36:25 +03:00
gdlbo 92e4c55cb5 upgraded new settings
refactored multi account counter
2022-06-15 02:13:33 +03:00
gdlbo f498e7af73 fixes 2022-06-14 23:48:07 +03:00
gdlbo bacf196a31 isdarktheme now should work depending on the dark theme of the app v2 2022-06-14 13:26:47 +03:00
gdlbo 2f4603af26 Merge pull request #313 from iNotFlying/master
New VK logo
2022-06-14 13:10:11 +03:00
gdlbo 203a7d00f2 isdarktheme now should work depending on the dark theme of the app 2022-06-14 13:08:20 +03:00
iNotFlying f8c351cd0b Some fixes 2022-06-14 10:48:25 +03:00
iNotFlying 93ab8d368b Merge branch 'vtosters:master' into master 2022-06-14 11:41:47 +04:00
gdlbo e38d93fa2b injected new setting to default theme 2022-06-14 01:19:20 +03:00
gdlbo 59518fa4ce fixed dark theme in new settings 2022-06-14 01:07:17 +03:00
gdlbo c7b7ccfb8b fixed amoled css 2022-06-14 00:15:25 +03:00
gdlbo e0f9ac1ea3 amoled theme now is fully amoled theme 2022-06-14 00:11:33 +03:00
gdlbo 2fa9f76d16 fixes 2022-06-13 23:57:53 +03:00
gdlbo 7eceb08e8c fixes 2022-06-13 22:49:22 +03:00
gdlbo 41f558c34c fixes 2022-06-13 22:40:10 +03:00
gdlbo dd5963b172 vkme mode updated 2022-06-13 22:34:35 +03:00
iNotFlying c1e3a03412 New VK logo 2022-06-13 21:45:29 +03:00
gdlbo ffd60ded27 vkme mode updated 2022-06-13 21:07:16 +03:00
gdlbo b5e02b04b7 vkme mode updated 2022-06-13 21:06:36 +03:00
gdlbo 4077621891 vkme mode updated 2022-06-13 21:04:16 +03:00
gdlbo 2d2a835bbe vkme mode updated 2022-06-13 18:18:38 +03:00
gdlbo 526c2a3b8a vkme mode updated 2022-06-13 12:38:50 +03:00
gdlbo 0bee2560d5 vkme mode updated 2022-06-13 12:20:21 +03:00
gdlbo c4796fb9c7 vkme mode updated 2022-06-13 12:01:04 +03:00
gdlbo 504aa22064 vkme mode test 2022-06-13 01:03:10 +03:00
gdlbo 7882532361 test coloring bottomsheet 2022-06-12 20:02:15 +03:00
gdlbo f4786f0479 mini refactoring 2022-06-12 16:19:45 +03:00
gdlbo 2dc814eacb fix https://github.com/vtosters/lite/issues/156 2022-06-12 15:44:05 +03:00
gdlbo 289d82e5bc fix 2022-06-12 01:49:10 +03:00
gdlbo 1157d96589 fix hardcoded text 2022-06-12 01:29:19 +03:00
gdlbo e1044a288d fix 2022-06-12 01:12:01 +03:00
gdlbo 2cba8fd9ef dropdown menu text color fix 2022-06-12 00:36:18 +03:00
gdlbo 1d9285d371 dropdown menu coloring!!!!!!! 2022-06-11 23:51:48 +03:00
gdlbo f8d342ba93 fixes 2022-06-11 23:08:16 +03:00
gdlbo eae02f4f4a fixes 2022-06-11 22:57:52 +03:00
gdlbo f8c397e57f fixes 2022-06-11 22:45:55 +03:00
gdlbo 87c53c8a42 fixes 2022-06-11 20:16:10 +03:00
gdlbo 8615d33da9 Animation fragment injector (beta) 2022-06-11 19:46:22 +03:00
gdlbo 59702a47f0 fixed games button 2022-06-11 17:29:05 +03:00
gdlbo cd69714985 upgraded ColorStateList recoloring 2022-06-11 16:42:39 +03:00
gdlbo f4e51b79fd some fixes of color inj 2022-06-11 15:24:04 +03:00
gdlbo b6fde08278 Merge remote-tracking branch 'origin/master' 2022-06-11 14:26:43 +03:00
gdlbo 4773f7faef fixed search color 2022-06-11 14:26:39 +03:00
gdlbo 33e4637b60 Fix string 2022-06-10 22:22:46 +03:00
gdlbo e676c5c4f1 fixed crash docs 2022-06-10 21:49:12 +03:00
gdlbo 58741f88f6 fixed crash docs 2022-06-10 21:37:52 +03:00
gdlbo 12077ba07a some improves 2022-06-10 21:00:37 +03:00
gdlbo 748cb47b4b fixed issue with undelete by default (oops) 2022-06-10 19:42:20 +03:00
gdlbo c0470012eb fixed issue with dateformat value 2022-06-10 19:00:26 +03:00
gdlbo cf3eacc14f Added an expanded view of the date format type selection
Full date in private messages
Minor improvements
Fixed a bug with anti-deletion of messages
2022-06-10 18:58:19 +03:00
gdlbo 083dc40ad9 improved disabling number shortening 2022-06-10 17:26:40 +03:00
gdlbo 72001373b9 fixed pic rounding 2022-06-10 16:40:50 +03:00
gdlbo 1eb33b6cc5 fixed serach text coloring 2022-06-10 16:19:00 +03:00
gdlbo 908047fbe2 fixed casino moment 2022-06-10 16:17:32 +03:00
gdlbo 2ac791344a fixed casino moment 2022-06-10 15:29:46 +03:00
gdlbo 0b28a4d20b fixed rounded msgs colors monet 2022-06-10 15:26:40 +03:00
gdlbo 62fbdab39a added pref disableanimstickers to debug 2022-06-09 00:04:14 +03:00
gdlbo 282c82282e fixed some accents 2022-06-08 23:44:58 +03:00
gdlbo 4b7eeed21c fixed accent vkim link 2022-06-08 23:26:30 +03:00
gdlbo d6d50bdc41 fixed load friends page 2022-06-08 22:58:52 +03:00
gdlbo 3be46106a1 added shadow in dialogs vkme 2022-06-08 21:18:05 +03:00
gdlbo ea2cda888d disabled divider in dialogs 2022-06-08 21:09:12 +03:00
gdlbo 1d59d4c5ed fixed shadow 2022-06-08 20:55:19 +03:00
gdlbo be47db75aa fixed shadow on 31 sdk+ 2022-06-08 20:47:52 +03:00
gdlbo 41b81641ce sdk 31 rounded msgs 2022-06-08 20:29:30 +03:00
gdlbo 1faebbb490 amoled theme for rounded msgs 2022-06-08 19:55:11 +03:00
gdlbo 7036c3e613 some fixes 2022-06-08 19:32:29 +03:00
gdlbo aa1fece7b5 init rounded msg for light theme 2022-06-08 19:26:01 +03:00
gdlbo 896b420c28 added applying theme after restart 2022-06-08 19:25:01 +03:00
gdlbo ac4fe43aef init rounded msg for dark theme 2022-06-08 18:50:28 +03:00
gdlbo 98e5bfb2bb init rounded theme 2022-06-08 18:41:03 +03:00
gdlbo ae722e689e fixed stickers time color 2022-06-08 18:28:56 +03:00
gdlbo 3abff8cad1 fixes some themes logic 2022-06-08 17:22:11 +03:00
gdlbo 155fa80c95 fixes + more translations 2022-06-08 15:14:34 +03:00
gdlbo a5a2179399 fixes + more translations 2022-06-08 14:02:45 +03:00
gdlbo 8aee5a78a4 fixes 2022-06-07 17:50:02 +03:00
gdlbo 06ce8a7e6f New feature open news settings via settings lmao 2022-06-07 11:56:23 +03:00
gdlbo 1cc4d7624a fixed news logic 2022-06-07 11:26:29 +03:00
gdlbo dd817960e1 Fixed some translations + fixed settings logic 2022-06-07 11:24:44 +03:00
gdlbo 92e0f3b55b Fixed links 2022-06-07 10:51:24 +03:00
gdlbo 03bdf92ae2 Casino update from 7 to 5 2022-06-04 22:14:36 +03:00
gdlbo 5492d69445 Added randomize to disable donate alert 2022-06-04 21:18:50 +03:00
gdlbo 83779a1698 fixed links + disable recomms 2022-06-04 20:36:00 +03:00
gdlbo 49c70e8162 Added donate banners lmao 2022-06-04 20:04:28 +03:00
gdlbo 654ba13dea Fixed market colors 2022-06-04 11:25:38 +03:00
gdlbo e4c0b7be6c Fix dark accent color on monet 2022-06-04 10:25:41 +03:00
gdlbo 0ee809a721 Merge pull request #283 from bxkr/master 2022-06-04 09:32:58 +03:00
Andrew 683e17bee4 Update R.java 2022-06-04 06:10:16 +03:00
gdlbo b9d35c2343 Fix pull requests building 2022-06-04 04:54:54 +03:00
Andrew 6b6c69fb19 Preferences localization
- Added en,ru translations for hardcoded strings in preferences
- Updated public.xml
- Fixed some ru strings
2022-06-03 23:38:52 +03:00
gdlbo 960980022f Fix actions compiling 2022-06-03 20:36:56 +03:00
gdlbo f72da4bec1 Fix actions compiling 2022-06-03 20:33:29 +03:00
gdlbo 08e35a811f fix some strings 2022-06-03 19:43:23 +03:00
gdlbo a34c41870c color fixes 2022-06-03 17:47:29 +03:00
gdlbo 25428464b7 Update build.gradle 2022-06-03 16:00:11 +03:00
gdlbo 97c65f9585 Color article fixes 2022-06-02 19:45:49 +03:00
gdlbo 302fa7e6af Color fixes 2022-06-02 19:28:16 +03:00
gdlbo ab067f242b Disabled discover ads 2022-06-02 19:04:24 +03:00
gdlbo 30e5ff6f64 Fix https://github.com/vtosters/lite/issues/266 2022-06-02 17:38:28 +03:00
gdlbo 2838dc5e7e Fixes 2022-06-02 16:42:45 +03:00
gdlbo 6f4f073ed3 Fixed comments load 2022-06-02 14:25:32 +03:00
gdlbo 564eb85575 Updated gitignore 2022-06-02 14:02:37 +03:00
gdlbo a6de8e0be4 Fixed icon changing 2022-06-02 13:25:19 +03:00
gdlbo abc87c0254 Fixed crash + fixed msg cache 2022-06-02 13:06:55 +03:00
gdlbo aec302d7f2 Refactoring of some code that suggested what to fix in the comments in our vk group 2022-06-02 12:33:52 +03:00
gdlbo d27d9227bc Refactoring of some code that suggested what to fix in the comments in our vk group 2022-06-02 11:20:11 +03:00
gdlbo a1c23aeaaa Refactoring 2022-05-31 16:55:19 +03:00
gdlbo 6b05544716 added more documentations 2022-05-31 16:43:58 +03:00
gdlbo 161ea1d318 Added our git links 2022-05-26 20:25:51 +03:00
gdlbo f500f34e78 Fixed statusbar and navbar light coloring 2022-05-17 23:08:12 +03:00
gdlbo e3716b759a Poll fix 2022-05-17 20:05:16 +03:00
gdlbo abc37de666 Fixes 2022-05-17 18:40:56 +03:00
gdlbo e09994cd30 reworked statusbar coloring 2022-05-17 00:35:39 +03:00
gdlbo e1dfd9bd99 fix music tabs 2022-05-16 22:38:57 +03:00
gdlbo b4ac86ef35 reworked do not read 2022-05-16 21:50:32 +03:00
gdlbo 3e40286e5d fixes 2022-05-16 21:27:59 +03:00
gdlbo 4a2d307410 copyright posts detect 2022-05-16 21:21:39 +03:00
gdlbo 878d68a655 Fixes + some imp of custom msg loader 2022-05-16 00:11:00 +03:00
gdlbo a56c92f87f Fixes 2022-05-15 21:23:48 +03:00
gdlbo 9095629f96 Reworked some cringe code 2022-05-15 21:11:25 +03:00
gdlbo 8755c2df34 fixed white screamers (maybe) 2022-05-13 20:28:20 +03:00
gdlbo 888a1af9b4 fixes 2022-05-13 19:59:36 +03:00
gdlbo e0450d3835 Fix summ 2022-05-13 15:36:42 +03:00
gdlbo 4e56fdf5aa Color fixes 2022-05-13 15:12:02 +03:00
gdlbo c332d5c97f Some corrections 2022-05-13 14:13:36 +03:00
gdlbo 2977a19532 color fix header 2022-05-13 14:10:18 +03:00
gdlbo a9365a8ba8 Fixes 2022-05-13 14:05:00 +03:00
gdlbo a6ddcdb759 Fix open notifs 2022-05-13 12:40:42 +03:00
gdlbo d9dccd53f0 Fixes 2022-05-13 11:59:15 +03:00
gdlbo 3b2f964961 Fix article custom verifs 2022-05-12 18:47:42 +03:00
gdlbo 2d8bd820a5 Monet dockbar icons coloring 2022-05-12 18:04:12 +03:00
gdlbo 56a979970c Added more summaries 2022-05-12 16:50:30 +03:00
gdlbo 836676eb18 System theme at start 2022-05-11 20:59:37 +03:00
gdlbo 86a013b619 Some color fixes + upped default app version 2022-05-10 22:34:56 +03:00
gdlbo e57a76790f Added another cringe feature 2022-05-10 22:12:40 +03:00
gdlbo b4cec48bbb Fixed doc upload 2022-05-10 21:27:25 +03:00
gdlbo 96676721c9 Fixed stats crash 2022-05-10 21:07:29 +03:00
gdlbo eeb8785d42 Custom opus lib bridges 2022-05-10 20:22:39 +03:00
gdlbo 993a1a7f86 Custom opus lib bridges 2022-05-10 20:18:59 +03:00
gdlbo 0b6f29dc70 Crashreporter fix 2022-05-10 14:35:33 +03:00
gdlbo 26007f97f3 Amoled monet accent + color fixes 2022-05-10 14:11:14 +03:00
gdlbo 5a55cca59d Disabled stats.track*** 2022-05-10 13:53:14 +03:00
gdlbo cb425fd18e Fixed vk cringe refl 2022-05-10 13:26:00 +03:00
gdlbo 5889dc675e Beautify code 2022-05-07 18:31:07 +03:00
gdlbo df8e7e4b54 Deleted unused code 2022-05-07 11:16:22 +03:00
gdlbo e07d253a5e Decrypt 2022-05-06 14:50:02 +03:00
gdlbo 81f4e6503a Fixes 2022-05-06 14:05:23 +03:00
gdlbo d7ff250faf Undelete feature + fixes 2022-05-06 13:43:42 +03:00
gdlbo 1d12a5f171 Merge branch 'master' of https://github.com/vtosters/lite 2022-05-06 01:58:35 +03:00
gdlbo 485d3d884a Encryption + Undelete code base 2022-05-06 01:57:33 +03:00
gdlbo e78754e39e color fixes 2022-05-04 16:41:59 +03:00
gdlbo 0b6c11f0d0 Fixed crash 2022-05-04 14:23:25 +03:00
gdlbo d25604ed66 Added proxy user/pass auth 2022-05-04 13:12:39 +03:00
gdlbo 4f3167064c Update README.md 2022-05-03 23:45:37 +03:00
gdlbo f0d4bec116 Updated build gradle 2022-05-03 22:19:23 +03:00
gdlbo 76a1872f74 Merge remote-tracking branch 'origin/master' 2022-05-03 22:11:35 +03:00
gdlbo 1158cb4aeb Fix 2022-05-03 22:11:19 +03:00
Vologhat 41ab384e1f fix #204 (null pointer while account deleting) 2022-05-02 18:07:04 +03:00
gdlbo 3839e721db Fix dockbar issue 2022-05-02 13:30:51 +03:00
gdlbo d1b84461e6 Fixed store stickers colors 2022-05-02 12:54:58 +03:00
gdlbo 3c79cb3ef5 Reworked some about menu 2022-05-02 12:40:57 +03:00
gdlbo ea7641278a Disabled anim stickers 2022-05-02 12:31:30 +03:00
gdlbo 23032e8409 Fixed bug with new feed design 2022-05-02 11:03:39 +03:00
gdlbo 1d687a01c1 Fixes + new update feed logic 2022-05-02 10:44:57 +03:00
gdlbo 0b751964fa Oh sh*t I am sorry (for refactoring) 2022-05-02 09:44:30 +03:00
gdlbo 59eb43c33f Color fixes 2022-04-30 14:25:40 +03:00
gdlbo dfdb056e07 Refactoring + renaming 2022-04-30 13:48:04 +03:00
gdlbo cd38eba184 Refactoring + renaming 2022-04-30 13:17:32 +03:00
gdlbo a4063b978f Updated README.md + version null fix 2022-04-29 22:22:07 +03:00
gdlbo af51775844 Github Actions test 2022-04-29 21:51:56 +03:00
gdlbo f4039abae3 Github Actions test 2022-04-29 21:48:08 +03:00
gdlbo 1b64f46588 gh actions test 3 2022-04-29 21:42:51 +03:00
gdlbo ad40368639 gh actions test 2 2022-04-29 21:38:24 +03:00
gdlbo d15159d9b0 fix 2022-04-29 21:29:20 +03:00
gdlbo c837f6eacc gh actions test 2022-04-29 21:27:25 +03:00
gdlbo 14b884daf7 Updated README.md 2022-04-29 20:56:14 +03:00
gdlbo 63ca14bbe6 color fixes 2022-04-29 16:49:30 +03:00
gdlbo 2605566f90 color fixes 2022-04-28 22:02:35 +03:00
gdlbo 0bcd59d5ba color fixes 2022-04-28 21:56:54 +03:00
gdlbo a9744bb577 Some fixes 2022-04-28 21:21:20 +03:00
gdlbo 9b4dae4af5 Clean up code 2022-04-28 21:11:04 +03:00
gdlbo 319d657ab4 Fixes 2022-04-28 20:57:57 +03:00
gdlbo d9896257c5 Backup system fixes 2022-04-28 19:07:11 +03:00
gdlbo b5d5e85ee2 Reset/Save prefs system init 2022-04-28 18:29:31 +03:00
gdlbo 9dcaddd7fd Reset/Save prefs system init 2022-04-28 18:29:21 +03:00
gdlbo d1bec2e815 fixes 2022-04-27 23:06:43 +03:00
gdlbo 96d7f28db9 fixes for music popup 2022-04-27 21:34:14 +03:00
gdlbo 90c4ca88e0 https://github.com/vtosters/lite/issues/181 + color fixes for tabs 2022-04-27 21:09:29 +03:00
gdlbo 942fe202d7 Fixed crash
https://github.com/vtosters/lite/issues/192
2022-04-27 20:29:18 +03:00
gdlbo e17f888598 Deleted exit button :) 2022-04-27 20:25:29 +03:00
gdlbo b089c7d7f9 Added debug feature for clear all sticks cache 2022-04-27 20:15:47 +03:00
gdlbo afc2a5b258 Fixed pic theme 2022-04-27 20:08:23 +03:00
gdlbo 1f0adb7510 Fixed header coloring 2022-04-27 19:37:48 +03:00
gdlbo aba62966b0 Max tabs updated 2022-04-26 14:28:37 +03:00
gdlbo aaff05685c Updated icons 2022-04-25 19:37:14 +03:00
gdlbo 9c1bbab253 Fixed msg strange bug + fixes 2022-04-25 17:24:13 +03:00
gdlbo def1c699e0 Improved Dark theme 2022-04-25 16:47:43 +03:00
gdlbo e6639a63b7 Improved player progress color 2022-04-25 16:31:02 +03:00
gdlbo 1b14761e9e Refactored vkui injector + added headers coloring 2022-04-25 15:51:07 +03:00
gdlbo 07a070a4fe Monet fixes 2022-04-25 14:23:18 +03:00
gdlbo 8b13fcfd68 Update preferences_themes.xml 2022-04-24 22:44:06 +03:00
gdlbo 4088ea68fa Update DockBarManager.java 2022-04-24 22:32:39 +03:00
gdlbo 2e95ed13ce Improved dark theme 2022-04-24 19:22:35 +03:00
gdlbo f79091bc9c added more info + reformated xml 2022-04-24 18:42:17 +03:00
gdlbo ebfc19c1f7 Update ThemesFragment.java 2022-04-24 18:28:12 +03:00
gdlbo bdb8f3cf6f Improved Theme changing 2022-04-24 18:16:24 +03:00
gdlbo 4b998f2b97 fixed comments 2022-04-24 17:57:26 +03:00
gdlbo aa1d254a49 Fixes + Added comments sorting 2022-04-24 17:43:02 +03:00
gdlbo 897b3300e6 fixes 2022-04-24 16:58:17 +03:00
gdlbo 9c6c9489ff Oh, fixes?
-Added styles list for dark and light themes
-Updated libs
-Auto refactored resources for easy editing
-Improved amoled theme
2022-04-23 21:36:08 +03:00
gdlbo 6d147b081e Improved Amoled Theme 2022-04-23 00:03:37 +03:00
gdlbo 78432057ca Revert "Improved navbar coloring"
This reverts commit 21b0ed8925.
2022-04-22 23:01:45 +03:00
gdlbo 21b0ed8925 Improved navbar coloring 2022-04-22 19:29:18 +03:00
gdlbo 1040e50b32 Update preferences_themes.xml 2022-04-22 18:59:48 +03:00
gdlbo 3806a05f4a Amoled Theme feature 2022-04-22 18:51:42 +03:00
gdlbo 82d45915c6 Improved Amoled Theme + Added support for SSFS 2022-04-22 18:04:56 +03:00
gdlbo 80e5145742 Amoled Theme Styles for VKIM + fixed vk refl 2022-04-22 17:39:37 +03:00
gdlbo f1b7a52f0c Test Amoled Theme Styles + Updated R.java 2022-04-22 17:03:41 +03:00
gdlbo 924952128f Updated Libs 2022-04-22 16:08:23 +03:00
gdlbo 2fcd04a55f Updated gradle + amoled inject 2022-04-22 14:07:56 +03:00
gdlbo deb6e86854 Improved dark theme 2022-04-16 18:41:11 +03:00
gdlbo 086fa37e86 Fixed bot keyboard 2022-04-16 17:58:12 +03:00
gdlbo e87ecf2f4f Custom load of msg 2022-04-16 01:56:12 +03:00
gdlbo 3dc01dd945 Fixed all issues with msgs 2022-04-16 00:23:32 +03:00
gdlbo da21999192 Fixed video downloading 2022-04-16 00:01:21 +03:00
gdlbo 161efaeb52 Downgraded msg api 2022-04-15 23:41:18 +03:00
gdlbo 1759fbe8d5 Zaborona fix 2022-04-15 23:40:06 +03:00
gdlbo b1525266a8 Improved dark theme 2022-04-12 17:34:09 +03:00
gdlbo 28ede39c26 Fixed vk refl 2022-04-12 16:37:52 +03:00
gdlbo 6b25eb37ba Fixed msg loading null 2022-04-12 15:07:35 +03:00
gdlbo e12dcdf86a Fixed strange twitter crash 2022-04-12 13:49:11 +03:00
gdlbo 4bab1490ae Fixed strange statusbar coloring 2022-04-12 13:29:32 +03:00
gdlbo 2374785ae7 Improved white theme 2022-04-12 13:17:45 +03:00
gdlbo b338da4359 Fixed crash 2022-04-11 22:56:11 +03:00
gdlbo d808f453d9 haha bruh dev->beta
1989 китай ничего не было
2022-04-11 22:38:51 +03:00
gdlbo b869f713eb Fixed bugs 2022-04-11 22:22:13 +03:00
gdlbo 2f9cf4751d Improved dark theme 2022-04-11 21:46:32 +03:00
gdlbo 6c7e796e17 deleted confidential logging 2022-04-11 21:12:00 +03:00
gdlbo ff40c7e576 Update MultiAccountAdapter.java 2022-04-11 21:10:16 +03:00
gdlbo 0ccc8b2607 fixes + disabled debuggable mode 2022-04-11 21:07:08 +03:00
Vologhat 8febcfdfb7 update multi account 2022-04-11 20:57:52 +03:00
gdlbo 9d05d077b5 Improved dark theme 2022-04-11 16:27:10 +03:00
gdlbo 63ad926078 Improved coloring 2022-04-11 14:24:50 +03:00
gdlbo e241848426 Msg fixes 2022-04-11 01:23:12 +03:00
gdlbo a82b652bc1 Fixes 2022-04-11 01:01:08 +03:00
gdlbo e59aecdc75 FIxed authactiviry cringe accent color on sdk31+ 2022-04-11 00:54:21 +03:00
gdlbo e56ba6b41a Improved dark theme 2022-04-11 00:29:28 +03:00
gdlbo cfd12483ae Improved dark theme 2022-04-11 00:13:21 +03:00
gdlbo fd18837f1b Deleted new video feature 2022-04-10 23:54:53 +03:00
gdlbo 4f3e37349d Improved dark theme 2022-04-10 23:47:51 +03:00
gdlbo 20653847f4 Improved dark theme 2022-04-10 23:10:12 +03:00
gdlbo 3e294a3ba4 Improved dark theme 2022-04-10 22:52:05 +03:00
gdlbo 20ca6f96f9 multiaccount fixes 2022-04-10 22:00:21 +03:00
Vologhat 70a30a5f33 multi account refactoring 2022-04-10 20:17:47 +03:00
gdlbo b9f170e668 Improved dark theme 2022-04-10 19:53:51 +03:00
gdlbo 809dfbe338 Update Prefs.java 2022-04-10 19:02:23 +03:00
Vologhat af25a82eca fix notifications updater 2022-04-10 16:08:08 +03:00
gdlbo 50b1fcadb4 Update InterfaceFragment.java 2022-04-09 20:40:06 +03:00
gdlbo aefe1b2f07 Improved dark theme 2022-04-09 19:28:53 +03:00
gdlbo 28bc30bd83 Improved dark theme 2022-04-09 18:26:11 +03:00
gdlbo 0aeffcd79d Improved dark theme 2022-04-09 17:57:00 +03:00
gdlbo f3863811bd Improved dark theme 2022-04-09 16:50:33 +03:00
gdlbo e4aab2fd15 Improved dark theme 2022-04-08 21:58:08 +03:00
gdlbo 5f72a6b855 Improved dark theme 2022-04-08 21:29:00 +03:00
gdlbo 31a0444409 Improved dark theme 2022-04-08 20:45:47 +03:00
gdlbo 4522935545 Improved dark theme 2022-04-08 15:03:42 +03:00
gdlbo 67c13bd416 Improved dark theme 2022-04-08 13:46:35 +03:00
gdlbo 28d5af5fa0 Improved dark theme 2022-04-08 13:31:09 +03:00
gdlbo 15d7e71e7f Improved dark theme 2022-04-08 13:14:44 +03:00
gdlbo 49bac975d2 Fixed crash crop 2022-04-08 11:57:33 +03:00
gdlbo 3878c9a1e2 Fixed installing app 2022-04-07 20:43:15 +03:00
gdlbo a5053c4418 Fixed win script 2022-04-07 20:30:26 +03:00
gdlbo 4cb844dea8 Fixed win script 2022-04-07 20:28:38 +03:00
gdlbo 04afad2fd3 Updated keystore 2022-04-07 19:47:02 +03:00
gdlbo 149efe3199 Fixed versioning null 2022-04-07 19:44:20 +03:00
gdlbo 6f05867563 Updated scripts 2022-04-07 19:15:46 +03:00
gdlbo 4442fd3265 Updated README.md 2022-04-07 19:10:11 +03:00
gdlbo 6e49856474 Fixed podcasts colors 2022-04-07 18:55:01 +03:00
gdlbo cc379b71de Added old icons feature 2022-04-07 18:40:04 +03:00
gdlbo c2a1bb4a5a Improved external video link parser 2022-04-07 18:23:57 +03:00
gdlbo cc58c33e37 Disabled monet coloring for dockbar 2022-04-07 17:38:52 +03:00
gdlbo 012f03f7e7 Fixed some color issues 2022-04-07 17:32:52 +03:00
gdlbo 28a7a3c389 Fixed some color issues 2022-04-07 16:44:55 +03:00
gdlbo 6417279d65 Fixed miniplayer text color issues 2022-04-07 15:30:39 +03:00
gdlbo 07db680ad3 Fixed settings stickers color issues 2022-04-07 15:26:02 +03:00
gdlbo d7c97b6589 Fixed docs text color issue 2022-04-07 15:01:51 +03:00
gdlbo af12289d7e Fixed a11+ issue 2022-04-07 14:55:34 +03:00
gdlbo afeafba67d Fixed crash 2022-04-07 13:54:15 +03:00
gdlbo f56e49da5c Fixed crash on sdk31+ 2022-04-07 13:17:17 +03:00
gdlbo d233897c73 Deleted libverify button 2022-04-04 20:45:48 +03:00
gdlbo 273f1c3d07 Fixed crash 2022-04-04 20:34:38 +03:00
gdlbo d34812b77b Update LinkProcessor1.smali 2022-04-03 18:30:23 +03:00
Vologhat 375a60bafc fix recycler view wrong resizing 2022-04-03 17:09:59 +03:00
gdlbo 156bd57461 Update DockBarManager.java 2022-04-03 14:15:12 +03:00
gdlbo dacc1b8eeb Update DockBarManager.java 2022-04-03 14:05:08 +03:00
gdlbo b3bb023852 Update StandartFilter.txt 2022-04-03 13:44:58 +03:00
gdlbo 8ca8272bc4 Fixed crash
https://github.com/vtosters/lite/issues/103
2022-04-03 13:17:55 +03:00
Vologhat fc36f7ad77 add saving and resetting 2022-04-03 12:26:17 +03:00
Vologhat 496bdf5b54 fix dockbar tabs limit 2022-04-03 12:23:42 +03:00
gdlbo 877d625945 Fixes fixes fixes 2022-04-02 23:53:54 +03:00
gdlbo 458710e9f0 Fixes dockbar 2022-04-02 23:41:20 +03:00
gdlbo fa6e7e44a0 Fixes 2022-04-02 22:30:51 +03:00
gdlbo bc12220d7a Merge branch 'master' of https://github.com/vtosters/lite 2022-04-02 22:05:09 +03:00
gdlbo 9d7b879e1f Some improvements 2022-04-02 22:04:16 +03:00
Vologhat e4ff8a169b add outline icons 2022-04-02 22:00:04 +03:00
Vologhat 5a62aea978 add inability to unselect menu tab 2022-04-02 22:00:04 +03:00
Vologhat b4d9de74c3 add possibility to choice alternative fragments for "news" and "discover" 2022-04-02 22:00:04 +03:00
Vologhat aa37d8b4b3 level down min tabs count 2022-04-02 22:00:04 +03:00
Vologhat e334bc6440 fix color palette and tab items 2022-04-02 22:00:04 +03:00
Vologhat 9f6b9923b0 fix dockbar 2022-04-02 22:00:04 +03:00
Vologhat 85415ae7fc add dockbar injector 2022-04-02 22:00:03 +03:00
Vologhat f5382e9649 migration to android support due to androidx instability 2022-04-02 22:00:03 +03:00
Vologhat 3ca786b820 докбар 2022-04-02 22:00:03 +03:00
gdlbo c13908f096 Updated README.md 2022-04-02 22:00:02 +03:00
gdlbo d11de94e0b Updated README.md https://github.com/vtosters/lite/pull/89 2022-04-02 22:00:02 +03:00
Daniil Isakov e2c10f7e87 Grammar check, a bit of rephrasing 2022-04-02 22:00:02 +03:00
gdlbo b05c717981 updated multiacc 2022-04-02 22:00:02 +03:00
gdlbo 38db5dfee4 updated adblock filter 2022-04-02 22:00:02 +03:00
gdlbo 151eeb5ec1 updated resources + R.java again 2022-04-02 22:00:02 +03:00
gdlbo 0d150765b8 translation fixes 2022-04-02 22:00:02 +03:00
gdlbo cd6ee3048c Updated R.java + some fixes 2022-04-02 22:00:02 +03:00
gdlbo 0ed9e62283 Added multi account feature 2022-04-02 22:00:02 +03:00
gdlbo fdb89fbf64 Improved adblock 2022-04-02 22:00:02 +03:00
gdlbo 3fd11831f6 Improvements of multiacc + added migrating from old type of accounts to new type 2022-04-02 22:00:01 +03:00
gdlbo cd81fc8b38 Improvements of multiacc + deleted old accs xD 2022-04-02 22:00:01 +03:00
gdlbo b512b7d5f7 Improvements of multiacc 2022-04-02 22:00:01 +03:00
gdlbo 883cb34bdb Multiaccount impl test 2022-04-02 22:00:01 +03:00
gdlbo c683947d20 fixed picker crash 2022-04-02 22:00:01 +03:00
gdlbo 483204a811 Updated README.md 2022-04-01 19:05:57 +03:00
gdlbo 0b5b7bcae2 Updated README.md https://github.com/vtosters/lite/pull/89 2022-04-01 18:56:52 +03:00
gdlbo e1d517f9c2 Merge pull request #84 from oplexz/patch-1 2022-04-01 09:53:41 +03:00
Daniil Isakov b80b869823 Grammar check, a bit of rephrasing 2022-04-01 09:40:25 +03:00
gdlbo 386a6cbb6c updated multiacc 2022-04-01 08:43:52 +03:00
gdlbo 9ce4c0ee90 updated adblock filter 2022-04-01 08:39:04 +03:00
gdlbo 1351b5ff90 updated resources + R.java again 2022-03-31 21:09:42 +03:00
gdlbo 84960a6107 translation fixes 2022-03-31 20:41:10 +03:00
gdlbo 5d3fdc0abd Updated R.java + some fixes 2022-03-31 20:19:28 +03:00
gdlbo 0d491f0d41 Added multi account feature 2022-03-31 19:22:37 +03:00
gdlbo 955ae91110 Improved adblock 2022-03-30 18:03:52 +03:00
gdlbo 85fa63d2a1 Improvements of multiacc + added migrating from old type of accounts to new type 2022-03-30 17:16:23 +03:00
gdlbo 6d8f02435e Improvements of multiacc + deleted old accs xD 2022-03-30 17:01:50 +03:00
gdlbo fc0600dfd8 Improvements of multiacc 2022-03-30 14:51:50 +03:00
gdlbo 1494579353 Multiaccount impl test 2022-03-30 00:22:49 +03:00
gdlbo 834d7e1da1 fixed picker crash 2022-03-28 10:13:12 +03:00
gdlbo 08b64834cf Update SettingsListFragment$b.smali 2022-03-27 21:12:45 +03:00
Vologhat 8265c5adec fix script for windows 2022-03-27 20:31:31 +03:00
gdlbo be4f2398a9 fixed compilation on windows 2022-03-27 18:04:47 +03:00
gdlbo b8f2d36f5e fixed compilation on windows 2022-03-27 18:01:02 +03:00
aliveoutside 49a2526528 fix icons in dropdown menu in newsfeed 2022-03-27 12:19:11 +03:00
aliveoutside a755d3d55e fix text color in dropdown menu in newsfeed 2022-03-27 12:19:11 +03:00
gdlbo 41a6ddb62a fixed proxy issue 2022-03-27 11:50:14 +03:00
gdlbo e32acd17ba fixed video catalog issue 2022-03-27 11:40:32 +03:00
gdlbo 0de0add858 fixed pic edit crash 2022-03-27 11:35:30 +03:00
gdlbo 9a90ca4c53 Fix doc upload crash 2022-03-26 23:38:53 +03:00
gdlbo 86b1fa6276 Fix graffiti crash 2022-03-26 23:15:47 +03:00
gdlbo 08d5fb50a7 Updated shit Filter 2022-03-26 22:57:17 +03:00
gdlbo 6fca7c7940 Updated ADBlock Filter + new test filter 2022-03-26 22:41:07 +03:00
gdlbo fad14b26b6 Updated ADBlock Filter 2022-03-26 21:37:17 +03:00
gdlbo d33fe6e185 Now some new features are enabled by default 2022-03-26 21:32:24 +03:00
gdlbo a1db85e50f updated README.md 2022-03-26 21:25:43 +03:00
gdlbo e67f1a649c fixed some color issues 2022-03-26 21:16:15 +03:00
gdlbo e88fe21802 fixed some crashes and other problems 2022-03-26 21:07:27 +03:00
gdlbo 21875b8dd5 fixed some issues 2022-03-26 20:38:38 +03:00
aliveoutside 8f4c6a5b32 fix animated stickers 2022-03-26 19:59:29 +03:00
gdlbo ba696abe0c fixed some issues 2022-03-26 17:43:49 +03:00
gdlbo 7f32d8d136 updated prefs 2022-03-26 17:03:58 +03:00
gdlbo e0af365ef3 updated README.md 2022-03-26 16:52:38 +03:00
gdlbo caa85cef49 updated debug 2022-03-26 16:44:55 +03:00
gdlbo 0cb6902519 updated README.md 2022-03-26 16:28:15 +03:00
gdlbo 7226473dcb Improvements + updated R.java and README.md 2022-03-26 16:27:02 +03:00
aliveoutside 222fdf51b5 fix pinned dialogs loading 2022-03-26 16:17:37 +03:00
aliveoutside 381ba0f69a fix "popular" videos 2022-03-26 15:44:24 +03:00
gdlbo e4170b5f16 libverify preference 2022-03-25 19:43:52 +03:00
gdlbo 81294ac9be fix fix 2fa auth........ 2022-03-25 19:15:28 +03:00
gdlbo 5ae0110153 fixed versioning on macos/linux 2022-03-25 18:45:11 +03:00
gdlbo 930c2ef9bb fixed versioning on macos/linux 2022-03-25 18:30:26 +03:00
gdlbo f109fb33d0 updated README.md 2022-03-25 17:51:00 +03:00
gdlbo eae4f99b34 added bug report button 2022-03-25 17:28:14 +03:00
gdlbo 241f0bec43 fixed ssfs domain 2022-03-25 16:52:36 +03:00
gdlbo 01ea68560f fix Jetifier 2022-03-25 16:45:49 +03:00
gdlbo 03ae42c98a fixed 2fa, fixed some issues with proxy, deleted xtrafrancyz proxy, fixed compiling, some other fixes 2022-03-25 16:42:25 +03:00
aliveoutside ab060b0981 update framework and add apksigner.jar 2022-03-25 16:16:13 +03:00
aliveoutside 89ef96f2b4 fix crash when music download button clicked 2022-03-24 22:31:43 +03:00
aliveoutside b7a1af9f64 fix serverside features 2022-03-24 22:30:52 +03:00
aliveoutside 102db1f46d Update README.md 2022-03-24 19:59:23 +03:00
aliveoutside cc35404c7f Update README.md 2022-03-24 19:41:44 +03:00
aliveoutside c07fccf607 init 2022-03-24 19:37:43 +03:00
1143 changed files with 14453 additions and 152462 deletions
+27
View File
@@ -0,0 +1,27 @@
---
name: Bug Report
about: Заготовка для репорта багов
title: Ошибка обновлении ленты новостей
labels: bug
assignees: ''
---
**Опишите сам баг**
При обновлении новостей вылезает ошибка
**Опишите действия для воспроизведения ошибки**
1. Обновил ленту интересных новостей
2. Пролистал до конца страницы
**Опишите ожидаемый результат**
Интересная лента должна прогружать результаты
**Скриншот ошибки**
**Информация об устройстве:**
- Устройство: Samsung Galaxy J1 Mini
- OS: Android 9 | OneUi 3.0
- Коммит: fa12e8f (В О Приложении написана версия коммита)
**Дополнительная информация о баге или мыслях почему оно может происходить (если есть)**
+15
View File
@@ -0,0 +1,15 @@
---
name: Feature request
about: Предложение функции
title: Улучшение голосовых сообщений
labels: enhancement
assignees: ''
---
**Опишите вашу идею максимально подробно и понятно**
Необходима функция улучшения голосовых сообщений. Она значительно улучшит запись голосовых сообщений и собеседнику будет лучше слышно меня
**Опишите возможное решение/реализацию функции (если понимаете как это можно реализовать на Java/C++)**
**Остальные мысли о предложенной функции**
+4
View File
@@ -4,11 +4,15 @@ on:
push:
branches:
- '*'
paths-ignore:
- '**.md'
pull_request:
types:
- opened
- synchronize
- reopened
paths-ignore:
- '**.md'
workflow_dispatch:
+1
View File
@@ -29,3 +29,4 @@ smali2/build/resources.zip
smali/build/resources.zip
smali/assets/version.properties
*.keystore
gradle.properties
+154 -57
View File
@@ -1,99 +1,196 @@
# 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 Me
* Встроенный переводчик текста для сообщений
* Возможность выбрать язык перевода
* Автоматический перевод ваших сообщений на выбранный язык
* Альтернативный дизайн эмодзи меню
* Возможность использовать системные эмодзи
* Возможнсть использовать Enter с аппаратной клавиатуры
* Активность
* Возможность видеть удаленные сообщения
* Функционал, позволяющий оставаться в «оффлайне» (принудительный оффлайн/не отправлять статус онлайна и т.п.)
* Нечиталка/неписалка для ЛС/бесед/ботов/групп
* Возможность отключить информацию о том, что вы просмотрели историю/прослушали голосовое сообщение
* Возможность видеть онлайн пользователей, если у вас скрыт онлайн через VK Messenger
* Возможность сохранять настройки бесшумных сообщений/сообщений-бомбочек
* Отключить уведомление о том, что вы сделали скриншот в беседе
* Отключение редиректа через away.php
* Отключение отправки метрики
* Внешний вид
* **Milkshake** тема (дизайн новых версий ВК)
* Название заголовков в докбаре
* Возможность использовать акцент для иконок
* Возможность отключить счётчики в докбаре
* Смена иконки приложения (содержит много уникальных иконок для донатеров)
* Возможность покрасить панель навигации, веб-страницы
* Telegram Стикеры
* Возможность загружать свои стикерпаки из Telegram во ВКонтакте
* Интерфейс
* Возможность отключить блок историй наверху ленты
* Возможность отключить боковую камеру в разделе «Новости»
* Возможность отключить блок «Что у вас нового?» в разделе «Новости»
* Возможность показывать лайки у постов справа
* Возможность менять стартовый раздел при запуске приложения
* Анимации фрагментов
* Возможность изменять размер закругления картинок (аватарок и прочего)
* Возможность отключить редизайн видеопостов
* Возможность отключить блок миниаппов/VK Pay/Superapp
* Возможность отключить сокращение названий разделов в меню
* Возможность скрыть блок рекомендаций друзей в разделе «Друзья»
* Возможность скрыть подписи в настройках
* Прокси
* Поддержка сторонних прокси, таких как: Zaborona, VikaMobile, рандомные прокси и прочие
* Возможность использовать **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"/>
+3 -5
View File
@@ -69,16 +69,15 @@ task exportDex {
android {
compileSdkVersion 32
buildToolsVersion '32.0.0'
buildToolsVersion '33.0.0'
defaultConfig {
applicationId "ru.vtosters.lite.utils.lite"
minSdkVersion 24
minSdk 22
targetSdkVersion 32
versionCode 1
versionName "1.0"
multiDexEnabled true
multiDexEnabled false
}
compileOptions {
@@ -89,7 +88,6 @@ android {
}
dependencies {
implementation "androidx.multidex:multidex:2.0.1"
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.exifinterface:exifinterface:1.3.3'
implementation 'androidx.preference:preference:1.2.0'
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
ea0425fab4379ae5f7e9db05a22d4b7afd709560
Binary file not shown.
@@ -1 +0,0 @@
3b92d8876dd59d5afc60a53bb23b103cede6a194
Binary file not shown.
Binary file not shown.
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,13 @@ 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, MusicPlaybackLaunchContext playerRefer) {
var playbackContext = "";
if (playerRefer != null) {
playbackContext = playerRefer.v0();
}
int indexOf = list.indexOf(musicTrack);
var ids = new ArrayList<String>();
for (var track : list) {
@@ -64,13 +71,17 @@ public class LibVKXClient{
}
try {
iLibVkxService.play(ids, indexOf, "");
iLibVkxService.play(ids, indexOf, playbackContext);
} catch (RemoteException e) {
e.printStackTrace();
}
}
private static String asId(MusicTrack musicTrack){
public static void lambdaplay(List<MusicTrack> list, MusicTrack musicTrack, ILibVkxService iLibVkxService){
lambdaplay(list, musicTrack, iLibVkxService, null);
}
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;
@@ -16,11 +16,12 @@ import com.aefyr.tsg.g2.stickersgrabber.TelegramStickersGrabber;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicLong;
import ru.vtosters.lite.utils.AndroidUtils;
/**
* Created by Aefyr on 20.05.2018.
*/
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 +32,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);
@@ -39,31 +40,31 @@ public class NotificationsHelper{
downloadingPacksNotificationsIds = new HashMap<>();
if (oreo()) {
NotificationChannel notificationChan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "Сервис стикеров Telegram в VTosters", NotificationManager.IMPORTANCE_HIGH);
NotificationChannel notificationChan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, AndroidUtils.getString("telegram_stickers_service"), NotificationManager.IMPORTANCE_HIGH);
((NotificationManager) c.getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(notificationChan);
}
}
public void packStartedDownloading(TelegramStickersPack pack){
public void packStartedDownloading(TelegramStickersPack pack) {
int notificationId = NOTIFICATION_ID_BASE + currentNotificationN++;
downloadingPacksNotificationsIds.put(pack, notificationId);
Notification.Builder builder = commonBuilder();
builder.setContentTitle(pack.state == TelegramStickersPack.DOWNLOADING ? pack.title + ": загрузка" : pack.title + ": обновление");
builder.setContentText("Получение информации");
builder.setContentTitle(pack.state == TelegramStickersPack.DOWNLOADING ? pack.title + AndroidUtils.getString("telegram_stickers_downloading") : pack.title + AndroidUtils.getString("telegram_stickers_updating"));
builder.setContentText(AndroidUtils.getString("telegram_stickers_gettinginfo"));
builder.setOngoing(true);
manager.notify(notificationId, builder.build());
}
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;
lastNotificationTime.set(System.currentTimeMillis());
Notification.Builder builder = commonBuilder();
builder.setContentTitle(pack.state == TelegramStickersPack.DOWNLOADING ? pack.title + ": загрузка" : pack.title + ": обновление");
builder.setContentTitle(pack.state == TelegramStickersPack.DOWNLOADING ? pack.title + AndroidUtils.getString("telegram_stickers_downloading") : pack.title + AndroidUtils.getString("telegram_stickers_updating"));
builder.setContentText(downloadProgress + "/" + pack.stickersCount);
builder.setProgress(pack.stickersCount, downloadProgress, false);
builder.setOngoing(true);
@@ -73,17 +74,17 @@ 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);
builder.setContentTitle("Сервис стикеров Telegram в VTosters");
builder.setContentTitle(AndroidUtils.getString("telegram_stickers_service"));
String text;
if (success)
text = wasUpdate ? pack.title + " успешно обновлен" : pack.title + " успешно загружен";
text = wasUpdate ? pack.title + AndroidUtils.getString("telegram_stickers_updated") : pack.title + AndroidUtils.getString("telegram_stickers_downloaded");
else
text = wasUpdate ? pack.title + ": ошибка при обновлении" : pack.title + ": ошибка при загрузке";
text = wasUpdate ? pack.title + AndroidUtils.getString("telegram_stickers_error_update") : pack.title + AndroidUtils.getString("telegram_stickers_error_download");
if (e instanceof TelegramStickersGrabber.TSGException) {
text = pack.title + ": " + e.getMessage();
@@ -94,11 +95,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 +108,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,242 @@
package com.vk.core.util;
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.os.Environment;
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.FileOutputStream;
import java.io.IOException;
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 uri, boolean z) {
if (TextUtils.isEmpty(uri)) {
return;
}
String fileName = a(str, uri);
File file;
Log.v("DownloadUtils", "download: filename = " + fileName + " | str = " + str + "| str2 = " + uri);
if (fileName.endsWith(".jpg") || fileName.endsWith(".png") || fileName.endsWith(".jpeg")) {
file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath(), fileName);
} else if (fileName.endsWith(".mp3") || fileName.endsWith(".wav") || fileName.endsWith(".ogg") || fileName.endsWith(".aac") || fileName.endsWith(".flac") || fileName.endsWith(".m4a")) {
file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath(), fileName);
} else if (fileName.endsWith(".mp4") || fileName.endsWith(".mkv") || fileName.endsWith(".avi") || fileName.endsWith(".flv") || fileName.endsWith(".wmv") || fileName.endsWith(".mov") || fileName.endsWith(".3gp")) {
file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).getAbsolutePath(), fileName);
} else {
file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(), fileName);
}
boolean isImage = MediaUtils.c(FileUtils.f(file));
if (isImage) {
EncodedImage encodedImage = VKImageLoader.c(Uri.parse(uri));
final InputStream h = encodedImage == null ? null : encodedImage.h();
if (h != null) {
try {
if (file.getParentFile() != null) {
file.createNewFile();
}
if (file.exists()) {
VkExecutors.x.e().execute(() -> {
try {
FileUtils.b.a(h, new FileOutputStream(file), h.available(), null);
ToastUtils.a(context.getString(R.string.file_saved, file.getAbsoluteFile()));
} catch (IOException e) {
ToastUtils.a(context.getString(R.string.error) + " [" + e.getMessage() + "]");
e.printStackTrace();
}
});
}
} catch (Exception e2) {
L.a(e2);
}
CameraUtils.a(context, file, null);
return;
}
}
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(uri));
var mimeType = FileUtils.f(file);
request.setDestinationUri(Uri.fromFile(file));
request.setMimeType(mimeType);
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);
var mimeType = FileUtils.f(file);
var uri = FileUtils.uriFromFile(file);
Log.d("DownloadUtils", "openFile: " + file.getAbsolutePath() + "| mimetype " + mimeType + "| uri " + uri);
if (!TextUtils.isEmpty(mimeType)) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(uri, mimeType);
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()) {
var mimeType = FileUtils.f(file);
var uri = FileUtils.uriFromFile(file);
Intent intent = new Intent("android.intent.action.VIEW");
intent.setDataAndType(uri, mimeType);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Log.d("DownloadUtils", "openFile: " + file.getAbsolutePath() + "| mimetype " + mimeType + "| uri " + uri);
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,40 @@
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,
ENCRYPT_SETT,
ENCRYPT,
DOWNLOAD
}
@@ -0,0 +1,149 @@
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,106 @@
package com.vk.profile.ui.community;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.util.AttributeSet;
import com.vk.core.ui.themes.Themable;
import com.vk.core.ui.themes.VKThemeHelper;
import com.vk.core.util.ContextExtKt;
import com.vk.dto.stories.model.StoriesContainer;
import com.vk.stories.view.BorderedCircleImageView;
import com.vtosters.lite.R;
public final class CommunityBorderedImageView extends BorderedCircleImageView implements Themable{
private boolean f0;
private int g0;
private int h0;
private PorterDuffColorFilter i0;
private PorterDuffColorFilter j0;
private int unread;
private int read;
public CommunityBorderedImageView(Context context){
this(context, null, 0, 6);
}
public CommunityBorderedImageView(Context context, AttributeSet attributeSet){
this(context, attributeSet, 0, 4);
}
public CommunityBorderedImageView(Context context, AttributeSet attributeSet, int i, int i2){
this(context, (i2 & 2) != 0 ? null : attributeSet, (i2 & 4) != 0 ? 0 : i);
}
public CommunityBorderedImageView(Context context, AttributeSet attributeSet, int i){
super(context, attributeSet, i);
this.g0 = VKThemeHelper.d((int) R.attr.accent);
this.h0 = ContextExtKt.a(context, (int) R.color.gray_200);
this.i0 = new PorterDuffColorFilter(this.g0, PorterDuff.Mode.SRC_IN);
this.j0 = new PorterDuffColorFilter(this.h0, PorterDuff.Mode.SRC_IN);
}
public final void c(int unread, int read){ // get unread and read resid
this.unread = unread;
this.read = read;
this.T = BitmapFactory.decodeResource(getResources(), this.unread);
}
public final int getPrimaryColor(){
return this.g0;
}
public final void setPrimaryColor(int i){
this.g0 = i;
this.i0 = new PorterDuffColorFilter(i, PorterDuff.Mode.SRC_IN);
}
public final int getWasViewedColor(){
return this.h0;
}
public final void setWasViewedColor(int i){
this.h0 = i;
this.j0 = new PorterDuffColorFilter(i, PorterDuff.Mode.SRC_IN);
}
public final void o(){
this.f0 = false;
l();
}
@Override // com.vk.stories.view.ClippedImageView, android.widget.ImageView, android.view.View
public void onDraw(Canvas canvas){
super.onDraw(canvas);
if (this.f0) {
a(canvas);
}
}
public final void setStoryContainer(StoriesContainer storiesContainer){
if (storiesContainer.L1()) {
this.f0 = true;
m();
if (storiesContainer.K1()) {
this.T = BitmapFactory.decodeResource(getResources(), this.unread);
setBorderColorFilter(this.i0);
b(getWidth(), getHeight());
invalidate();
return;
}
this.T = BitmapFactory.decodeResource(getResources(), this.read);
setBorderColorFilter(this.j0);
b(getWidth(), getHeight());
invalidate();
return;
}
o();
}
@Override // com.vk.core.ui.themes.Themable
public void v(){
}
}
@@ -0,0 +1,301 @@
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.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;
@UiThread
public class TargetImageView extends VKMultiImageView {
private static final int I = Screen.a(2);
private final int B;
private final int C;
private Drawable D;
private String[] F;
private int G;
private final RectF f21629d;
private final Paint f21630e;
private Canvas f21631f;
private final RectF g;
private final Paint h;
public TargetImageView(Context context, Drawable d) {
this(context, null, 0, 6);
}
public TargetImageView(Context context, AttributeSet attributeSet) {
this(context, attributeSet, 0, 4);
}
public TargetImageView(Context context, AttributeSet attributeSet, int i, int i2) {
this(context, (i2 & 2) != 0 ? null : attributeSet, (i2 & 4) != 0 ? 0 : i);
}
private void e() {
int i = this.G;
for (int i2 = 0; i2 < i; i2++) {
a(i2, this.F[i2]);
}
}
private void f() {
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int width = (getWidth() - paddingLeft) - getPaddingRight();
int height = (getHeight() - paddingTop) - getPaddingBottom();
int i = width / 2;
int i2 = height / 2;
int i3 = this.G;
if (i3 == 1) {
DraweeHolder<GenericDraweeHierarchy> a2 = this.a.a(0);
Drawable d2 = a2.d();
if (d2 != null) {
d2.setBounds(paddingLeft, paddingTop, width + paddingLeft, height + paddingTop);
}
} else if (i3 == 2) {
DraweeHolder<GenericDraweeHierarchy> a3 = this.a.a(0);
Drawable d3 = a3.d();
if (d3 != null) {
int i4 = i + paddingLeft;
int i5 = height + paddingTop;
d3.setBounds(paddingLeft, paddingTop, i4, i5);
DraweeHolder<GenericDraweeHierarchy> a4 = this.a.a(1);
Drawable d4 = a4.d();
if (d4 != null) {
d4.setBounds(i4, paddingTop, paddingLeft + width, i5);
}
}
} else if (i3 == 3) {
DraweeHolder<GenericDraweeHierarchy> a5 = this.a.a(0);
Drawable d5 = a5.d();
if (d5 != null) {
int i6 = i + paddingLeft;
int i7 = height + paddingTop;
d5.setBounds(paddingLeft, paddingTop, i6, i7);
DraweeHolder<GenericDraweeHierarchy> a6 = this.a.a(1);
Drawable d6 = a6.d();
if (d6 != null) {
int i9 = paddingLeft + width;
int i10 = i2 + paddingTop;
d6.setBounds(i6, paddingTop, i9, i10);
DraweeHolder<GenericDraweeHierarchy> a7 = this.a.a(2);
Drawable d7 = a7.d();
if (d7 != null) {
d7.setBounds(i6, i10, i9, i7);
}
}
}
} else {
DraweeHolder<GenericDraweeHierarchy> a8 = this.a.a(0);
Drawable d8 = a8.d();
if (d8 != null) {
int i11 = i + paddingLeft;
int i13 = i2 + paddingTop;
d8.setBounds(paddingLeft, paddingTop, i11, i13);
DraweeHolder<GenericDraweeHierarchy> a9 = this.a.a(1);
Drawable d9 = a9.d();
if (d9 != null) {
int i16 = height + paddingTop;
d9.setBounds(paddingLeft, i13, i11, i16);
DraweeHolder<GenericDraweeHierarchy> a10 = this.a.a(2);
Drawable d10 = a10.d();
if (d10 != null) {
int i18 = paddingLeft + width;
d10.setBounds(i11, paddingTop, i18, i13);
DraweeHolder<GenericDraweeHierarchy> a11 = this.a.a(3);
Drawable d11 = a11.d();
if (d11 != null) {
d11.setBounds(i11, i13, i18, i16);
}
}
}
}
}
}
private void g() {
if (getWidth() == 0 || getHeight() == 0) {
return;
}
f();
}
private AbbreviationAvatarDrawable getAbbreviationDrawable() {
return a(getContext(), null, 2);
}
private AbbreviationAvatarDrawable a(Context context, Typeface typeface, int i) {
return new AbbreviationAvatarDrawable(context, (i & 2) != 0 ? ContextExtKt.e(context, roboto_medium) : typeface);
}
public void a(String str) {
Arrays.fill(this.F, null);
if (str == null) {
b();
this.G = 1;
g();
e();
return;
}
Uri uri = Uri.parse(str);
if (uri.getScheme().equals("vkchatphoto")) {
this.G = 0;
while (true) {
String queryParameter = uri.getQueryParameter("photo" + this.G);
if (queryParameter != null) {
int i = this.G;
this.G = i + 1;
this.F[i] = queryParameter;
} else {
g();
e();
return;
}
}
} else if (uri.getScheme().equals("vkchatplaceholder")) {
this.G = 1;
g();
AbbreviationAvatarDrawable abbreviationDrawable = getAbbreviationDrawable();
String queryParameter2 = uri.getQueryParameter(NavigatorKeys.Q);
int parseInt = queryParameter2 != null ? Integer.parseInt(queryParameter2) : 0;
String queryParameter3 = uri.getQueryParameter(NavigatorKeys.d);
if (queryParameter3 == null) {
queryParameter3 = "";
}
abbreviationDrawable.a(parseInt, queryParameter3);
a(0, getAbbreviationDrawable());
} else {
this.F[0] = str;
this.G = 1;
g();
e();
}
}
@Override // android.view.View
protected void onDraw(Canvas canvas) {
Canvas canvas2 = this.f21631f;
int pref = preferences.getInt("pic_rounding", 0);
if (canvas2 != null) {
canvas2.drawColor(0, PorterDuff.Mode.CLEAR);
}
int i = this.G;
for (int i2 = 0; i2 < i; i2++) {
DraweeHolder<GenericDraweeHierarchy> a2 = this.a.a(i2);
Drawable d2 = a2.d();
if (d2 != null) {
Canvas canvas3 = this.f21631f;
d2.draw(canvas3);
}
}
if (pref > 0) {
canvas.drawRoundRect(this.f21629d, pref, pref, this.f21630e);
} else {
canvas.drawOval(this.f21629d, this.f21630e);
}
if (isSelected()) {
if (pref > 0) {
canvas.drawRoundRect(this.g.left, this.g.top, this.g.right, this.g.bottom, pref, pref, this.h);
} else {
canvas.drawCircle(this.g.centerX(), this.g.centerY(), this.g.width() / 2, this.h);
}
this.D.draw(canvas);
}
}
@Override // android.view.View
protected void onSizeChanged(int i, int i2, int i3, int i4) {
super.onSizeChanged(i, i2, i3, i4);
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
int paddingTop = getPaddingTop();
int i5 = i - paddingRight;
int paddingBottom = i2 - getPaddingBottom();
this.f21629d.set(paddingLeft, paddingTop, i5, paddingBottom);
Bitmap createBitmap = Bitmap.createBitmap(i5, paddingBottom, Bitmap.Config.ARGB_8888);
this.f21631f = new Canvas(createBitmap);
Shader.TileMode tileMode = Shader.TileMode.CLAMP;
this.f21630e.setShader(new BitmapShader(createBitmap, tileMode, tileMode));
float f2 = I / 2;
this.g.set(f2, f2, i - f2, (float) i2 - f2);
float f4 = i / 2;
this.h.setShader(new LinearGradient(f4, 0.0f, f4, (float) i2, this.B, this.C, Shader.TileMode.CLAMP));
Drawable drawable = this.D;
drawable.setBounds(i - drawable.getIntrinsicWidth(), i2 - this.D.getIntrinsicHeight(), i, i2);
f();
}
public TargetImageView(Context context, AttributeSet attributeSet, int i) {
super(context, attributeSet, i);
this.f21629d = new RectF();
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
paint.setFilterBitmap(true);
this.f21630e = paint;
this.g = new RectF();
Paint paint2 = new Paint();
paint2.setAntiAlias(true);
paint2.setStrokeWidth(I);
paint2.setStyle(Paint.Style.STROKE);
this.h = paint2;
this.B = getAccentColor();
this.C = this.B;
Drawable c2 = ContextExtKt.c(context, R.drawable.ic_check_circle_composite_24_full);
if (c2 != null) {
this.D = c2;
this.F = new String[4];
int i2 = I * 2;
setPadding(i2, i2, i2, i2);
if (attributeSet != null) {
TypedArray obtainStyledAttributes = context.obtainStyledAttributes(attributeSet, a0.TargetImageView);
setSelected(obtainStyledAttributes.getBoolean(0, false));
obtainStyledAttributes.recycle();
}
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.user_placeholder);
for (int i3 = 0; i3 <= 3; i3++) {
a();
DraweeHolder<GenericDraweeHierarchy> a3 = this.a.a(i3);
a3.b().e(drawable);
}
setScaleType(ScalingUtils.b.o);
}
}
}
@@ -0,0 +1,442 @@
package com.vk.stories.view;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.AttributeSet;
import android.view.ViewTreeObserver;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.LottieCompositionFactory;
import com.airbnb.lottie.LottieDrawable;
import com.airbnb.lottie.LottieListener;
import com.facebook.common.internal.Supplier;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.DataSource;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import com.facebook.u.b.a.PipelineDraweeControllerBuilder;
import com.facebook.x.g.CloseableImage;
import com.vk.core.ui.themes.Themable;
import com.vk.core.ui.themes.VKThemeHelper;
import com.vk.core.util.DrawableUtils;
import com.vk.core.util.ResUtils;
import com.vk.core.util.Screen;
import com.vk.dto.stories.d.StoriesContainerExt;
import com.vk.dto.stories.model.CommunityGroupedStoriesContainer;
import com.vk.dto.stories.model.StoriesContainer;
import com.vk.dto.stories.model.StoryEntry;
import com.vk.im.engine.models.Image;
import com.vk.im.ui.views.avatars.AvatarDataSource;
import com.vk.imageloader.FrescoWrapper;
import com.vk.stories.StoriesController;
import com.vtosters.lite.R;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
public class StoryCircleImageView extends BorderedCircleImageView implements Themable{
private static final HashSet<Integer> B0 = new HashSet<>();
private final PipelineDraweeControllerBuilder f0;
private int A0;
private Drawable g0;
private Drawable h0;
private Drawable i0;
private int j0;
private int k0;
private int l0;
private int m0;
private int n0;
private int o0;
private Bitmap p0;
private Bitmap q0;
private Bitmap r0;
private Bitmap s0;
private boolean t0;
private boolean u0;
private boolean v0;
private boolean w0;
private boolean x0;
private String y0;
private LottieDrawable z0;
public StoryCircleImageView(Context context){
this(context, null);
}
public StoryCircleImageView(Context context, AttributeSet attributeSet){
this(context, attributeSet, 0);
}
public StoryCircleImageView(Context context, AttributeSet attributeSet, int i){
super(context, attributeSet, i);
this.f0 = FrescoWrapper.c.d();
a(context, attributeSet, i);
}
private void b(Canvas canvas){
this.z0.draw(canvas);
}
private boolean o(){
return !this.u0 && !this.t0 && this.z0 == null && !this.w0 && !this.v0;
}
private void p(){
this.z0.stop();
this.z0 = null;
invalidate();
}
private void q(){
int i = this.j0;
if (i != 0 && VKThemeHelper.k.a(i)) {
this.k0 = VKThemeHelper.d(this.j0);
}
this.g0 = DrawableUtils.a(this.g0, ColorStateList.valueOf(this.k0));
Drawable drawable = this.g0;
int i2 = this.A0;
this.p0 = DrawableUtils.a(drawable, i2, i2);
int i3 = this.l0;
if (i3 != 0 && VKThemeHelper.k.a(i3)) {
this.m0 = VKThemeHelper.d(this.l0);
}
int i4 = this.m0;
if (i4 != 0) {
this.i0 = DrawableUtils.a(this.i0, ColorStateList.valueOf(i4));
}
int i5 = this.n0;
if (i5 != 0 && VKThemeHelper.k.a(i5)) {
this.o0 = VKThemeHelper.d(this.n0);
}
Drawable a2 = DrawableUtils.a(this.g0, ColorStateList.valueOf(0));
int i6 = this.A0;
DrawableUtils.a(a2, i6, i6);
Drawable a3 = DrawableUtils.a(this.h0, ColorStateList.valueOf(this.o0));
int i7 = this.A0;
this.r0 = DrawableUtils.a(a3, i7, i7);
Drawable a4 = DrawableUtils.a(this.g0, ColorStateList.valueOf(ContextCompat.getColor(getContext(), R.color.orange)));
int i8 = this.A0;
this.s0 = DrawableUtils.a(a4, i8, i8);
}
private void r(){
this.c0 = Screen.a(o() ? 0 : 2);
m();
q();
}
private void setUploadFailed(boolean z){
this.u0 = z;
invalidate();
}
@Override // com.vk.stories.view.ClippedImageView, android.widget.ImageView, android.view.View
public void onDraw(Canvas canvas){
super.onDraw(canvas);
setBorderAlpha(255);
if (this.u0) {
this.i0.draw(canvas);
} else if (this.t0) {
if (this.z0 != null) {
b(canvas);
return;
}
this.T = this.x0 ? this.s0 : this.p0;
b(getWidth(), getHeight());
a(canvas);
} else if (this.z0 != null) {
p();
} else if (!this.w0) {
} else {
this.T = this.r0;
setBorderAlpha(163);
b(getWidth(), getHeight());
a(canvas);
}
}
@Override // com.vk.stories.view.BorderedCircleImageView, android.view.View
public void onSizeChanged(int i, int i2, int i3, int i4){
super.onSizeChanged(i, i2, i3, i4);
this.i0.setBounds(0, 0, i, i2);
b(i);
}
public void setStoryContainer(@Nullable StoriesContainer storiesContainer){
boolean z = true;
boolean z2 = storiesContainer != null && storiesContainer.Q1();
this.v0 = storiesContainer != null && storiesContainer.S1() && !storiesContainer.L1();
boolean z3 = storiesContainer instanceof CommunityGroupedStoriesContainer;
this.x0 = z3;
if (storiesContainer != null) {
if (!StoriesContainerExt.c(storiesContainer) && !StoriesContainerExt.d(storiesContainer)) {
this.T = this.p0;
} else {
this.T = this.q0;
}
b(getWidth(), getHeight());
if (StoriesContainerExt.e(storiesContainer)) {
a(storiesContainer);
} else if (this.z0 != null) {
p();
}
this.w0 = !storiesContainer.K1() && storiesContainer.L1();
if (z2) {
String h = storiesContainer.h(ResUtils.c(R.dimen.story_preview_image_size));
if (h != null) {
a(h);
} else {
g();
}
if (StoriesController.a(storiesContainer)) {
setUploadFailed(true);
a(false, false);
} else {
setUploadFailed(false);
if (!storiesContainer.K1() && !StoriesContainerExt.c(storiesContainer)) {
a(false, false);
} else {
StoryEntry A1 = storiesContainer.A1();
if (A1 != null) {
a(true, !B0.contains(A1.b));
B0.add(A1.b);
} else {
a(true, false);
}
}
}
} else {
setUploadFailed(false);
if (!storiesContainer.K1() && !StoriesContainerExt.c(storiesContainer)) {
z = false;
}
a(z, false);
if (z3) {
b(((CommunityGroupedStoriesContainer) storiesContainer).j(ResUtils.c(R.dimen.story_preview_image_size)));
} else {
String h2 = storiesContainer.h(ResUtils.c(R.dimen.story_preview_image_size));
if (h2 != null) {
a(h2);
} else {
g();
}
}
}
} else {
g();
a(false, false);
setUploadFailed(false);
this.w0 = false;
}
r();
}
@Override // com.vk.core.ui.themes.Themable
public void v(){
r();
invalidate();
}
private void b(int i){
LottieDrawable lottieDrawable = this.z0;
if (lottieDrawable == null || lottieDrawable.e() == null) {
return;
}
this.z0.d(i / this.z0.e().a().width());
}
protected void a(Context context, AttributeSet attributeSet, int i){
TypedArray obtainStyledAttributes = context.obtainStyledAttributes(attributeSet, com.vtosters.lite.a0.StoryCircleImageView, i, 0);
a(context, attributeSet, obtainStyledAttributes);
obtainStyledAttributes.recycle();
r();
this.T = this.p0;
}
public void b(@Nullable List<String> list){
PipelineDraweeControllerBuilder pipelineDraweeControllerBuilder = this.f0;
pipelineDraweeControllerBuilder.j();
pipelineDraweeControllerBuilder.a(getController());
setControllerListener(pipelineDraweeControllerBuilder);
a(pipelineDraweeControllerBuilder, list);
setController(pipelineDraweeControllerBuilder.k0());
}
@SuppressLint("ResourceType")
private void a(Context context, AttributeSet attributeSet, TypedArray typedArray){ // bullshit vk code is not working with custom bordered circle image
Drawable drawable;
this.A0 = typedArray.getDimensionPixelSize(0, Screen.a(64.0f));
if (typedArray.hasValue(2)) {
this.g0 = typedArray.getDrawable(2);
} else {
this.g0 = ContextCompat.getDrawable(context, R.drawable.bg_stores_unread_border_80);
}
if (typedArray.hasValue(3)) {
this.h0 = typedArray.getDrawable(3);
} else {
this.h0 = ContextCompat.getDrawable(context, R.drawable.bg_stores_read_border_80);
}
int b2 = VKThemeHelper.b(attributeSet, "vk_borderTint");
if (b2 != 0 && VKThemeHelper.k.a(b2)) {
this.j0 = b2;
} else if (typedArray.hasValue(5)) {
this.k0 = typedArray.getColor(5, 0);
} else {
this.j0 = R.attr.accent;
}
int b3 = VKThemeHelper.b(attributeSet, "vk_failBorderTint");
if (b3 != 0 && VKThemeHelper.k.a(b3)) {
this.l0 = b3;
} else if (typedArray.hasValue(7)) {
this.m0 = typedArray.getColor(7, 0);
}
int b4 = VKThemeHelper.b(attributeSet, "vk_borderSeenTint");
if (b4 != 0 && VKThemeHelper.k.a(b4)) {
this.n0 = b4;
} else if (typedArray.hasValue(4)) {
this.o0 = typedArray.getColor(4, 0);
} else {
this.o0 = 0;
}
if (typedArray.hasValue(6)) {
this.i0 = typedArray.getDrawable(6);
} else {
this.i0 = ContextCompat.getDrawable(context, R.drawable.ic_story_error_size64);
}
if (typedArray.hasValue(8)) {
drawable = typedArray.getDrawable(8);
} else {
drawable = ContextCompat.getDrawable(context, R.drawable.bg_live_unread_border);
}
if (typedArray.hasValue(9)) {
this.y0 = typedArray.getString(9);
} else {
this.y0 = "stories_animation_64.json";
}
int i = this.A0;
this.q0 = DrawableUtils.a(Objects.requireNonNull(drawable), i, i);
Drawable drawable2 = this.g0;
int i2 = this.A0;
DrawableUtils.a(drawable2, i2, i2);
Drawable drawable3 = this.h0;
int i3 = this.A0;
this.r0 = DrawableUtils.a(drawable3, i3, i3);
Drawable drawable4 = this.g0;
int i4 = this.A0;
this.s0 = DrawableUtils.a(drawable4, i4, i4);
}
public void a(StoriesContainer storiesContainer){
if (this.z0 == null) {
LottieCompositionFactory.a(getContext(), this.y0).b(new a(storiesContainer));
}
}
public void a(StoriesContainer storiesContainer, LottieComposition lottieComposition){
this.z0 = new LottieDrawable();
this.z0.a(lottieComposition);
this.z0.d(-1);
b(getWidth());
if (!StoriesContainerExt.f(storiesContainer)) {
this.z0.a(new b());
this.z0.start();
return;
}
this.z0.stop();
}
private void a(boolean z, boolean z2){
k();
this.t0 = z;
if (!z2) {
setSelectionAmount(1.0f);
} else {
n();
}
}
private void a(@NonNull PipelineDraweeControllerBuilder pipelineDraweeControllerBuilder, @Nullable final List<String> list){
pipelineDraweeControllerBuilder.b(null);
pipelineDraweeControllerBuilder.a((Supplier<DataSource<CloseableReference<com.facebook.x.g.CloseableImage>>>) null);
if (list != null && !list.isEmpty()) {
if (list.size() == 1) {
ImageRequestBuilder b2 = ImageRequestBuilder.b(Uri.parse(list.get(0)));
b2.a(ImageRequest.CacheChoice.SMALL);
pipelineDraweeControllerBuilder.b(b2.a());
return;
}
pipelineDraweeControllerBuilder.a((Supplier<DataSource<CloseableReference<CloseableImage>>>) () -> StoryCircleImageView.this.a(list));
return;
}
pipelineDraweeControllerBuilder.b(null);
}
public DataSource<CloseableReference<CloseableImage>> a(@Nullable List<String> list){
ArrayList<Image> arrayList = new ArrayList<>();
for (String o : Objects.requireNonNull(list)) {
arrayList.add(new Image(-1, -1, o));
}
return AvatarDataSource.a(arrayList, this.A0, 0);
}
public class a implements LottieListener<LottieComposition>{
final StoriesContainer a;
a(StoriesContainer storiesContainer){
this.a = storiesContainer;
}
@Override // com.airbnb.lottie.LottieListener
public void a(LottieComposition lottieComposition){
if (StoryCircleImageView.this.getWidth() > 0) {
StoryCircleImageView.this.a(this.a, lottieComposition);
} else {
StoryCircleImageView.this.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver$OnGlobalLayoutListenerC0393a(lottieComposition));
}
}
public class ViewTreeObserver$OnGlobalLayoutListenerC0393a implements ViewTreeObserver.OnGlobalLayoutListener{
final LottieComposition a;
ViewTreeObserver$OnGlobalLayoutListenerC0393a(LottieComposition lottieComposition){
this.a = lottieComposition;
}
@Override // android.view.ViewTreeObserver.OnGlobalLayoutListener
public void onGlobalLayout(){
StoryCircleImageView.this.getViewTreeObserver().removeOnGlobalLayoutListener(this);
a aVar = a.this;
StoryCircleImageView.this.a(aVar.a, this.a);
}
}
}
public class b implements ValueAnimator.AnimatorUpdateListener{
b(){
}
@Override // android.animation.ValueAnimator.AnimatorUpdateListener
public void onAnimationUpdate(ValueAnimator valueAnimator){
StoryCircleImageView.this.invalidate();
}
}
}
+41 -41
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;
@@ -3560,26 +3560,26 @@ public class R{
public static final int stickers_notifications_size = 0x7f070285;
public static final int stickers_tabs_padding = 0x7f070286;
public static final int stickers_tabs_size = 0x7f070287;
public static final int stiсkers_catalog_button_padding_bottom = 0x7f070288;
public static final int stiсkers_catalog_button_padding_left = 0x7f070289;
public static final int stiсkers_catalog_button_padding_right = 0x7f07028a;
public static final int stiсkers_catalog_button_padding_top = 0x7f07028b;
public static final int stiсkers_catalog_double_stacked_slider_image_bg_size = 0x7f07028c;
public static final int stiсkers_catalog_double_stacked_slider_image_corner_radius = 0x7f07028d;
public static final int stiсkers_catalog_double_stacked_slider_image_size = 0x7f07028e;
public static final int stiсkers_catalog_large_slider_image_bg_height = 0x7f07028f;
public static final int stiсkers_catalog_large_slider_image_bg_width = 0x7f070290;
public static final int stiсkers_catalog_large_slider_image_corner_radius = 0x7f070291;
public static final int stiсkers_catalog_large_slider_image_size = 0x7f070292;
public static final int stiсkers_catalog_small_slider_image_bg_size = 0x7f070293;
public static final int stiсkers_catalog_small_slider_image_corner_radius = 0x7f070294;
public static final int stiсkers_catalog_small_slider_image_size = 0x7f070295;
public static final int stiсkers_catalog_triple_stacked_slider_image_bg_size = 0x7f070296;
public static final int stiсkers_catalog_triple_stacked_slider_image_corner_radius = 0x7f070297;
public static final int stiсkers_catalog_triple_stacked_slider_image_size = 0x7f070298;
public static final int stiсkers_catalog_vertical_list_image_bg_size = 0x7f070299;
public static final int stiсkers_catalog_vertical_list_image_corner_radius = 0x7f07029a;
public static final int stiсkers_catalog_vertical_list_image_size = 0x7f07029b;
public static final int stickers_catalog_button_padding_bottom = 0x7f070288;
public static final int stickers_catalog_button_padding_left = 0x7f070289;
public static final int stickers_catalog_button_padding_right = 0x7f07028a;
public static final int stickers_catalog_button_padding_top = 0x7f07028b;
public static final int stickers_catalog_double_stacked_slider_image_bg_size = 0x7f07028c;
public static final int stickers_catalog_double_stacked_slider_image_corner_radius = 0x7f07028d;
public static final int stickers_catalog_double_stacked_slider_image_size = 0x7f07028e;
public static final int stickers_catalog_large_slider_image_bg_height = 0x7f07028f;
public static final int stickers_catalog_large_slider_image_bg_width = 0x7f070290;
public static final int stickers_catalog_large_slider_image_corner_radius = 0x7f070291;
public static final int stickers_catalog_large_slider_image_size = 0x7f070292;
public static final int stickers_catalog_small_slider_image_bg_size = 0x7f070293;
public static final int stickers_catalog_small_slider_image_corner_radius = 0x7f070294;
public static final int stickers_catalog_small_slider_image_size = 0x7f070295;
public static final int stickers_catalog_triple_stacked_slider_image_bg_size = 0x7f070296;
public static final int stickers_catalog_triple_stacked_slider_image_corner_radius = 0x7f070297;
public static final int stickers_catalog_triple_stacked_slider_image_size = 0x7f070298;
public static final int stickers_catalog_vertical_list_image_bg_size = 0x7f070299;
public static final int stickers_catalog_vertical_list_image_corner_radius = 0x7f07029a;
public static final int stickers_catalog_vertical_list_image_size = 0x7f07029b;
public static final int story_author_title_top_space = 0x7f07029c;
public static final int story_cadre_bottom_btn_top_padding = 0x7f07029d;
public static final int story_camera_tabs_height = 0x7f07029e;
@@ -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,15 +1,17 @@
package com.vtosters.lite.ui.bottomnavigation;
import static ru.vtosters.lite.utils.Themes.getCSTDock;
import static ru.vtosters.lite.utils.Preferences.vkme;
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;
import android.view.View;
@@ -25,13 +27,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;
@@ -43,14 +42,12 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
private MenuItemImpl mItemData;
private ColorStateList mColorStateList;
private final int mMargin;
private final int mDiff;
private final float mSmallScale;
private final float mLargeScale;
private boolean mShiftingModeEnabled;
private boolean mIconsModeEnabled;
private boolean mStaticModeEnabled;
private ImageView mIcon;
private ImageView mActionIcon;
private final ImageView mIcon;
private final ImageView mActionIcon;
public BottomNavigationItemView(@NonNull Context context) {
this(context, null);
@@ -64,12 +61,9 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
super(context, attrs, defStyle);
this.mItemPos = -1;
var textSize = (float) getResources().getDimensionPixelSize(R.dimen.design_bottom_navigation_text_size);
var activeTextSize = (float) getResources().getDimensionPixelSize(R.dimen.design_bottom_navigation_active_text_size);
this.mMargin = getResources().getDimensionPixelSize(R.dimen.design_bottom_navigation_margin);
this.mDiff = (int) (textSize - activeTextSize);
this.mSmallScale = activeTextSize / textSize;
this.mLargeScale = textSize / activeTextSize;
this.mSmallScale = 10.0f;
float mLargeScale = 10.0f;
LayoutInflater.from(context).inflate(R.layout.design_bottom_navigation_item, this, true);
this.setBackgroundResource(R.drawable.design_bottom_navigation_item_background);
@@ -102,6 +96,7 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
this.mActionIcon.setVisibility(VISIBLE);
}
@SuppressLint("RestrictedApi")
public MenuItemImpl getItemData() {
return this.mItemData;
}
@@ -110,6 +105,7 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
return this.mItemPos;
}
@SuppressLint("RestrictedApi")
public void initialize(MenuItemImpl impl, int i) {
this.mItemData = impl;
this.setCheckable(impl.isCheckable());
@@ -121,6 +117,7 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
this.setContentDescription(impl.getTitle());
}
@SuppressLint("RestrictedApi")
public int[] onCreateDrawableState(int extraSpace) {
int[] baseState = super.onCreateDrawableState(extraSpace + 1);
if (this.mItemData != null && this.mItemData.isCheckable() && this.mItemData.isChecked()) {
@@ -146,14 +143,17 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
}
}
@SuppressLint("RestrictedApi")
public boolean prefersCondensedTitle() {
return false;
}
@SuppressLint("RestrictedApi")
public void setCheckable(boolean var1) {
this.refreshDrawableState();
}
@SuppressLint("RestrictedApi")
public void setChecked(boolean checked) {
this.mItemData.setChecked(checked);
@@ -174,20 +174,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);
@@ -198,17 +198,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);
@@ -220,6 +220,20 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
// ViewCompat.setScaleY(mLargeLabel, !mStaticModeEnabled && !checked ? mLargeScale : 1.0f);
ViewCompat.setScaleX(mSmallLabel, !mStaticModeEnabled && checked ? mSmallScale : 1.0f);
ViewCompat.setScaleY(mSmallLabel, !mStaticModeEnabled && checked ? mSmallScale : 1.0f);
mLargeLabel.setTypeface(null, Typeface.BOLD);
mSmallLabel.setTypeface(null, Typeface.BOLD);
int textsize;
if (vkme()){
textsize = 11;
} else {
textsize = 10;
}
mLargeLabel.setTextSize(TypedValue.COMPLEX_UNIT_SP, textsize);
mSmallLabel.setTextSize(TypedValue.COMPLEX_UNIT_SP, textsize);
mLargeLabel.setVisibility(/*checked ? VISIBLE :*/ INVISIBLE);
mSmallLabel.setVisibility(VISIBLE);//checked ? INVISIBLE : VISIBLE);
@@ -229,7 +243,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);
@@ -264,6 +278,7 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
this.mIcon.setEnabled(b);
}
@SuppressLint("RestrictedApi")
public void setIcon(Drawable drawable) {
if (drawable != null) {
if (drawable.getConstantState() != null)
@@ -276,6 +291,7 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
this.mIcon.setImageDrawable(drawable);
}
@SuppressLint("RestrictedApi")
public void setIconTintList(ColorStateList colorStateList) {
this.mColorStateList = colorStateList;
MenuItemImpl impl = this.mItemData;
@@ -305,17 +321,20 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
this.mShiftingModeEnabled = var1;
}
@SuppressLint("RestrictedApi")
public void setShortcut(boolean b, char c) {
}
public void setTextColor(ColorStateList colorStateList) {
}
@SuppressLint("RestrictedApi")
public void setTitle(CharSequence title) {
this.mSmallLabel.setText(title);
this.mLargeLabel.setText(title);
}
@SuppressLint("RestrictedApi")
public boolean showsIcon() {
return true;
}
@@ -1,6 +1,8 @@
package ru.vtosters.lite.deviceinfo;
public class Device{
import androidx.annotation.NonNull;
public class Device {
private String androidId;
private String bluetoothMac;
private String boardName;
@@ -16,81 +18,82 @@ 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(){
@NonNull
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 + "'}";
}
}
@@ -1,5 +1,6 @@
package ru.vtosters.lite.deviceinfo;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.net.wifi.WifiInfo;
@@ -18,16 +19,17 @@ 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 {
@SuppressLint("PrivateApi")
Class<?> cls = Class.forName("android.os.SystemProperties");
Method method = cls.getMethod("get", String.class);
str = (String) method.invoke(cls, "gsm.sn1");
@@ -53,11 +55,12 @@ public class DeviceInfoCollector{
return null;
}
private String androidId(Context context){
@SuppressLint("HardwareIds")
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 +77,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 +91,7 @@ public class DeviceInfoCollector{
}
}
private String wifiMacFromNetworkInterfaces(){
private String wifiMacFromNetworkInterfaces() {
try {
for (NetworkInterface networkInterface : Collections.list(NetworkInterface.getNetworkInterfaces())) {
if ("wlan0".equalsIgnoreCase(networkInterface.getName())) {
@@ -99,7 +102,7 @@ public class DeviceInfoCollector{
StringBuilder sb = new StringBuilder();
int length = hardwareAddress.length;
for (int i = 0; i < length; i++) {
sb.append(String.format("%02X:", Byte.valueOf(hardwareAddress[i])));
sb.append(String.format("%02X:", hardwareAddress[i]));
}
if (sb.length() > 0) {
sb.deleteCharAt(sb.length() - 1);
@@ -114,7 +117,7 @@ public class DeviceInfoCollector{
}
}
private String wifiMacFromFileSystem(){
private String wifiMacFromFileSystem() {
try {
FileReader fileReader = new FileReader("/sys/class/net/wlan0/address");
try {
@@ -137,7 +140,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 +154,7 @@ public class DeviceInfoCollector{
return null;
}
private String bluetoothMacFromAdapter(){
private String bluetoothMacFromAdapter() {
try {
BluetoothAdapter defaultAdapter = BluetoothAdapter.getDefaultAdapter();
if (defaultAdapter == null) {
@@ -173,7 +176,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 +185,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);
@@ -1,75 +1,392 @@
package ru.vtosters.lite.dnr;
import static com.vk.im.engine.h.im_ic_done;
import static com.vk.im.engine.h.im_ic_edit_msg;
import static com.vk.im.engine.h.im_ic_more_vertical;
import static com.vk.im.engine.h.im_ic_pinned_msg_hide;
import static com.vk.im.engine.h.im_ic_pinned_msg_show;
import static com.vk.im.ui.c.im_ic_keyboard;
import static ru.vtosters.lite.dnr.DNRModule.hookDNR;
import static ru.vtosters.lite.dnr.DNRModule.hookDNT;
import static ru.vtosters.lite.dnr.DNRModule.isDnrEnabledFor;
import static ru.vtosters.lite.dnr.DNRModule.isDntEnabledFor;
import static ru.vtosters.lite.utils.Globals.getIdentifier;
import static ru.vtosters.lite.encryption.EncryptProvider.decryptMessage;
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.getString;
import static ru.vtosters.lite.utils.AndroidUtils.isTablet;
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
import com.vk.core.util.ToastUtils;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Environment;
import android.util.Log;
import com.vk.core.network.Network;
import com.vk.im.engine.ImEngine1;
import com.vk.im.engine.events.OnDialogUpdateEvent;
import com.vk.im.engine.models.EntityIntMap;
import com.vk.im.engine.models.dialogs.Dialog;
import com.vk.im.engine.models.messages.Msg;
import com.vk.im.engine.models.messages.MsgFromUser;
import com.vk.im.ui.components.common.DialogAction;
import com.vk.im.ui.components.common.MsgAction;
import com.vk.im.ui.components.viewcontrollers.popup.DelegateMsg;
import com.vk.im.ui.views.dialog_actions.DialogActionsListView;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
public class DNRInjector{
public static void inject(Dialog dialog, List<DialogAction> list){
int peerId = dialog.getId();
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import ru.vtosters.lite.downloaders.MessagesDownloader;
import ru.vtosters.lite.encryption.EncryptProvider;
import ru.vtosters.lite.encryption.base.IMProcessor;
import ru.vtosters.lite.hooks.CryptImHook;
import ru.vtosters.lite.ui.dialogs.Translate;
public class DNRInjector {
public static void inject(Dialog dialog, List<DialogAction> list) {
int peerId = 0;
if (dialog != null) {
try {
peerId = dialog.getId();
} catch (Exception e){
Log.d("DialoggetId", "null");
}
}
if (peerId == 0) {
return;
}
list.add(DialogAction.DOWNLOAD);
list.add(DialogAction.pinmsg);
list.add(DialogAction.unpinmsg);
if (isDnrEnabledFor(peerId)) {
list.add(DialogAction.valueOf("DNR_OFF"));
list.add(DialogAction.DNR_OFF);
} else {
list.add(DialogAction.valueOf("DNR_ON"));
list.add(DialogAction.DNR_ON);
}
if (isDntEnabledFor(peerId)) {
list.add(DialogAction.valueOf("DNT_OFF"));
list.add(DialogAction.DNT_OFF);
} else {
list.add(DialogAction.valueOf("DNT_ON"));
list.add(DialogAction.DNT_ON);
}
list.add(DialogAction.ENCRYPT);
IMProcessor prov = EncryptProvider.getProcessorFor(peerId);
if (prov != null && !prov.isPublic()) {
list.add(DialogAction.ENCRYPT_SETT);
}
}
public static LinkedHashMap<DialogAction, Integer> injectToHashMap(LinkedHashMap<DialogAction, Integer> hashMap){
hashMap.put(DialogAction.valueOf("DNR_ON"), getIdentifier("DNR_ON", "string"));
hashMap.put(DialogAction.valueOf("DNR_OFF"), getIdentifier("DNR_OFF", "string"));
hashMap.put(DialogAction.valueOf("DNT_ON"), getIdentifier("DNT_ON", "string"));
hashMap.put(DialogAction.valueOf("DNT_OFF"), getIdentifier("DNT_OFF", "string"));
public static LinkedHashMap<DialogAction, Integer> injectToHashMap(LinkedHashMap<DialogAction, Integer> hashMap) {
hashMap.put(DialogAction.DOWNLOAD, getIdentifier("download_dl", "string"));
hashMap.put(DialogAction.DNR_ON, getIdentifier("DNR_ON", "string"));
hashMap.put(DialogAction.DNR_OFF, getIdentifier("DNR_OFF", "string"));
hashMap.put(DialogAction.DNT_ON, getIdentifier("DNT_ON", "string"));
hashMap.put(DialogAction.DNT_OFF, getIdentifier("DNT_OFF", "string"));
hashMap.put(DialogAction.ENCRYPT, getIdentifier("encryption", "string"));
hashMap.put(DialogAction.ENCRYPT_SETT, getIdentifier("encryption_sett", "string"));
// hashMap.put(DialogAction.pinmsg, getIdentifier("pinmsg", "string"));
// hashMap.put(DialogAction.unpinmsg, getIdentifier("unpinmsg", "string"));
return hashMap;
}
public static boolean onClick(Dialog dialog, DialogAction action){
var id = dialog.getId();
@SuppressLint("ResourceType")
public static List<Object> injectToList(List<Object> actions) {
var list = new ArrayList<>(actions);
list.add(new DialogActionsListView.b.a(DialogAction.DOWNLOAD, 1, getIdentifier("im_ic_msgdl", "attr"), getIdentifier("download_dl", "string"))); // DialogAction, Int, Icon, String
if (action == DialogAction.valueOf("MARK_AS_READ")) {
list.add(new DialogActionsListView.b.a(DialogAction.DNR_ON, 2, im_ic_pinned_msg_hide, getIdentifier("DNR_ON", "string"))); // DialogAction, Int, Icon, String
list.add(new DialogActionsListView.b.a(DialogAction.DNR_OFF, 2, im_ic_pinned_msg_show, getIdentifier("DNR_OFF", "string"))); // DialogAction, Int, Icon, String
list.add(new DialogActionsListView.b.a(DialogAction.DNT_ON, 2, im_ic_edit_msg, getIdentifier("DNT_ON", "string"))); // DialogAction, Int, Icon, String
list.add(new DialogActionsListView.b.a(DialogAction.DNT_OFF, 2, im_ic_edit_msg, getIdentifier("DNT_OFF", "string"))); // DialogAction, Int, Icon, String
if (!isTablet()) {
list.add(new DialogActionsListView.b.a(DialogAction.ENCRYPT, 3, im_ic_keyboard, getIdentifier("encryption", "string"))); // DialogAction, Int, Icon, String
list.add(new DialogActionsListView.b.a(DialogAction.ENCRYPT_SETT, 3, im_ic_more_vertical, getIdentifier("encryption_sett", "string"))); // DialogAction, Int, Icon, String
}
list.add(new DialogActionsListView.b.a(DialogAction.MARK_AS_READ, 4, im_ic_done, getIdentifier("vkim_dialogs_list_option_mark_as_read", "string"))); // DialogAction, Int, Icon, String
return list;
}
public static void forceInvalidateDialogActions(Dialog d) {
EntityIntMap<Dialog> map = new EntityIntMap<>();
map.a(d.getId(), d);
ImEngine1.a().a(new OnDialogUpdateEvent(null, map));
}
public static List<DialogAction> injectToListAccess(List<DialogAction> actions, Dialog dialog) {
int peerId = 0;
if (dialog != null) {
try {
peerId = dialog.getId();
} catch (Exception e){
Log.d("DialoggetId", "null");
}
}
if (peerId == 0) {
return actions;
}
actions.add(DialogAction.DOWNLOAD);
if (isDnrEnabledFor(peerId)) {
actions.add(DialogAction.DNR_OFF);
} else {
actions.add(DialogAction.DNR_ON);
}
if (isDntEnabledFor(peerId)) {
actions.add(DialogAction.DNT_OFF);
} else {
actions.add(DialogAction.DNT_ON);
}
actions.add(DialogAction.ENCRYPT);
IMProcessor prov = EncryptProvider.getProcessorFor(peerId);
if (prov != null && !prov.isPublic()) {
actions.add(DialogAction.ENCRYPT_SETT);
}
actions.add(DialogAction.MARK_AS_READ);
return actions;
}
public static boolean onClickHeader(DialogAction action, Dialog dialog) {
int peerId = 0;
if (dialog != null) {
try {
peerId = dialog.getId();
} catch (Exception e){
Log.d("DialoggetId", "null");
}
}
if (peerId == 0) {
return true;
}
if (action == DialogAction.MARK_AS_READ) {
DNRModule.hookRead(dialog);
forceInvalidateDialogActions(dialog);
}
if (action == DialogAction.valueOf("DNR_ON")) {
if (action == DialogAction.DOWNLOAD) {
File out = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "dialog-" + peerId + ".html");
try {
new MessagesDownloader().downloadDialog(peerId, new MessagesDownloader.HtmlDialogDownloaderFormatProvider(), out);
} catch (Exception e) {
sendToast(getString("download_dl_error"));
e.printStackTrace();
}
return true;
}
if (action == DialogAction.DNR_ON) {
setDnr(dialog, true);
forceInvalidateDialogActions(dialog);
return true;
} else if (action == DialogAction.valueOf("DNR_OFF")) {
} else if (action == DialogAction.DNR_OFF) {
setDnr(dialog, false);
forceInvalidateDialogActions(dialog);
return true;
}
if (action == DialogAction.valueOf("DNT_ON")) {
if (action == DialogAction.DNT_ON) {
setDnt(dialog, true);
forceInvalidateDialogActions(dialog);
return true;
} else if (action == DialogAction.valueOf("DNT_OFF")) {
} else if (action == DialogAction.DNT_OFF) {
setDnt(dialog, false);
forceInvalidateDialogActions(dialog);
return true;
}
if (action == DialogAction.ENCRYPT_SETT) {
CryptImHook.hookPref(peerId);
return true;
} else if (action == DialogAction.ENCRYPT) {
CryptImHook.hook(peerId, dialog);
return true;
}
return false;
}
public static void setDnr(Dialog dialog, boolean value){
hookDNR(dialog.getId());
public static boolean onClick(Dialog dialog, DialogAction action) {
int peerId = 0;
if (dialog != null) {
try {
peerId = dialog.getId();
} catch (Exception e){
Log.d("DialoggetId", "null");
}
}
if (peerId == 0) {
return true;
}
if (action == DialogAction.MARK_AS_READ) {
DNRModule.hookRead(dialog);
}
if (action == DialogAction.DOWNLOAD) {
File out = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), peerId + "-dialog.html");
try {
new MessagesDownloader().downloadDialog(peerId, new MessagesDownloader.HtmlDialogDownloaderFormatProvider(), out);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
if (action == DialogAction.DNR_ON) {
setDnr(dialog, true);
return true;
} else if (action == DialogAction.DNR_OFF) {
setDnr(dialog, false);
return true;
}
if (action == DialogAction.DNT_ON) {
setDnt(dialog, true);
return true;
} else if (action == DialogAction.DNT_OFF) {
setDnt(dialog, false);
return true;
}
if (action == DialogAction.pinmsg) {
pinnedMsg(peerId, true);
return true;
} else if (action == DialogAction.unpinmsg) {
pinnedMsg(peerId, false);
return true;
}
if (action == DialogAction.ENCRYPT_SETT) {
CryptImHook.hookPref(peerId);
return true;
} else if (action == DialogAction.ENCRYPT) {
CryptImHook.hook(peerId, dialog);
return true;
}
return false;
}
public static void setDnt(Dialog dialog, boolean value){
hookDNT(dialog.getId());
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 peerId = msg.v1();
if (action == MsgAction.valueOf("READTO")) {
DNRModule.hookReadStartMsgTo(msg);
return true;
}
if (msg instanceof MsgFromUser){
var text = ((MsgFromUser) msg).f();
var fullMsg = ((MsgFromUser) msg).j2(); // text + reply
var reply = fullMsg.substring(text.length() + 1);
var isTextExist = !text.isEmpty() && !text.equals(" ");
var isReplyExist = !reply.isEmpty() && !reply.equals(" ");
if (isReplyExist) {
reply = decryptMessage(reply, peerId);
}
if (isTextExist) {
text = decryptMessage(text, peerId);
}
if (action == MsgAction.valueOf("TRANSLATE")) {
if (isTextExist && isReplyExist) {
Translate.showTranslatedText(context, text + "\n\n" + getString("translator_reply") + "\n" + reply);
} else if (isReplyExist) {
Translate.showTranslatedText(context, getString("translator_reply") + "\n" + reply);
} else if (isTextExist) {
Translate.showTranslatedText(context, text);
} else {
sendToast(getString("translator_no_text"));
}
}
}
return false;
}
public static void pinnedMsg(int dialogid, boolean needToBePinned) {
Thread thread = new Thread(() -> {
try {
var request = new Request.a()
.b("https://" + getApi() + "/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(getString("pin_dialog") + " " + getString(needToBePinned ? "dialog_pinned" : "dialog_unpinned"));
}
public static void setDnr(Dialog dialog, boolean value) {
int peerId = 0;
if (dialog != null) {
peerId = dialog.getId();
}
hookDNR(peerId);
}
public static void setDnt(Dialog dialog, boolean value) {
int peerId = 0;
if (dialog != null) {
peerId = dialog.getId();
}
hookDNT(peerId);
}
}
@@ -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.proxy.ProxyUtils.getApi;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
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);
@@ -15,36 +15,56 @@ import ru.vtosters.lite.downloaders.notifications.NotificationChannels;
import ru.vtosters.lite.music.Callback;
import ru.vtosters.lite.music.FFMpeg;
import ru.vtosters.lite.music.M3UDownloader;
import ru.vtosters.lite.utils.Globals;
import ru.vtosters.lite.music.MP3Downloader;
import ru.vtosters.lite.utils.AndroidUtils;
public class AudioDownloader{
private static NotificationManagerCompat notificationManager = NotificationManagerCompat.from(Globals.getContext());
public class AudioDownloader {
private static NotificationManagerCompat notificationManager = NotificationManagerCompat.from(AndroidUtils.getGlobalContext());
public static void downloadAudio(MusicTrack track){
public static void downloadAudio(MusicTrack track) {
if (AndroidUtils.getDefaultPrefs().getBoolean("new_music_downloading_way", false)) {
downloadMP3(track);
} else {
downloadM3U8(track);
}
}
public static void downloadM3U8(MusicTrack track) {
if (track.D == null) {
ToastUtils.a("Не удалось найти ссылку на аудиозапись");
ToastUtils.a(AndroidUtils.getString("link_audio_error"));
return;
}
var musicPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath();
var musicDir = new File(musicPath);
if (!musicDir.exists()) {
if (musicDir.mkdirs()) {
Log.d("AudioDownloader", "Created music dir");
} else {
Log.e("AudioDownloader", "Failed to create music dir");
return;
}
}
var tempId = track.d;
var downloadPath = musicPath + File.separator + tempId;
var notification = buildDownloadNotification(track, tempId);
downloadM3U8(track, downloadPath, new Callback(){
var notification = buildDownloadNotification(track, tempId);
downloadM3U8(track, downloadPath, new Callback() {
@Override
public void onProgress(int progress){
public void onProgress(int progress) {
notification.setProgress(100, progress, false);
notificationManager.notify(tempId, notification.build());
}
@Override
public void onSuccess(){
public void onSuccess() {
try {
var fileName = track.toString();
var success = FFMpeg.convert(downloadPath, musicPath + File.separator + fileName + ".mp3");
if (success) {
notification
.setContentText("Загрузка завершена")
.setContentText(AndroidUtils.getString("player_download_finished"))
.setProgress(0, 0, false)
.setSmallIcon(android.R.drawable.stat_sys_download_done);
notificationManager.notify(tempId, notification.build());
@@ -52,26 +72,26 @@ public class AudioDownloader{
onFailure();
}
} catch (UnsatisfiedLinkError e) {
Log.e("AudioDownloader", "Опять эти нативные либы");
Log.e("AudioDownloader", "native libs");
Log.e("AudioDownloader", e.getMessage());
onFailure();
}
}
@Override
public void onFailure(){
notification.setContentText("Не удалось загрузить аудиозапись").setProgress(0, 0, false);
public void onFailure() {
notification.setContentText(AndroidUtils.getString("load_audio_error")).setProgress(0, 0, false);
notificationManager.notify(tempId, notification.build());
}
@Override
public void onSizeReceived(long size, long header){
public void onSizeReceived(long size, long header) {
}
});
}
private static void downloadM3U8(MusicTrack track, String path, Callback callback){
private static void downloadM3U8(MusicTrack track, String path, Callback callback) {
File outDir = new File(path);
if (!outDir.exists())
if (outDir.mkdir())
@@ -79,13 +99,17 @@ 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 NotificationCompat.Builder buildDownloadNotification(MusicTrack track, int id){
var notificationBuilder = new NotificationCompat.Builder(Globals.getContext(), NotificationChannels.MUSIC_DOWNLOAD_CHANNEL_ID)
private static void downloadMP3(MusicTrack track) {
MP3Downloader.execute(track);
}
private static NotificationCompat.Builder buildDownloadNotification(MusicTrack track, int id) {
var notificationBuilder = new NotificationCompat.Builder(AndroidUtils.getGlobalContext(), NotificationChannels.MUSIC_DOWNLOAD_CHANNEL_ID)
.setSmallIcon(android.R.drawable.stat_sys_download)
.setContentTitle("Загрузка аудиозаписи")
.setContentTitle(AndroidUtils.getString("audio_downloading"))
.setContentText(track.toString())
.setPriority(NotificationCompat.PRIORITY_LOW)
.setCategory(NotificationCompat.CATEGORY_PROGRESS)
@@ -0,0 +1,604 @@
package ru.vtosters.lite.downloaders;
import static ru.vtosters.lite.encryption.EncryptProvider.decryptMessage;
import static ru.vtosters.lite.net.Request.makeRequest;
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserId;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getResources;
import android.util.SparseArray;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
public class MessagesDownloader{
private static SimpleDateFormat sdformat;
private static SparseArray<MiniUser> usersArray;
private static final String VK_DOMAIN = "vk.com";
public static String formatTime(long now){
return sdformat.format(new Date(now));
}
public static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements){
Objects.requireNonNull(delimiter);
Objects.requireNonNull(elements);
StringBuilder builder = new StringBuilder();
for (CharSequence cs : elements) {
builder.append(cs).append(delimiter);
}
return builder.toString();
}
public void downloadDialog(int peer_id, DialogDownloaderFormatProvider format, File out) throws Exception{
sdformat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss", getResources().getConfiguration().locale);
FileOutputStream fos = new FileOutputStream(out);
// fix TODO with conversation name (API method messages.getConversationsById)
fos.write(format.provideDocumentStart("TODO", formatTime(System.currentTimeMillis())).getBytes(StandardCharsets.UTF_8));
fetchDialogInfo(peer_id, 0, ((users, messages) -> {
try {
fos.write(format.provideHeader("TODO", formatTime(System.currentTimeMillis())).getBytes(StandardCharsets.UTF_8));
for (MiniMsg msg : messages) {
fos.write(format.provideMessage(msg, users.get(msg.fromId)).getBytes(StandardCharsets.UTF_8));
}
fos.write(format.provideDocumentEnd().getBytes(StandardCharsets.UTF_8));
fos.close();
Toast.makeText(getGlobalContext(), "Сохранено как " + out.getAbsolutePath(), Toast.LENGTH_SHORT).show();
} catch (IOException | JSONException e) {
e.printStackTrace();
}
}));
}
public void fetchDialogInfo(int peer_id, int offset, FetchListener fl){
makeRequest("https://" + getApi() + "/method/messages.getHistory?extended=1&v=5.140&offset=" + offset + "&count=200&peer_id=" + peer_id + "&access_token=" + getUserToken(),
response -> {
try {
JSONObject mainJson = new JSONObject(response);
JSONObject obj = mainJson.getJSONObject("response");
SparseArray<MiniUser> users = new SparseArray<>();
parseUsers(users, obj.optJSONArray("profiles"), false);
parseUsers(users, obj.optJSONArray("groups"), true);
List<MiniMsg> msgs = parseMessages(obj.getJSONArray("items"));
usersArray = users;
fl.onReceive(users, msgs);
} catch (JSONException e) {
e.printStackTrace();
}
});
}
private List<MiniMsg> parseMessages(JSONArray jsonArray) throws JSONException{
ArrayList<MiniMsg> thing = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
MiniMsg msg = new MiniMsg(jsonArray.getJSONObject(i));
thing.add(msg);
}
return thing;
}
private void parseUsers(SparseArray<MiniUser> array, @Nullable JSONArray jsonArray, boolean groups) throws JSONException{
if (jsonArray == null) return;
for (int i = 0; i < jsonArray.length(); i++) {
MiniUser user = new MiniUser(jsonArray.getJSONObject(i), groups);
array.put(groups ? -user.id : user.id, user);
}
}
interface FetchListener{
void onReceive(SparseArray<MiniUser> users, List<MiniMsg> messages);
}
static class MiniUser{
public String firstName;
public String lastName;
public boolean isGroup;
int id;
String photo100;
public MiniUser(JSONObject obj, boolean is_group) throws JSONException {
id = obj.getInt("id");
firstName = obj.optString("first_name", obj.optString("name"));
lastName = obj.optString("last_name", "");
photo100 = obj.getString("photo_100");
isGroup = is_group;
}
}
static class MiniMsg{
long date;
int fromId;
int id; // message id
String text;
List<JSONObject> attachments;
List<JSONObject> fwd_messages;
JSONObject reply_message; // one reply
JSONObject chat_action;
JSONObject geo;
public MiniMsg(JSONObject obj) throws JSONException{
date = obj.getLong("date") * 1000;
fromId = obj.getInt("from_id");
id = obj.getInt("id");
text = decryptMessage(obj.getString("text"), obj.getInt("peer_id"));
reply_message = obj.optJSONObject("reply_message");
chat_action = obj.optJSONObject("action");
geo = obj.optJSONObject("geo");
attachments = new ArrayList<>();
fwd_messages = new ArrayList<>();
JSONArray arr = obj.optJSONArray("attachments");
if (arr != null)
for (int i = 0; i < arr.length(); i++) attachments.add(arr.getJSONObject(i));
JSONArray fwdArr = obj.optJSONArray("fwd_messages");
if (fwdArr != null)
for (int i = 0; i < fwdArr.length(); i++) fwd_messages.add(fwdArr.getJSONObject(i));
}
}
// This class defines everything which is needed to create an output file
abstract static class DialogDownloaderFormatProvider{
// Internal, for JSON/HTML
abstract String provideDocumentStart(String dialogName, String date);
abstract String provideDocumentEnd();
abstract String provideHeader(String dialogName, String date);
abstract String provideMessage(MiniMsg message, MiniUser user) throws JSONException;
}
public static class HtmlDialogDownloaderFormatProvider extends DialogDownloaderFormatProvider{
@Override
String provideDocumentStart(String dialogName, String date){
String style = ".vtex-milk-msg {\n" +
" border-radius: 8px;\n" +
" padding: 24px;\n" +
" background: white;\n" +
" margin: 16px;\n" +
" box-shadow: 0 4px 8px 0 rgba(0,0,0,0.07);\n" +
" word-wrap: break-word;\n" +
"}\n" +
"\n" +
".vtex-milk-msgcont br {\n" +
" display: none;\n" +
"}\n" +
"\n" +
".vtex-milk-msg p {\n" +
" margin: 0;\n" +
"}\n" +
"\n" +
".vtex-milk-msg.vtex-milk-msg-out {\n" +
" background: #ADD3FF;\n" +
"}\n" +
"\n" +
"p.msg-attaches {\n" +
" margin-top: 8px;\n" +
" font-style: italic;\n" +
"}\n" +
"p.chat-action {\n" +
" font-style: italic;\n" +
"}\n" +
"\n" +
".vtex-milk-header {\n" +
" border-radius: 8px;\n" +
" padding: 24px;\n" +
" background: white;\n" +
" margin: 16px;\n" +
" box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);\n" +
"}\n" +
"\n" +
"h4.vtex-milk-header-txt {\n" +
" margin: 0;\n" +
"}\n" +
"\n" +
"h5.vtex-milk-header-sub {\n" +
" margin: 0;\n" +
" padding-top: 8px;\n" +
"}\n" +
"\n" +
"a.msg-attach-link {\n" +
" color: #5181B8;\n" +
" text-decoration: none;\n" +
"}\n" +
"\n" +
".msg-from a {\n" +
" color: #5181B8;\n" +
" text-decoration: none;\n" +
"}\n" +
"\n" +
".msg-from-date {\n" +
" color: rgba(0, 0, 0, 0.75);\n" +
"}\n" +
"\n" +
"body {\n" +
" font-family: Roboto, system-ui, sans-serif;\n" +
"}\n" +
"\n" +
".msg-body {\n" +
" padding-top: 4px;\n" +
"}\n" +
".msg-reply {\n" +
" border-left: 3px solid #7aa7f6;\n" +
" margin-top: 5px;\n" +
" padding-left: 3px;\n" +
"}\n\n" +
".msg-reply p {\n" +
" padding-left: 5px;\n" +
"}\n\n" +
".msg-reply p.reply-header {\n" +
" color: #5181B8;\n" +
"}\n\n" +
".msg-reply p.reply-content {\n" +
" color: #000000;\n" +
"}\n" +
".vtex-milk-msg.poll {\n" +
" width: 45%;\n" +
" background: linear-gradient(to bottom right, #707c8c, #4d5565);\n" +
" font-style: normal;" +
"}\n" +
".vtex-milk-msg.poll p { color: white; }\n" +
".vtex-milk-msg.poll hr { border-top: 1px; background: #ffffff; }\n" +
"\n" +
"";
return "<html><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><meta charset=\"utf-8\"><title>Экспорт из VTLite</title><style>" + style + "</style></head><body>";
}
@Override
String provideDocumentEnd(){
return "</div></body></html>";
}
@Override
String provideHeader(String dialogName, String date){
return "<div class=\"vtex-milk-header\"><h4 class=\"vtex-milk-header-txt\">VTLite</h4><h5 class=\"vtex-milk-header-sub\">Экспорт истории чата (" + date + ")</h5></div><div class=\"vtex-milk-msgcont\">";
}
@Override
String provideMessage(MiniMsg message, MiniUser user) throws JSONException{
String isOut = (user.id == getUserId()) ? " vtex-milk-msg-out" : "";
String geoPosition = "";
if (message.geo != null) {
var coordinates = message.geo.optJSONObject("coordinates");
if (coordinates != null) {
var latitude = coordinates.optDouble("latitude");
var longitude = coordinates.optDouble("longitude");
var ll = longitude + "," + latitude;
geoPosition = "<a href=\"https://yandex.ru/maps/?ll=" + ll + "&mode=search&sll=" + ll + "&text=" + latitude + "," + longitude + "&z=12\">" +
"<img src=\"https://static-maps.yandex.ru/1.x/?ll=" + longitude + "," + latitude + "&z=12&l=map&size=300,200&pt=" + ll + ",vkgrm\"/>" +
"</a>";
}
}
String chatAction = (message.chat_action != null) ? getHtmlForChatAction(message.chat_action) : "";
String attaches = (message.attachments.size() > 0) ? "<p class=\"msg-attaches\">Вложения: " + getHtmlForAttach(message.attachments) + "</p>" : "";
String reply = (message.reply_message != null) ? provideReply(message.reply_message) : "";
String fwdMessages = (message.fwd_messages.size() > 0) ? provideForwardMessages(message.fwd_messages) : "";
String userLink = (user.isGroup ? "club" : "id") + user.id;
return "<div class=\"vtex-milk-msg" + isOut + "\" id=\"" + message.id + "\">" +
"<p class=\"msg-from\">от <a href=\"https://" + VK_DOMAIN + "/" + userLink + "\">" + user.firstName + " " + user.lastName + "</a> <span class=\"msg-from-date\">" + formatTime(message.date) + "</span></p>" + // TODO photo100
"<p class=\"msg-body\">" + mentionsReplace(message.text) + "</p>" +
geoPosition +
chatAction +
attaches +
reply +
fwdMessages +
"</div>";
}
private String provideReply(JSONObject replyMessage) {
var messageId = replyMessage.optInt("id");
var userId = replyMessage.optInt("from_id");
var peerId = replyMessage.optInt("peer_id");
var text = mentionsReplace(decryptMessage(replyMessage.optString("text"), peerId));
var fwdMessages = replyMessage.optJSONArray("fwd_messages");
var user = usersArray.get(userId);
if (text.isEmpty()) {
if (fwdMessages != null) {
var length = fwdMessages.length();
if (length > 0) text = length + " " + pluralMsg(length);
} else text = "Вложение";
}
return "<a href=\"#" + messageId + "\" class=\"msg-attach-link\">" +
"<div class=\"msg-reply\">" +
"<p class=\"reply-header\">Пересланное сообщение</p>" +
"<p class=\"reply-content\">" + user.firstName + " " + user.lastName + ": " + text + "</p>" +
"</div>" +
"</a>";
}
private String provideForwardMessages(List<JSONObject> fwd_messages) throws JSONException {
StringBuilder fwdmsgs = new StringBuilder("<div class=\"msg-reply\">");
for (JSONObject fwd_message : fwd_messages) {
if (fwd_message == null) continue;
List<JSONObject> attaches = new ArrayList<>();
JSONArray arr = fwd_message.optJSONArray("attachments");
if (arr != null) {
for (int i = 0; i < arr.length(); i++) {
try {
attaches.add(arr.getJSONObject(i));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
List<JSONObject> fwdsMsg = new ArrayList<>();
JSONArray fwd_msgs = fwd_message.optJSONArray("fwd_messages");
if (fwd_msgs != null) {
for (int i = 0; i < fwd_msgs.length(); i++) {
try {
fwdsMsg.add(fwd_msgs.getJSONObject(i));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
JSONObject reply_message = fwd_message.optJSONObject("reply_message");
var attachesHtml = (attaches.size() > 0) ? "Вложения: " + getHtmlForAttach(attaches) : "";
var replyHtml = (reply_message != null) ? provideReply(reply_message) : "";
var fwdsHtml = (fwdsMsg.size() > 0) ? provideForwardMessages(fwdsMsg) : ""; // recursion XD :>
var userId = fwd_message.optInt("from_id");
var peerId = fwd_message.optInt("peer_id");
var text = mentionsReplace(decryptMessage(fwd_message.optString("text"), peerId));
var userLink = ((userId < 0) ? "club" : "id") + Math.abs(userId);
fwdmsgs.append("<p class=\"reply-content\"><a class=\"msg-attach-link\" href=\"https://" + VK_DOMAIN + "/").append(userLink).append("\">@").append(userLink).append("</a>: ").append(text).append(attachesHtml).append(replyHtml).append(fwdsHtml);
}
return fwdmsgs.append("</div>").toString();
}
private String mentionsReplace(String text) {
var matcher = Pattern.compile("\\[((?:club|id|public)\\d+)\\|([^]]+)\\]").matcher(text);
return matcher.replaceAll("<a class=\"msg-attach-link\" href=\"https://" + VK_DOMAIN + "/$1\">$2</a>");
}
private String pluralMsg(int count) {
String[] plurals = {"сообщение", "сообщения", "сообщений"};
var hundredModulo = count % 100;
var tenModulo = count % 10;
if (hundredModulo > 10 && hundredModulo < 20) return plurals[2];
else if (tenModulo > 1 && tenModulo < 5) return plurals[1];
else if (tenModulo == 1) return plurals[0];
return plurals[2];
}
private String getHtmlForChatAction(JSONObject action) {
var type = action.optString("type");
StringBuilder htmlAction = new StringBuilder("<p class=\"chat-action\">");
switch(type) {
case "chat_photo_update":
htmlAction.append("Обновил фотографию беседы");
break;
case "chat_photo_remove":
htmlAction.append("Удалил фотографию беседы");
break;
case "chat_create":
var name = action.optString("text");
htmlAction.append("Создал беседу").append((!name.isEmpty()) ? " с названием \"" + name + "\"" : "");
break;
case "chat_title_update":
var newName = action.optString("text");
htmlAction.append("Сменил название беседы").append((!newName.isEmpty()) ? " на \"" + newName : "\"");
break;
case "chat_invite_user":
var newUserId = action.optInt("member_id");
htmlAction.append("Добавил ").append((newUserId > 0) ? "пользователя" : "группу");
if (newUserId != 0) {
var userLink = ((newUserId < 0) ? "club" : "id") + Math.abs(newUserId);
htmlAction.append(" <a href=\"https://" + VK_DOMAIN + "/").append(userLink).append("\" class=\"msg-attach-link\">@").append(userLink).append("</a>");
}
break;
case "chat_kick_user":
var removedUserId = action.optInt("member_id");
htmlAction.append("Исключил ").append((removedUserId > 0) ? "пользователя" : "группу");
if (removedUserId != 0) {
var userLink = ((removedUserId < 0) ? "club" : "id") + Math.abs(removedUserId);
htmlAction.append(" <a href=\"https://" + VK_DOMAIN + "/").append(userLink).append("\" class=\"msg-attach-link\">@").append(userLink).append("</a>");
}
break;
case "chat_pin_message":
var message = action.optString("message");
htmlAction.append("Закрепил сообщение").append((!message.isEmpty()) ? (" с текстом: \"" + message + "\"") : "");
break;
case "chat_unpin_message":
htmlAction.append("Открепил сообщение");
break;
case "chat_invite_user_by_link":
htmlAction.append("Вступил в беседу по ссылке");
break;
case "chat_screenshot":
htmlAction.append("Сделал скриншот беседы");
break;
case "custom":
htmlAction.append(action.optString("message"));
break;
default:
htmlAction.append("Действие не поддерживается (").append(type).append(")");
break;
}
return htmlAction.append("</p>").toString();
}
private String getHtmlForAttach(List<JSONObject> attaches) throws JSONException{
StringBuilder rs = new StringBuilder();
for (JSONObject attach : attaches) {
String type = attach.getString("type");
JSONObject item = attach.optJSONObject(type);
if (item == null) continue;
switch(type) { // market_album is not supported
case "photo":
var sizes = item.getJSONArray("sizes");
rs.append("<a href=\"").append(sizes.getJSONObject(sizes.length() - 1).getString("url")).append("\" class=\"msg-attach-link\">фотография</a>");
break;
case "doc":
rs.append("<a href=\"").append(item.getString("url")).append("\" class=\"msg-attach-link\">документ</a>");
break;
case "link":
rs.append("<a href=\"").append(item.getString("url")).append("\" class=\"msg-attach-link\">ссылка</a>");
break;
case "wall":
rs.append("<a href=\"https://" + VK_DOMAIN + "/wall").append(item.optString("to_id", item.optString("owner_id"))).append("_").append(item.getString("id")).append("\" class=\"msg-attach-link\">запись на стене</a>");
break;
case "sticker":
rs.append("<img style=\"width:128px;height:128px;\" src=\"").append(item.getJSONArray("images").getJSONObject(1).getString("url")).append("\"/>");
break;
case "audio_message":
rs.append("<a href=\"").append(item.optString("link_mp3")).append("\" class=\"msg-attach-link\">голосовое сообщение</a>");
break;
case "audio":
rs.append("аудиозапись (").append(item.optString("artist")).append(" — ").append(item.optString("title")).append(")");
break;
case "video":
rs.append("видеозапись ( ").append(getVideoHtml(item.optJSONObject("files"))).append(")");
break;
case "wall_reply":
var link = "https://" + VK_DOMAIN + "/wall" + item.optString("owner_id") + "_" + item.optString("post_id") + "?reply=" + item.optString("id");
rs.append("<a class=\"msg-attach-link\" href=\"").append(link).append("\">комментарий на стене</a>");
break;
case "story":
var story_link = "https://" + VK_DOMAIN + "/story" + item.optString("owner_id") + "_" + item.optString("id");
rs.append("<a class=\"msg-attach-link\" href=\"").append(story_link).append("\">история</a>");
break;
case "podcast":
var podcast_link = "https://" + VK_DOMAIN + "/podcast" + item.optString("owner_id") + "_" + item.optString("id");
rs.append("<a class=\"msg-attach-link\" href=\"").append(podcast_link).append("\">подкаст</a>");
break;
case "gift":
rs.append("<img src=\"").append(item.optString("thumb_96")).append("\"/>");
break;
case "mini_app":
var app = item.optJSONObject("app");
if (app != null) {
var miniapp_link = "https://" + VK_DOMAIN + "/app" + app.optString("id");
rs.append("<a class=\"msg-attach-link\" href=\"").append(miniapp_link).append("\">мини-приложение</a>");
break;
}
rs.append("ошибка");
break;
case "audio_playlist":
var playlist_link = "https://" + VK_DOMAIN + "/music/album/" + item.optString("owner_id") + "_" + item.optString("id") + "_" + item.optString("access_key");
rs.append("<a class=\"msg-attach-link\" href=\"").append(playlist_link).append("\">плейлист (").append(item.optString("title")).append(")</a>");
break;
case "poll":
rs.append((item.optBoolean("anonymous") ? "анонимный" : "публичный")).append(" опрос ").append(getPollHtml(item));
break;
case "market":
var market_item_link = "https://" + VK_DOMAIN + "/market" + item.optString("owner_id") + "_" + item.optString("id");
rs.append("<a class=\"msg-attach-link\" href=\"").append(market_item_link).append("\">товар</a>");
break;
default:
rs.append("не поддерживается (").append(type).append(")");
break;
}
rs.append(" ");
}
return rs.toString();
}
}
private static String getPollHtml(JSONObject poll) throws JSONException {
StringBuilder pollHtml = new StringBuilder(
"<div class=\"vtex-milk-msg poll\">" +
"<p style=\"text-align:center;\">" + poll.optString("question") + "</p>"
);
var answers = poll.optJSONArray("answers");
for (int i = 0; i < answers.length(); i++) {
var jsonObject = answers.optJSONObject(i);
if (jsonObject != null)
pollHtml.append("<hr><p>").append(jsonObject.optString("text")).append(" · ").append(jsonObject.optString("votes")).append(" (").append(jsonObject.optString("rate")).append("%)</p>");
}
pollHtml.append("<hr><p style=\"text-align:center;\">Проголосовало ").append(poll.optString("votes")).append(" чел.</p>");
return pollHtml.append("</div>").toString();
}
private static String getVideoHtml(JSONObject files) throws JSONException {
if (files == null) return "ссылки отсутствуют";
Iterator< ? > keys = files.keys();
StringBuilder videoHtml = new StringBuilder();
int qualityIndex = 0;
String[] quality = {"144", "240", "360", "480", "720", "1080", "1440", "2160"};
while (keys.hasNext()) {
String key = (String) keys.next();
if (key.equals("mp4_" + quality[qualityIndex])) {
videoHtml.append("<a class=\"msg-attach-link\" href=\"").append(files.get(key)).append("\">").append(quality[qualityIndex]).append("p</a>").append(" ");
if (qualityIndex == quality.length - 1) break;
++qualityIndex;
}
}
return videoHtml.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;
@@ -11,17 +11,19 @@ import android.content.IntentFilter;
import android.net.Uri;
import android.os.Environment;
import com.vk.core.dialogs.alert.VkAlertDialog;
import java.io.File;
import b.h.g.m.FileUtils;
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 +31,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));
@@ -46,26 +48,41 @@ public class OTADownloader{
maxIndex = Math.max(maxIndex, Integer.parseInt(name.replaceFirst(".+-(\\d+).+", "$1")));
}
File apk = maxIndex == -1 ? new File(downloadDir, "VTLite.apk") : new File(downloadDir, "VTLite-" + maxIndex + ".apk");
APKInstallActivity.installOta(context, FileUtils.n(apk));
APKInstallActivity.installOta(context, FileUtils.uriFromFile(apk));
} else if (status == DownloadManager.STATUS_FAILED) {
Globals.sendToast(getString("downloaderr"));
AndroidUtils.sendToast(getString("downloaderr"));
}
}
}
};
public static void downloadBuild(String url){
var context = Globals.getContext();
var uri = Uri.parse(url);
public static void downloadBuild(String url) {
var context = AndroidUtils.getGlobalContext();
try {
var uri = Uri.parse(url);
context.registerReceiver(callback, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
context.registerReceiver(callback, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
var request = new DownloadManager.Request(uri);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle("VTLite.apk");
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "VTLite.apk");
var request = new DownloadManager.Request(uri);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle("VTLite.apk");
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "VTLite.apk");
var manager = (DownloadManager) Globals.getContext().getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
var manager = (DownloadManager) AndroidUtils.getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
} catch (Exception e) {
e.printStackTrace();
VkAlertDialog.Builder alertDialog = new VkAlertDialog.Builder(context);
alertDialog.setTitle(AndroidUtils.getString("update_error"));
alertDialog.setMessage(AndroidUtils.getString("update_error_text"));
alertDialog.setPositiveButton(AndroidUtils.getString("no"), (dialog, which) -> {
dialog.cancel();
});
alertDialog.setNeutralButton(AndroidUtils.getString("yes"), (dialog, which) -> {
context.startActivity(new Intent("android.intent.action.VIEW").setData(Uri.parse("https://github.com/vtosters/lite/releases/latest/download/VTLite.apk")));
});
var alert = alertDialog.create();
alert.show();
}
}
}
@@ -1,6 +1,7 @@
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 android.app.DownloadManager;
import android.content.Context;
@@ -12,8 +13,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()) {
@@ -21,9 +22,10 @@ public class StoryDownloader{
String url = imageSizes.get(imageSizes.size() - 1).url;
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.setTitle("photo" + story.E.a + ".jpg");
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_PICTURES, "photo" + story.E.a + ".jpg");
request.allowScanningByMediaScanner();
((DownloadManager) getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
return;
}
@@ -1,12 +1,12 @@
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.proxy.ProxyUtils.getApi;
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 android.app.AlertDialog;
import android.app.DownloadManager;
import android.app.ProgressDialog;
import android.content.Context;
@@ -14,6 +14,7 @@ import android.net.Uri;
import android.os.Environment;
import android.widget.Toast;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vk.core.dialogs.bottomsheet.MenuBottomSheetAction;
import com.vk.core.util.ToastUtils;
import com.vk.dto.common.VideoFile;
@@ -27,23 +28,24 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import ru.vtosters.lite.utils.ExternalLinkHandler;
import ru.vtosters.lite.utils.AndroidUtils;
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 +56,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,31 +106,33 @@ 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.allowScanningByMediaScanner();
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_MOVIES, videoFile + ".mp4");
((DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
((DownloadManager) getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
return;
}
var builder = new AlertDialog.Builder(context);
var builder = new VkAlertDialog.Builder(context);
builder.setItems(max, ((dialog, which) -> {
var url = urls.get(which);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle(videoFile.toString());
request.allowScanningByMediaScanner();
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_MOVIES, videoFile + ".mp4");
((DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
}));
builder.show();
}
public static void parseVideoLink(String url, Context ctx){
if (url.contains("vk.com/story")) {
ToastUtils.a("Не поддерживается загрузка историй");
public static void parseVideoLink(String url, Context ctx) {
if (url.contains("vk.com/story") || url.contains("vk.com/story")) {
ToastUtils.a(AndroidUtils.getString("video_dl_stories_not_supported"));
return;
}
if (!url.contains("vk.com/video")) {
ToastUtils.a("Неверная ссылка");
if (!url.contains("vk.com/video") || !url.contains("vk.com/video")) {
ToastUtils.a(AndroidUtils.getString("video_dl_wrong_link"));
return;
}
@@ -136,10 +140,10 @@ public class VideoDownloader{
String ownerId = videoId.split("_")[0];
final ProgressDialog progressDialog = new ProgressDialog(ctx);
progressDialog.setMessage("Обработка видео");
progressDialog.setMessage(AndroidUtils.getString("video_dl_progress"));
progressDialog.show();
makeRequest("https://" + "api.vk.com" + "/method/video.get?owner_id=" + ownerId + "&videos=" + videoId + "&v=5.99&access_token=" + getUserToken(),
makeRequest("https://" + getApi() + "/method/video.get?owner_id=" + ownerId + "&videos=" + videoId + "&v=5.99&access_token=" + getUserToken(),
response -> {
progressDialog.cancel();
@@ -152,7 +156,7 @@ public class VideoDownloader{
downloadVideo(videoFile, ctx);
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(ctx, "Видео нельзя скачать", Toast.LENGTH_SHORT).show();
Toast.makeText(ctx, AndroidUtils.getString("video_dl_error"), Toast.LENGTH_SHORT).show();
}
});
}
@@ -8,12 +8,12 @@ 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";
public static final String MUSIC_DOWNLOAD_CHANNEL_NAME = "Загрузка музыки";
public static final String MUSIC_DOWNLOAD_CHANNEL_DESCRIPTION = "Прогресс загрузки музыки";
public static final String MUSIC_DOWNLOAD_CHANNEL_NAME = AndroidUtils.getString("music_dl_title");
public static final String MUSIC_DOWNLOAD_CHANNEL_DESCRIPTION = AndroidUtils.getString("music_dl_progress");
@RequiresApi(api = Build.VERSION_CODES.O)
public static void createChannels() {
@@ -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);
}
}
@@ -1,10 +1,14 @@
package ru.vtosters.lite.encryption;
import static ru.vtosters.lite.hooks.MessagesHook.injectOwnText;
import static ru.vtosters.lite.hooks.MessagesHook.injectOwnTextAll;
import android.util.Log;
import android.util.Pair;
import com.vk.im.engine.models.messages.Msg;
import com.vk.im.engine.models.messages.MsgFromUser;
import com.vk.im.ui.components.msg_list.MsgListComponent;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -19,10 +23,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 +35,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,32 +45,75 @@ 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();
}
// For message editing
public static String decryptMessage(MsgFromUser msg, boolean showEmoji) {
var decryptedMessage = decryptMessage(getBody(msg), getPeerId(msg));
if (!showEmoji && !decryptedMessage.equals(injectOwnTextAll(getBody(msg)))) decryptedMessage = decryptedMessage.replaceAll("^\uD83D\uDD12 ", "");
return decryptedMessage;
}
public static String decryptMessage(String msg, MsgListComponent list) {
var peerid = list.G().getId();
var decryptedMessage = decryptMessage(msg, peerid);
if (!decryptedMessage.equals(injectOwnTextAll(msg))) decryptedMessage = decryptedMessage.replaceAll("^\uD83D\uDD12 ", "");
return decryptedMessage;
}
public static CharSequence decryptMessage(CharSequence msg, int peerid) {
return decryptMessage(msg.toString(), peerid);
}
public static CharSequence decryptMessage(Msg msg, CharSequence orig) {
if (msg instanceof MsgFromUser) {
var decrypted = decryptMessage(((MsgFromUser) msg).f(), msg.v1());
if (decrypted.contains("\uD83D\uDD12")) {
return decrypted;
}
}
return orig;
}
public static String decryptMessages(String msgBody, int peer, boolean showEmoji) {
return (String) decryptMessage(msgBody, peer, showEmoji);
}
// For MentionsFormatter that requires CharSequence
public static CharSequence decryptMessage(String msgBody, int peer, boolean showEmoji) {
var decryptedMessage = decryptMessage(msgBody, peer);
if (!showEmoji && !decryptedMessage.equals(injectOwnTextAll(msgBody))) decryptedMessage = decryptedMessage.replaceAll("^\uD83D\uDD12 ", "");
return decryptedMessage;
}
// This will run through EVERY single processor available.
public static String decryptMessage(MsgFromUser msg){
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))
return "\uD83D\uDD12 " + processor.decode(msgBody, getKeyForProcessor(processor, peer));
return "\uD83D\uDD12 " + injectOwnTextAll(processor.decode(msgBody, getKeyForProcessor(processor, peer)));
}
} catch (Exception e) {
e.printStackTrace();
}
return msgBody;
return injectOwnTextAll(msgBody);
}
private static byte[] getKeyForProcessor(IMProcessor processor, int peer){
private static byte[] getKeyForProcessor(IMProcessor processor, int peer) {
if (processor.isPublic()) return null;
String keyString = processor.getEncryptionKeyFor(peer);
if (keyString == null) return null;
@@ -84,9 +131,8 @@ public class EncryptProvider{
return keyString.getBytes();
}
// This will use only the processor which was chosen in chat menu [that's why ID is needed, bruh]
public static String encryptMessage(MsgFromUser msg){
// This will use only the processor which was chosen in chat menu
public static String encryptMessage(MsgFromUser msg) {
String msgBody = getBody(msg);
Log.d("EncryptProvider", "encryptMessage: msg = " + msg);
@@ -96,15 +142,15 @@ public class EncryptProvider{
for (IMProcessor processor : processors) {
int peer = getPeerId(msg);
if (processor.isUsedToEncrypt(peer)) {
return processor.encode(msgBody, getKeyForProcessor(processor, peer));
return injectOwnText(processor.encode(msgBody, getKeyForProcessor(processor, peer)));
}
}
return msgBody;
return injectOwnText(msgBody);
}
// For rendering UI
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,54 +2,119 @@ 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.proxy.ProxyUtils.getApi;
import static ru.vtosters.lite.proxy.ProxyUtils.isAnyProxyEnabled;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
import static ru.vtosters.lite.utils.AndroidUtils.getString;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Context;
import android.util.Log;
import androidx.exifinterface.media.ExifInterface;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vk.core.network.Network;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Objects;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import ru.vtosters.lite.net.Request;
import ru.vtosters.lite.utils.Preferences;
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 String API_VKNEXT = "https://api.vtosters.app/v1/getBypassedOnlineInfo?json=1&ids=";
private static final OkHttpClient client = new OkHttpClient();
public static long getLastSeen(long origtime, int id) throws ParseException, IOException{
if (!Preferences.foaf()) return origtime;
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();
String response = null;
try {
response = client.a(request).execute().a().g();
} catch (IOException e) {
Log.e("FoafBase", e.getMessage());
}
Matcher matcher = FOAF_REGEX_LAST_SEEN.matcher(response);
Matcher matcher = FOAF_REGEX_LAST_SEEN.matcher(
client.a(
new okhttp3.Request.a().a(getLink(id)).b().a()
).execute().a().g());
if (!matcher.find()) {
return origtime;
}
return new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ss", Locale.getDefault()).parse(matcher.group(1)).getTime() / 1000;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Moscow"));
Date date = sdf.parse(Objects.requireNonNull(matcher.group(1)));
sdf.setTimeZone(TimeZone.getDefault());
return sdf.parse(sdf.format(date)).getTime() / 1000;
}
private static String getLink(int i){
public static JSONObject getBypassedOnlineInfo(int id) throws JSONException {
var request = new okhttp3.Request.a()
.b(API_VKNEXT + Integer.toString(id))
.a();
String response = null;
var dummy = new JSONObject();
dummy.put("last_seen", 0);
try {
response = client.a(request).execute().a().g();
var online_info = new JSONObject(response).optJSONObject("response").optJSONObject(Integer.toString(id));
return online_info == null ? dummy : online_info;
} catch (Exception e) {
Log.e("GetBypassedOnlineInfo", e.getMessage());
return dummy;
}
}
public static JSONObject getBypassedOnlineInfo(String ids) throws JSONException {
var request = new okhttp3.Request.a()
.b(API_VKNEXT + ids)
.a();
String response = null;
var dummy = new JSONObject();
try {
response = client.a(request).execute().a().g();
var online_info = new JSONObject(response).optJSONObject("response");
return online_info == null ? dummy : online_info;
} catch (Exception e) {
Log.e("GetBypassedOnlineInfo1", e.getMessage());
return dummy;
}
}
private static String getLink(int i) {
String str;
StringBuilder sb;
if (apiproxy()) {
if (isAnyProxyEnabled()) {
sb = new StringBuilder();
str = "https://" + getApi() + "/_/vk.com/foaf.php?id=";
} else {
@@ -61,7 +126,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);
@@ -71,25 +136,26 @@ 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);
Matcher matcher2 = FOAF_REGEX_LOGIN.matcher(str);
matcher.find();
matcher2.find();
String normalHumanDate = getNormalHumanDate(matcher.group(1));
getNormalHumanDate(matcher2.group(1));
String normalHumanDate = getNormalHumanDate(Objects.requireNonNull(matcher.group(1)));
getNormalHumanDate(Objects.requireNonNull(matcher2.group(1)));
VkAlertDialog.Builder a2 = new VkAlertDialog.Builder(context).setTitle(getIdentifier("addinf", "string"));
a2.setMessage(getString("foafid") + " " + i + getString("foafregdate") + " " + normalHumanDate + getString("foafdate") + " " + daysPassedFromFoafDate(normalHumanDate)).setPositiveButton(17039370, null).create().show();
} catch (Exception e) {
e.printStackTrace();
makeText(context, getString("foaferr"), LENGTH_SHORT).show();
makeText(getGlobalContext(), getString("foaferr"), LENGTH_SHORT).show();
}
}
private static long daysPassedFromFoafDate(String str){
private static long daysPassedFromFoafDate(String str) {
try {
@SuppressLint("SimpleDateFormat")
Date parse = new SimpleDateFormat("yyyy-MM-dd").parse(str.split(" ")[1]);
return TimeUnit.DAYS.convert(new Date().getTime() - parse.getTime(), TimeUnit.MILLISECONDS);
} catch (ParseException e) {
@@ -98,7 +164,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];
}
@@ -0,0 +1,358 @@
package ru.vtosters.lite.hooks;
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;
import static ru.vtosters.lite.utils.Preferences.authorsrecomm;
import static ru.vtosters.lite.utils.Preferences.dev;
import static ru.vtosters.lite.utils.Preferences.friendsrecomm;
import static ru.vtosters.lite.utils.Preferences.postsrecomm;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Collections;
import java.util.LinkedHashSet;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.NewsFeedFiltersUtils;
public class AdBlockHook {
public static Boolean discoverAdBlock(JSONObject jsonObject) {
if (jsonObject == null) return true;
try {
var type = jsonObject.optString("type");
var post = jsonObject.optJSONObject("post");
if (jsonObject.optString("template").contains("ads") || jsonObject.has("ads")) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + (post != null ? post.optInt("post_id") : 0) + " from discover, Reason: ads");
return false;
}
if (isAds(post, type)) {
return false;
}
if (authorsrecomm() && (type.equals("authors_rec")
|| type.startsWith("recommended_") && (type.endsWith("audios")
|| type.endsWith("artists")
|| type.endsWith("playlists")
|| type.endsWith("groups")))) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + (post != null ? post.optInt("post_id") : 0) + " from discover, Reason: authorsrecomm");
return false;
}
if (postsrecomm() && (type.equals("inline_user_rec") || type.equals("live_recommended"))) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + (post != null ? post.optInt("post_id") : 0) + " from discover, Reason: postsrecomm");
return false;
}
if (friendsrecomm() && (type.equals("user_rec") || type.equals("friends_recomm"))) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + (post != null ? post.optInt("post_id") : 0) + " from discover, Reason: friendsrecomm");
return false;
}
if (adsgroup() && (post != null ? post.optInt("marked_as_ads") : 0) == 1 && !isWhitelistedAd(post)) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + post.optInt("post_id") + " from discover, Reason: marked_as_ads is true");
return false;
}
if (post != null) {
if (isBadNews(post.optString("text")) && !isWhitelistedFilters(post)) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + post.optInt("post_id") + " from discover, Reason: text filters");
return false;
}
if (checkCopyright(post) && !isWhitelistedFilters(post)) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + post.optInt("post_id") + " from discover, Reason: copyright filters");
return false;
}
if (checkCaption(post) && !isWhitelistedFilters(post)) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + post.optInt("post_id") + " from discover, Reason: caption filters");
return false;
}
if (NewsFeedFiltersUtils.injectFiltersReposts(post) && !isWhitelistedFilters(post)) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + post.optInt("post_id") + " from discover, Reason: repost ad");
return false;
}
}
} catch (Exception e) {
Log.d("NewsfeedAdBlockV2", "discover: " + e.getMessage());
}
return true;
}
public static JSONObject discoverInject(JSONObject json) throws JSONException {
var items = json.optJSONArray("items");
var newObj = new JSONArray();
// newObj.put(discoverObj()); // template injection
for (int i = 0; i < (items != null ? items.length() : 0); i++) {
try {
var curr = items.getJSONObject(i);
if (!curr.optString("template").contains("info") && discoverAdBlock(curr)) {
newObj.put(items.optJSONObject(i));
}
} catch (Exception e) {
Log.d("NewsfeedAdBlockV2", "discover: " + e);
}
}
json.put("items", newObj);
return json;
}
public static JSONObject discoverObj() throws JSONException {
var mainjson = new JSONObject();
var info = new JSONObject();
info.put("title", "Test Injection");
info.put("text_color", "#ffffff");
info.put("description", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat");
var image = new JSONArray();
var imageQuality1 = new JSONObject();
imageQuality1.put("url", "https://w7.pngwing.com/pngs/505/1021/png-transparent-konata-izumi-lucky-star-desktop-anime-anime-blue-mammal-face.png");
imageQuality1.put("width", 72); // 72, 108, 144, 216, 288
imageQuality1.put("height", 72); // 72, 108, 144, 216, 288
image.put(imageQuality1);
var background = new JSONArray();
var backgroundQuality1 = new JSONObject();
backgroundQuality1.put("url", "https://2ch.life/vg/arch/2022-08-22/src/38524739/16440606579870.jpg");
backgroundQuality1.put("width", 344); // 344, 516, 680, 1032, 1376
backgroundQuality1.put("height", 215); // 215, 323, 426, 645, 860
background.put(backgroundQuality1);
info.put("image", image);
info.put("background", background);
mainjson.put("info", info);
mainjson.put("track_code", "info_banner_donut_catalog");
mainjson.put("template", "info");
var action = new JSONObject();
action.put("type", "open_url");
action.put("url", "vk.com/vtosters_official");
action.put("target", "internal");
mainjson.put("action", action);
return mainjson;
}
public static JSONArray feedInject(JSONArray items) {
if (items.length() == 0) return items;
try {
var newItems = new JSONArray();
for (int j = 0; j < items.length(); j++) {
var list = items.optJSONObject(j);
if (list == null) continue;
var type = list.optString("type");
if (isAds(list, type)) {
continue;
}
if (authorsrecomm() && (type.equals("authors_rec")
|| type.startsWith("recommended_") && (type.endsWith("audios")
|| type.endsWith("artists")
|| type.endsWith("playlists")
|| type.endsWith("groups")))) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: authorsrecomm");
continue;
}
if (postsrecomm() && (type.equals("inline_user_rec") || type.equals("live_recommended"))) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: postsrecomm");
continue;
}
if (friendsrecomm() && (type.equals("user_rec") || type.equals("friends_recomm"))) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: friendsrecomm");
continue;
}
if (adsgroup() && list.optInt("marked_as_ads") == 1 && !isWhitelistedAd(list)) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: marked_as_ads is true");
continue;
}
if (isBadNews(list.optString("text")) && !isWhitelistedFilters(list)) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: text filters");
continue;
}
if (checkCopyright(list) && !isWhitelistedFilters(list)) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: copyright filters");
continue;
}
if (checkCaption(list) && !isWhitelistedFilters(list)) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: caption filters");
continue;
}
if (NewsFeedFiltersUtils.injectFiltersReposts(list) && !isWhitelistedFilters(list)) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: repost ad");
continue;
}
newItems.put(list);
}
return newItems;
} catch (Exception e) {
Log.d("NewsfeedAdBlockV2", e.getMessage());
}
return items;
}
public static JSONObject storiesads(JSONObject json, boolean isDeleteFix) throws JSONException {
if (!adsstories()) {
return json;
}
if (json.has("ads")) {
var ad = json.optJSONObject("ads");
if (isDeleteFix) {
if (ad != null) {
ad.optJSONObject("settings")
.put("stories_interval", 0)
.put("authors_interval", 0)
.put("time_interval", 0)
.put("stories_init", 0)
.put("authors_init", 0)
.put("time_init", 0);
}
if (dev()) Log.d("StoriesAds", "Set ads settings at zero values");
} else {
json.remove("ads");
if (dev()) Log.d("StoriesAds", "Removed ads block");
}
}
if (!json.has("items")) return json;
var items = json.optJSONArray("items");
if (items != null) {
for (int i = 0; i < items.length(); i++) {
var item = items.optJSONObject(i);
if (item != null) {
parseStoriesItem(item);
}
}
}
return json;
}
private static void parseStoriesItem(JSONObject item) throws JSONException {
var stories = item.optJSONArray("stories");
var newStories = new JSONArray();
if (stories == null) return;
for (int j = 0; j < stories.length(); j++) {
var story = stories.optJSONObject(j);
if (!story.optBoolean("is_ads") && !story.optBoolean("is_promo")) {
newStories.put(story);
} else {
if (dev())
Log.d("StoriesAds", "Fetched ad, owner id " + story.optString("owner_id") + ", caption " + story.optString("caption"));
}
}
item.put("stories", newStories);
}
public static Boolean isAds(JSONObject list, String type) throws JSONException {
if (list == null || type == null || !ads()) return false;
if (list.has("ads")
|| type.equals("ads")
|| type.equals("carousel")
|| type.equals("html5_ad")
|| type.equals("ads_easy_promote")) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: ads");
return true;
}
if (type.equals("promo_button")
|| type.equals("app_widget")
|| type.equals("app_video")
|| type.equals("app_slider")
|| type.equals("tags_suggestions")) {
if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: promo");
return true;
}
return false;
}
public static Boolean isWhitelistedFilters(JSONObject list) {
var id = String.valueOf(list.optInt("owner_id"));
if (id.equals("0")) {
id = String.valueOf(list.optInt("source_id"));
}
if (id.equals("-189659924")){
return true;
}
var whitelist = AndroidUtils.getDefaultPrefs().getStringSet("whitelisted_filters_groups", Collections.synchronizedSet(new LinkedHashSet<>()));
return whitelist.contains(id);
}
public static Boolean isWhitelistedAd(JSONObject list) {
var id = String.valueOf(list.optInt("owner_id"));
if (id.equals("0")) {
id = String.valueOf(list.optInt("source_id"));
}
var whitelist = AndroidUtils.getDefaultPrefs().getStringSet("whitelisted_ad_groups", Collections.synchronizedSet(new LinkedHashSet<>()));
return whitelist.contains(id);
}
}
@@ -0,0 +1,129 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.dnr.DNRInjector.forceInvalidateDialogActions;
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
import static ru.vtosters.lite.utils.AndroidUtils.getString;
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
import static ru.vtosters.lite.utils.LifecycleUtils.getCurrentActivity;
import static ru.vtosters.lite.utils.ThemesUtils.getAlertStyle;
import static ru.vtosters.lite.utils.ThemesUtils.getSTextAttr;
import android.content.Context;
import android.content.res.ColorStateList;
import android.text.Editable;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.LinearLayout;
import androidx.appcompat.app.AlertDialog;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vk.im.engine.models.dialogs.Dialog;
import java.util.List;
import java.util.Objects;
import ru.vtosters.lite.encryption.EncryptProvider;
import ru.vtosters.lite.encryption.base.IMProcessor;
public class CryptImHook{
public static boolean isPrivateProcessor(int peerID){
for (IMProcessor processor : EncryptProvider.processors) {
if (processor.isUsedToEncrypt(peerID)) {
return !processor.isPublic();
}
}
return false;
}
public static void hook(int peerId, Dialog d){
List<IMProcessor> processors = EncryptProvider.processors;
IMProcessor enabled = null;
int enabledPosition = 0;
String[] titles = new String[processors.size() + 1];
titles[0] = getString("encryption_disable");
for (int i = 0; i < processors.size(); i++) {
IMProcessor proc = processors.get(i);
titles[i + 1] = proc.getUIName();
if (proc.isUsedToEncrypt(peerId)) {
enabled = proc;
enabledPosition = i + 1;
}
}
IMProcessor finalEnabled = enabled;
new VkAlertDialog.Builder(getCurrentActivity())
.setTitle(getString("encryption_sett"))
.setSingleChoiceItems(titles, enabledPosition, (dialog, which) -> {
if (which == 0) {
if (finalEnabled != null) finalEnabled.disableEncryptFor(peerId);
} else {
IMProcessor proc = processors.get(which - 1);
if (proc.isUsedToEncrypt(peerId)) {
proc.disableEncryptFor(peerId);
} else {
proc.enableEncryptFor(peerId);
if (finalEnabled != null) finalEnabled.disableEncryptFor(peerId);
}
}
dialog.dismiss();
forceInvalidateDialogActions(d);
}).create().show();
}
public static void hookPref(int peerId){
IMProcessor enabled = null;
String key = null;
for (IMProcessor processor : EncryptProvider.processors) {
if (processor.isUsedToEncrypt(peerId)) {
enabled = processor;
}
}
if (enabled != null && enabled.isPublic()) {
sendToast(getString("encryption_public_algorithm_error"));
return;
}
if (Objects.requireNonNull(enabled).getEncryptionKeyFor(peerId) != null) {
key = enabled.getEncryptionKeyFor(peerId);
}
if (key.equals("VTAesDefault")) {
key = null;
}
Context ctx = getCurrentActivity();
LinearLayout linearLayout = new LinearLayout(ctx);
final EditText editText = new EditText(ctx);
editText.setHintTextColor(getSTextAttr());
editText.setBackgroundTintList(ColorStateList.valueOf(getSTextAttr()));
linearLayout.addView(editText);
editText.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
ViewGroup.MarginLayoutParams margin = ((ViewGroup.MarginLayoutParams) editText.getLayoutParams());
margin.setMargins(dp2px(24f), 0, dp2px(24f), 0);
editText.setLayoutParams(margin);
editText.setText(key == null ? "" : key);
IMProcessor finalEnabled = enabled;
new AlertDialog.Builder(ctx, getAlertStyle())
.setTitle(getString("encryption_enter_key"))
.setMessage(String.format(getString("encryption_current_algorithm_title"), enabled.getUIName()))
.setView(linearLayout)
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
Editable edit = editText.getText();
finalEnabled.setEncryptionKeyFor(peerId, edit == null ? null : edit.toString());
}).setNegativeButton(android.R.string.cancel, null).create().show();
}
}
@@ -1,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,45 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.AndroidUtils.MD5;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import android.annotation.SuppressLint;
import android.os.Build;
import android.provider.Settings;
import android.util.Log;
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) {
return findDeviceId() + ":" + getDeviceId();
}
public static String getDeviceId() {
String sb2 = Build.PRODUCT +
Build.BOARD +
Build.BOOTLOADER +
Build.BRAND +
Build.DEVICE +
Build.DISPLAY +
Build.FINGERPRINT +
Build.HARDWARE +
Build.HOST +
Build.ID +
Build.MANUFACTURER +
Build.MODEL +
Build.PRODUCT +
Build.TAGS;
return MD5(sb2);
}
@SuppressLint("HardwareIds")
private static String findDeviceId() {
return Settings.Secure.getString(getGlobalContext().getContentResolver(), "android_id");
}
}
@@ -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);
@@ -289,7 +286,7 @@ public class DockBarInjector {
}
public static Class<?> interceptClick(int id, RightMenu rightMenu) {
if (id == tab_menu) {
if (id == tab_menu && rightMenu != null) {
rightMenu.a();
}
@@ -297,6 +294,7 @@ public class DockBarInjector {
if (id == tab.id)
return tab.fragmentClass;
}
for (DockBarTab tab : sManager.getDisabledTabs()) {
if (id == tab.id)
return tab.fragmentClass;
@@ -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,98 +1,200 @@
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.getBypassedOnlineInfo;
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.getUserToken;
import static ru.vtosters.lite.hooks.OnlineFormatterHook.onlineHookProfiles;
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
import static ru.vtosters.lite.proxy.ProxyUtils.getStatic;
import static ru.vtosters.lite.utils.AndroidUtils.getDefaultPrefs;
import static ru.vtosters.lite.utils.Preferences.dev;
import static ru.vtosters.lite.utils.Preferences.friendsblock;
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
import static ru.vtosters.lite.utils.Preferences.hasVerification;
import static ru.vtosters.lite.utils.Preferences.podcastcatalog;
import static ru.vtosters.lite.utils.VTVerifications.isDeveloper;
import static ru.vtosters.lite.utils.VTVerifications.isPrometheus;
import static ru.vtosters.lite.utils.VTVerifications.isVerified;
import android.text.TextUtils;
import android.util.Log;
import com.vk.core.network.Network;
import com.vk.core.util.DeviceIdProvider;
import com.vtosters.lite.fragments.messages.chat.vc.MsgSendVc;
import com.vk.core.util.LangUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Random;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import ru.vtosters.lite.utils.Globals;
import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils;
public class JsonInjectors{
public class JsonInjectors {
private static final OkHttpClient mClient = new OkHttpClient();
public static JSONObject profileButton(JSONObject orig) throws JSONException{
if (haveDonateButton()) return orig;
public static JSONObject profileButton(JSONObject orig) throws JSONException {
var id = orig.getInt("id");
var pic = "https://sun1-18.userapi.com/NLd_rNpGuSaBnPV6O-j5mqCGZk8BK8drAMd2LQ/5R-DEF37PFs.png";
var title = "Помоги проекту донатом и получи бонус!";
var newItem = new JSONArray();
if (orig.has("buttons")) {
newItem = orig.getJSONArray("buttons");
}
if (!haveDonateButton() && id == AccountManagerUtils.getUserId()) {
newItem.put(donateRecomm());
}
if (!orig.has("type") && AccountManagerUtils.isVKTester()) {
newItem.put(vktesters(id));
}
orig.put("buttons", newItem);
return orig;
}
public static JSONObject donateRecomm() throws JSONException {
var title = AndroidUtils.getString("donate_to_vtl");
var link = "https://vk.com/vtosters_official";
var text_color = "2D81E0";
// JSONObject jsonObj = new JSONObject("{\"action\":{\"target\":\"internal\",\"type\":\"open_url\",\"url\":\"" + link + "\"},\"title\":\"" + title + "\",\"icons\":[{\"url\":\"" + pic + "\",\"width\":20,\"height\":20},{\"url\":\"" + pic + "\",\"width\":40,\"height\":40},{\"url\":\"" + pic + "\",\"width\":60,\"height\":60},{\"url\":\"" + pic + "\",\"width\":80,\"height\":80}],\"text_color\":\"" + text_color + "\"}");
return new JSONObject(decode("eyJhY3Rpb24iOnsidGFyZ2V0IjoiaW50ZXJuYWwiLCJ0eXBlIjoib3Blbl91cmwiLCJ1cmwiOiI=")
+ link + decode("In0sInRpdGxlIjoi")
+ title + decode("IiwiaWNvbnMiOlt7InVybCI6Ig==")
+ pic + decode("Iiwid2lkdGgiOjIwLCJoZWlnaHQiOjIwfSx7InVybCI6Ig==")
+ pic + decode("Iiwid2lkdGgiOjQwLCJoZWlnaHQiOjQwfSx7InVybCI6Ig==")
+ pic + decode("Iiwid2lkdGgiOjYwLCJoZWlnaHQiOjYwfSx7InVybCI6Ig==")
+ pic + decode("Iiwid2lkdGgiOjgwLCJoZWlnaHQiOjgwfV0sInRleHRfY29sb3IiOiI=")
+ text_color + decode("In0="));
var json = new JSONObject();
var icons = new JSONArray();
var action = new JSONObject();
action.put("target", "internal");
action.put("type", "open_url"); // may be open_url, open_internal_vkui, open_game, help_hint, show_full_post, open_vkapp, show_recommendations_for_post and groups_advertisement
action.put("url", link);
json.put("action", action);
json.put("title", title);
var icon1 = new JSONObject();
icon1.put("url", "https://sun2-10.userapi.com/NLd_rNpGuSaBnPV6O-j5mqCGZk8BK8drAMd2LQ/5R-DEF37PFs.png");
icon1.put("width", "20");
icon1.put("height", "20");
icons.put(icon1);
var icon2 = new JSONObject();
icon2.put("url", "https://sun2-12.userapi.com/N8y9pU1meJq_eug-wB1u-HUuGyMqDfdq7A025w/A4Aio-xuLY8.png");
icon2.put("width", "40");
icon2.put("height", "40");
icons.put(icon2);
var icon3 = new JSONObject();
icon3.put("url", "https://sun2-9.userapi.com/3Hx4hff63_2Lt6wjjthJMF_3QLUswNNlQKoAXQ/oyzEu1NL9T8.png");
icon3.put("width", "80");
icon3.put("height", "80");
icons.put(icon3);
json.put("icons", icons);
json.put("text_color", text_color);
return json;
}
public static JSONObject convBar(JSONObject orig) throws JSONException{
if (!dev()) return orig.optJSONObject("conversation_bar"); // TODO Make it server-side
public static JSONObject vktesters(int id) throws JSONException {
var title = AndroidUtils.getString("tester_profile");
var text_color = "2D81E0";
var link = "https://" + getStatic() + "/bugs?lang=" + LangUtils.a() + "#/reporter" + id;
var json = new JSONObject();
var icons = new JSONArray();
var action = new JSONObject();
action.put("target", "internal");
action.put("type", "open_internal_vkui");
action.put("url", link);
json.put("action", action);
json.put("title", title);
var icon1 = new JSONObject();
icon1.put("url", "https://sun2-10.userapi.com/NLd_rNpGuSaBnPV6O-j5mqCGZk8BK8drAMd2LQ/5R-DEF37PFs.png");
icon1.put("width", "20");
icon1.put("height", "20");
icons.put(icon1);
var icon2 = new JSONObject();
icon2.put("url", "https://sun2-12.userapi.com/N8y9pU1meJq_eug-wB1u-HUuGyMqDfdq7A025w/A4Aio-xuLY8.png");
icon2.put("width", "40");
icon2.put("height", "40");
icons.put(icon2);
var icon3 = new JSONObject();
icon3.put("url", "https://sun2-9.userapi.com/3Hx4hff63_2Lt6wjjthJMF_3QLUswNNlQKoAXQ/oyzEu1NL9T8.png");
icon3.put("width", "80");
icon3.put("height", "80");
icons.put(icon3);
json.put("icons", icons);
json.put("text_color", text_color);
return json;
}
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
var text = "Я не загрузил данные (9(9((";
var text = AndroidUtils.getString("no_data_error");
var link = "https://vtosters.app"; // can be null
var linktitle = "Test button"; // can be null
// "{\"layout\":\"tertiary\",\"text\":\"" + linktitle + "\",\"type\":\"link\",\"link\":\"" + link + "\"}";
var buttons = decode("eyJsYXlvdXQiOiJ0ZXJ0aWFyeSIsInRleHQiOiI=") + linktitle + decode("IiwidHlwZSI6ImxpbmsiLCJsaW5rIjoi") + link + decode("In0=");
// ,"icon":" + pic + "
var icon = decode("LCJpY29uIjoi") + pic + decode("Ig==");
var hasIcon = !pic.isEmpty();
var hasButton = !buttons.isEmpty();
var hasButton = !link.isEmpty();
var isPicture = pic.endsWith(".png") || pic.endsWith(".jpg") || pic.endsWith(".jpeg") || pic.endsWith(".webp");
if (!isPicture) hasIcon = false;
if (!hasIcon) icon = "";
if (!hasButton) buttons = "";
if (isVerified(peerid)) text = AndroidUtils.getString("i_bought") + " VTosters Premium";
if (isPrometheus(peerid)) text = AndroidUtils.getString("i_bought") + " VTosters Premium Gold Prime Pro Plus";
if (isDeveloper(peerid)) text = AndroidUtils.getString("i_created_poop");
if (isVerified(peerid)) text = "Я купил VTosters Premium";
if (isPrometheus(peerid)) text = "Я купил VTosters Premium Gold Prime Pro Plus";
if (isDeveloper(peerid)) text = "Я создал говно";
if (!isVerified(peerid) || text.equals("")) return orig.optJSONObject("conversation_bar");
if (!isVerified(peerid) || text.equals("") || peerid == AccountManagerUtils.getUserId() || peerid == 0) {
if (getBoolValue("convBarRecomm", false)) {
return null;
} else {
return orig.optJSONObject("conversation_bar");
}
}
// JSONObject("{\"name\":\"group_admin_welcome\",\"text\":\"" + textverif + "\",\"buttons\":[],\"icon\":\"" + pic + "\"}");
return new JSONObject(decode("eyJuYW1lIjoiZ3JvdXBfYWRtaW5fd2VsY29tZSIsInRleHQiOiI=")
+ text + decode("IiwiYnV0dG9ucyI6Ww==")
+ buttons + decode("XQ==")
+ icon
+ decode("fQ=="));
if (!dev()) return orig.optJSONObject("conversation_bar"); // for devs only
var json = new JSONObject();
var buttonsJson = new JSONObject();
buttonsJson.put("layout", "tertiary");
buttonsJson.put("text", linktitle);
buttonsJson.put("type", "link");
buttonsJson.put("link", link);
var buttonsjson = new JSONArray(); // max 3 buttons in array
if (hasButton) buttonsjson.put(buttonsJson);
json.put("name", "group_admin_welcome");
json.put("text", text);
json.put("buttons", buttonsjson);
if (hasIcon && isPicture) {
json.put("icon", pic);
}
return json;
}
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");
@@ -105,7 +207,8 @@ public class JsonInjectors{
}
public static JSONObject superapp(JSONObject json) throws JSONException {
var superApps = Globals.getPreferences().getString("superapp_items", "").split(",");
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");
@@ -132,22 +235,159 @@ public class JsonInjectors{
return json.putOpt("items", newItems);
}
public static JSONObject musiclink(JSONObject json){
var oldItems = json.optJSONArray("links");
public static JSONObject musiclink(JSONObject json) {
var links = json.optJSONArray("links");
if (oldItems != null) {
if (oldItems.optJSONObject(0).optString("url").contains("?section=recent")) {
if (links != null) {
if (links.optJSONObject(0).optString("url").contains("?section=recent")) {
json.remove("links");
if (dev()) Log.d("VKMusic", "Removed links buttons");
}
}
return json;
}
public static JSONObject music(JSONObject json) throws JSONException{
var oldItems = json.optJSONObject("catalog").optJSONArray("sections");
public static JSONObject setOnlineInfo(JSONObject json) throws JSONException {
var id = json.optInt("id");
if (id == AccountManagerUtils.getUserId()) {
return json;
}
var onlineinfo = json.optJSONObject("online_info");
if (onlineinfo != null && !onlineinfo.optBoolean("visible")) {
var bypassed = getBypassedOnlineInfo(id);
if (bypassed.optInt("last_seen", 0) != 0) {
json.remove("online_info");
var online_info = new JSONObject()
.put("visible", true)
.put("last_seen", bypassed.optInt("last_seen"))
.put("is_online", bypassed.optBoolean("is_online"))
.put("app_id", bypassed.optInt("app_id"))
.put("is_mobile", bypassed.optBoolean("is_mobile"));
var last_seen = new JSONObject()
.put("platform", bypassed.optInt("platform"))
.put("time", bypassed.optInt("last_seen"));
json.put("last_seen", last_seen).put("online_info", online_info);
}
}
return json;
}
public static JSONArray setOnlineInfoUsers(JSONArray profiles) throws JSONException {
if (profiles == null || profiles.length() == 0) return profiles;
StringBuilder sb = new StringBuilder();
var curVkId = AccountManagerUtils.getUserId();
for (int i=0; i < profiles.length(); i++) {
JSONObject profile = profiles.getJSONObject(i);
int id = profile.optInt("id", -1);
JSONObject onlinfo = profile.optJSONObject("online_info");
if (id == curVkId || id < 0 || onlinfo == null || onlinfo.optBoolean("visible")) {
continue;
}
sb.append(id);
sb.append(",");
}
var ids = sb.toString();
if (ids.length() > 0) {
ids = ids.substring(0, ids.length() - 1);
} else {
return profiles;
}
JSONObject bypassedObj = getBypassedOnlineInfo(ids);
for (int i=0; i < profiles.length(); i++) {
JSONObject profile = profiles.getJSONObject(i);
int id = profile.optInt("id");
JSONObject bypassed = bypassedObj.optJSONObject(Integer.toString(id));
if (bypassed == null) {
continue;
}
profile.remove("online_info");
var online_info = new JSONObject()
.put("visible", true)
.put("last_seen", bypassed.optInt("last_seen"))
.put("is_online", bypassed.optBoolean("is_online"))
.put("app_id", bypassed.optInt("app_id"))
.put("is_mobile", bypassed.optBoolean("is_mobile"));
var last_seen = new JSONObject()
.put("platform", bypassed.optInt("platform"))
.put("time", bypassed.optInt("last_seen"));
profile.put("last_seen", last_seen).put("online_info", online_info);
}
return profiles;
}
public static JSONArray newsfeedlist(JSONArray items) throws JSONException {
var selectedItems = getDefaultPrefs().getString("news_feed_selected_items", "");
var filtersSet = getDefaultPrefs().getStringSet("news_feed_items_set", null);
var mutableFiltersSet = Collections.synchronizedSet(new LinkedHashSet<String>());
if (filtersSet != null)
mutableFiltersSet.addAll(filtersSet);
synchronized (mutableFiltersSet) {
for (int i = 0; i < items.length(); i++) {
var item = items.optJSONObject(i);
if (item == null) continue;
var id = item.optString("id");
var title = item.optString("title");
if (TextUtils.isEmpty(id) || TextUtils.isEmpty(title)
// this items not working
|| id.equals("kpop") || id.equals("foryou")
|| id.equals("qazaqstan") || id.equals("podcasts"))
continue;
mutableFiltersSet.add(id + "|" + title);
var hide = selectedItems.contains(id);
Log.d("NewsfeedList", "Added list " + id + " to feed");
item.put("is_hidden", hide)
.put("is_unavailable", hide);
if (dev()) Log.d("NewsfeedListInj", "Unlocked " + id + " in newsfeed list");
}
getDefaultPrefs().edit().putStringSet("news_feed_items_set", mutableFiltersSet)
.apply();
}
return items;
}
public static JSONObject music(JSONObject json) throws JSONException {
var catalog = json.optJSONObject("catalog");
JSONArray oldItems = null;
if (catalog != null) {
oldItems = catalog.optJSONArray("sections");
}
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));
}
}
if (oldItems != null) {
var playlists = fetchCatalogId("https://vk.com/audio?section=my_playlists");
if (playlists != null) {
var catalogarr = playlists.optJSONObject("catalog").optJSONArray("sections").optJSONObject(0);
@@ -156,6 +396,8 @@ public class JsonInjectors{
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));
}
@@ -167,6 +409,8 @@ public class JsonInjectors{
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));
}
@@ -178,30 +422,46 @@ public class JsonInjectors{
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));
}
for (int i = 0; i < oldItems.length(); i++) {
var item = oldItems.optJSONObject(i);
var title = item.optString("title");
var id = item.optString("id");
var url = item.optString("url");
var value = AndroidUtils.getPrefsValue("musicdefcatalog");
Log.d("VKMusic", "title: " + title + " id: " + id + " url: " + url + " value: " + value);
if (url.contains(value) && !value.isEmpty()) {
catalog.put("default_section", id);
if (dev()) Log.d("VKMusic", "Added " + title + " as default music section");
}
}
}
return json;
}
public static JSONObject fetchCatalogId(String section){
public static JSONObject fetchCatalogId(String section) {
if (section == null) return null;
var request = new Request.a()
.b("https://api.vk.com/method/catalog.getAudio"
.b("https://" + getApi() + "/method/catalog.getAudio"
+ "?v=5.119"
+ "&https=1"
+ "&need_blocks=1"
+ "&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");
@@ -212,8 +472,30 @@ public class JsonInjectors{
return null;
}
public static JSONObject friends(JSONObject json) throws JSONException{
JSONObject catalog = json;
public static JSONObject fetchCatalogPodcast() {
var request = new Request.a()
.b("https://" + getApi() + "/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, ParseException, IOException {
JSONObject catalog = onlineHookProfiles(json);
boolean sectionexecute = true;
boolean hasBirthday = false;
@@ -253,11 +535,11 @@ public class JsonInjectors{
skip = friendsblock();
}
if (buttons.contains("friends_birthdays_list")){
if (buttons.contains("friends_birthdays_list")) {
hasBirthday = true;
}
if (name.contains("separator") && hasBirthday){
if (name.contains("separator") && hasBirthday) {
skip = false;
hasBirthday = false;
}
@@ -278,10 +560,7 @@ public class JsonInjectors{
return json;
}
public static boolean haveDonateButton(){
int randomshower = new Random().nextInt(6);
return hasVerification() || randomshower != 1;
public static boolean haveDonateButton() {
return hasVerification() || new Random().nextInt(6) != 1;
}
}
@@ -0,0 +1,53 @@
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.NewsFeedFiltersUtils.setupFilters;
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 com.vk.core.concurrent.VkExecutors;
import ru.vtosters.lite.downloaders.notifications.NotificationChannels;
import ru.vtosters.lite.hooks.ui.SystemThemeChangerHook;
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;
import ru.vtosters.lite.utils.DeletedMessagesHandler;
public class MainActivityInjector{
public static void inject(Activity activity){
setNeededTheme(activity);
ServerDialog.activity = activity;
sendRequest();
if (checkupdates()) OTADialog.checkUpdates(activity);
VkExecutors.x.f().a(DeletedMessagesHandler::reloadMessagesList); // ioScheduler
Start.alert(activity);
InstallGMS.alert(activity);
DisableBattery.alert(activity);
PreferenceManager.getDefaultSharedPreferences(activity)
.edit()
.putBoolean("isdark", isDarkTheme())
.commit();
SystemThemeChangerHook.onThemeChanged(activity.getResources().getConfiguration());
VkExecutors.x.q().a(() -> {
getInstance().autoCleaningCache();
}); // slowTasksScheduler
setupFilters();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannels.createChannels();
}
// VKIDProtection.alert(activity);
}
}
@@ -0,0 +1,106 @@
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 java.util.ArrayList;
import java.util.regex.Pattern;
import ru.vtosters.lite.translators.BaseTranslator;
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,56 +1,32 @@
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.isBadNew;
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.getDefaultPrefs;
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
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;
import com.vk.core.preference.Preference;
import com.vtosters.lite.api.ExtendedCommunityProfile;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
public class NewsfeedHook{
public static boolean injectFilters(JSONObject obj) throws JSONException{
var optString = obj.optString("type", "");
if (isAds(optString) || isAuthorRecommendations(optString) || isPostRecommendations(optString) || isFriendsRecommendations(optString) || isRecomsGroup(optString) || isMusicBlock(optString) || isNewsBlock(optString)) {
return false;
}
optString = obj.optString("post_type", "");
if (isAds(optString) || isAuthorRecommendations(optString) || isPostRecommendations(optString) || isFriendsRecommendations(optString) || isMusicBlock(optString) || isNewsBlock(optString)) {
return false;
}
optString = obj.optString("filters", "");
if (isAds(optString) || isAuthorRecommendations(optString) || isPostRecommendations(optString) || isFriendsRecommendations(optString)) {
return false;
}
import ru.vtosters.lite.utils.AccountManagerUtils;
if (checkCopyright(obj)) return false;
if (isBadNew(obj.optString("text", ""))) return false;
if (checkCaption(obj)) return false;
if (isGroupAds(obj)) return false;
return !injectFiltersReposts(obj);
} // inject our filters to newsfeed, getpost and discover
public static long getUpdateNewsfeed(boolean refresh_timeout){
public class NewsfeedHook {
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":
@@ -59,4 +35,91 @@ public class NewsfeedHook{
return Preference.b().getLong(refresh_timeout ? "refresh_timeout_top" : "refresh_timeout_recent", 600000L);
}
}
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() && !getBoolValue("donotgetads", false)) {
params.add("friends_recomm");
}
if (!ads()) {
params.add("app_widget");
params.add("promo_button");
}
if (!authorsrecomm() && !getBoolValue("donotgetads", false)) {
params.add("authors_rec");
}
return params.toArray(new String[0]);
}
public static boolean isWhitelistedFilter(ExtendedCommunityProfile eup) {
return getDefaultPrefs().getStringSet("whitelisted_filters_groups", Collections.synchronizedSet(new LinkedHashSet<>())).contains(String.valueOf(AccountManagerUtils.getUserID(eup)));
}
public static boolean isWhitelistedAd(ExtendedCommunityProfile eup) {
return getDefaultPrefs().getStringSet("whitelisted_ad_groups", Collections.synchronizedSet(new LinkedHashSet<>())).contains(String.valueOf(AccountManagerUtils.getUserID(eup)));
}
public static void setWhitelistedFilter(ExtendedCommunityProfile eup, boolean needWhitelist) {
var mutableAdsSet = Collections.synchronizedSet(new LinkedHashSet<String>());
var id = String.valueOf(AccountManagerUtils.getUserID(eup));
mutableAdsSet.addAll(getDefaultPrefs().getStringSet("whitelisted_filters_groups", mutableAdsSet));
if (needWhitelist) {
mutableAdsSet.add(id);
} else {
mutableAdsSet.remove(id);
}
getDefaultPrefs().edit().putStringSet("whitelisted_filters_groups", mutableAdsSet).apply();
}
public static void setWhitelistedAd(ExtendedCommunityProfile eup, boolean needWhitelist) {
var mutableAdsSet = Collections.synchronizedSet(new LinkedHashSet<String>());
var id = String.valueOf(AccountManagerUtils.getUserID(eup));
mutableAdsSet.addAll(getDefaultPrefs().getStringSet("whitelisted_ad_groups", mutableAdsSet));
if (needWhitelist) {
mutableAdsSet.add(id);
} else {
mutableAdsSet.remove(id);
}
getDefaultPrefs().edit().putStringSet("whitelisted_ad_groups", mutableAdsSet).apply();
}
public static void adsParams(HashSet<String> hashSet) {
if (ads()) {
hashSet.add("ads_disabled");
if (getBoolValue("donotgetads", false)) {
return;
}
}
hashSet.add("ads_app");
hashSet.add("ads_site");
hashSet.add("ads_post");
if (!adsslider()) {
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,24 +1,34 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.hooks.JsonInjectors.setOnlineInfo;
import static ru.vtosters.lite.hooks.JsonInjectors.setOnlineInfoUsers;
import static ru.vtosters.lite.net.Request.makeRequest;
import static ru.vtosters.lite.utils.Globals.getString;
import static ru.vtosters.lite.utils.Globals.getUserToken;
import static ru.vtosters.lite.utils.Globals.sendToast;
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
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 org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class OnlineFormatterHook{
import java.io.IOException;
import java.text.ParseException;
import ru.vtosters.lite.utils.AndroidUtils;
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:
@@ -54,37 +64,37 @@ public class OnlineFormatterHook{
case 5027722:
return "VK Messenger (Desktop)";
case 6146827:
return "VK Мессенджер (Android)";
return AndroidUtils.getString("vk_messenger") + " (Android)"; // VK Мессенджер (Android)
case 6482950:
return "VK Мессенджер (iPhone)";
return AndroidUtils.getString("vk_messenger") + " (iPhone)"; // VK Мессенджер (iPhone)
case 6481715:
return "VK Мессенджер Dev (iPhone)";
return AndroidUtils.getString("vk_messenger") + " Dev (iPhone)"; // VK Мессенджер Dev (iPhone)
case 7799655:
return "VK Почта";
return AndroidUtils.getString("vk_mail_online"); // VK Почта
case 7598572:
return "Сферум (Android)";
return AndroidUtils.getString("sferum_online") + " (Android)"; // Сферум (Android)
case 7571751:
return "Сферум (iPhone)";
return AndroidUtils.getString("sferum_online") + " (iPhone)"; // Сферум (iPhone)
case 7556576:
return "Сферум";
return AndroidUtils.getString("sferum_online"); // Сферум
case 7497650:
return "VK ID";
case 8094476:
return "VK Звонки (Android)";
return AndroidUtils.getString("vk_calls_online") + " (Android)"; // VK Звонки (Android)
case 8093730:
return "VK Звонки (iPhone)";
return AndroidUtils.getString("vk_calls_online") + " (iPhone)"; // VK Звонки (iPhone)
case 7793118:
return "VK Звонки (Desktop)";
return AndroidUtils.getString("vk_calls_online") + " (Desktop)"; // VK Звонки (Desktop)
case 6767438:
return "VK Музыка (Android)";
return AndroidUtils.getString("vk_music_online") + " (Android)"; // VK Музыка (Android)
case 8113297:
return "VK Клипы (Android)";
return AndroidUtils.getString("vk_clips_online") + " (Android)"; // VK Клипы (Android)
case 8106428:
return "VK Клипы (iPhone)";
return AndroidUtils.getString("vk_clips_online") + " (iPhone)"; // VK Клипы (iPhone)
case 5044491:
return "Candy";
case 8114066:
return "VK Видео";
return AndroidUtils.getString("vk_video_online"); // VK Видео
case 4894723:
return "Phoenix Lite";
case 4994316:
@@ -120,13 +130,19 @@ public class OnlineFormatterHook{
return "Miranda NG (bridge)";
case 8043814:
return "Quise";
case 7221936:
return "Вечный Online";
case 6892935:
return "VK Helper";
case 6248661:
return "MemeVoices for VK";
default:
return getAppNameFromOnline(appid);
}
}
public static String getAppNameFromOnline(int appid){
public static String getAppNameFromOnline(int appid) {
var prefs = getPrefsFromFile("onlines");
var appname = prefs.getString(String.valueOf(appid), null);
@@ -152,12 +168,75 @@ 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;
return getString("custom_online") + " " + appname;
}
public static JSONObject onlineHook(JSONObject json) throws ParseException, IOException, JSONException {
if (getBoolValue("onlinefix", false)) setOnlineInfo(json);
return json;
}
public static JSONArray onlineHookList(JSONArray jsonArr) throws ParseException, IOException, JSONException {
if (!getBoolValue("onlinefix", false)) return jsonArr;
try {
setOnlineInfoUsers(jsonArr);
} catch (Exception e) {
Log.e("onlineHookProfiles", e.getMessage());
}
return jsonArr;
}
public static JSONObject onlineHookProfiles(JSONObject json) throws ParseException, IOException, JSONException {
if (!getBoolValue("onlinefix", false)) return json;
try {
setOnlineInfoUsers(json.optJSONArray("profiles"));
} catch (Exception e) {
Log.e("onlineHookProfiles", e.getMessage());
}
return json;
}
public static JSONObject onlineHookItems(JSONObject json) throws ParseException, IOException, JSONException {
if (!getBoolValue("onlinefix", false)) return json;
try {
setOnlineInfoUsers(json.optJSONArray("items"));
} catch (Exception e) {
Log.e("onlineHookItems", e.getMessage());
}
return json;
}
public static JSONObject onlineHookRequestsAndRecommendations(JSONObject json) throws ParseException, IOException, JSONException {
if (!getBoolValue("onlinefix", false)) return json;
try {
setOnlineInfoUsers(json.optJSONObject("read_requests").optJSONArray("items"));
} catch (Exception e) {
Log.e("onlineHookItems", e.getMessage());
}
try {
setOnlineInfoUsers(json.optJSONObject("recommendations").optJSONArray("items"));
} catch (Exception e) {
Log.e("onlineHookItems", e.getMessage());
}
try {
setOnlineInfoUsers(json.optJSONArray("profiles"));
} catch (Exception e) {
Log.e("onlineHookItems", e.getMessage());
}
return json;
}
}
@@ -1,8 +1,10 @@
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 static ru.vtosters.lite.utils.AndroidUtils.getString;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
@@ -14,10 +16,15 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.vk.core.dialogs.actionspopup.ActionsPopup;
import com.vk.core.drawable.RecoloredDrawable;
import com.vk.core.util.ToastUtils;
import com.vk.dto.common.AttachmentWithMedia;
import com.vk.dto.common.ImageSize;
import com.vtosters.lite.R;
import com.vtosters.lite.attachments.DocumentAttachment;
import com.vtosters.lite.attachments.PhotoAttachment;
import org.json.JSONException;
@@ -25,69 +32,119 @@ import org.json.JSONObject;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import ru.vtosters.lite.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")) {
searchPhoto(getUrlFromAttachment((PhotoAttachment) attachment));
if (item.getItemId() == AndroidUtils.getIdentifier("search_photo", "id")) {
searchPhoto(getUrlFromPhotoAttachment((PhotoAttachment) attachment));
return true;
} else if (item.getItemId() == Globals.getIdentifier("copy_photo_url", "id")) {
copyPhotoUrl(getUrlFromAttachment((PhotoAttachment) attachment));
} else if (item.getItemId() == AndroidUtils.getIdentifier("copy_photo_url", "id")) {
copyPhotoUrl(getUrlFromPhotoAttachment((PhotoAttachment) attachment));
return true;
} else if (item.getItemId() == Globals.getIdentifier("open_original_photo", "id")) {
openUrl(getUrlFromAttachment((PhotoAttachment) attachment));
} else if (item.getItemId() == AndroidUtils.getIdentifier("open_original_photo", "id")) {
openUrl(getUrlFromPhotoAttachment((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()),
false,
() -> {
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()
? 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,
() -> {
copyPhotoUrl(getUrlFromAttachment((PhotoAttachment) attachment));
if (attachment instanceof PhotoAttachment) {
searchPhoto(getUrlFromPhotoAttachment((PhotoAttachment) attachment));
} else if (attachment instanceof DocumentAttachment) {
var documentAttachment = (DocumentAttachment) attachment;
if (documentAttachment.J != null)
try {
searchPhoto(getUrlFromDocumentAttachment(documentAttachment));
} catch (Exception e) {
ToastUtils.a(getString("photo_get_error"));
}
else
ToastUtils.a(getString("photo_get_error"));
}
return null;
}
);
actionPopup.a(getIdentifier("copy_photo_url_content", "string"),
!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,
() -> {
if (attachment instanceof PhotoAttachment) {
copyPhotoUrl(getUrlFromPhotoAttachment((PhotoAttachment) attachment));
} else if (attachment instanceof DocumentAttachment) {
var documentAttachment = (DocumentAttachment) attachment;
if (documentAttachment.J != null)
try {
copyPhotoUrl(getUrlFromDocumentAttachment(documentAttachment));
} catch (Exception e) {
ToastUtils.a(getString("photo_get_error"));
}
else
ToastUtils.a(getString("photo_get_error"));
}
return null;
}
);
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));
if (attachment instanceof PhotoAttachment) {
openUrl(getUrlFromPhotoAttachment((PhotoAttachment) attachment));
} else if (attachment instanceof DocumentAttachment) {
var documentAttachment = (DocumentAttachment) attachment;
if (documentAttachment.J != null)
try {
openUrl(getUrlFromDocumentAttachment(documentAttachment));
} catch (Exception e) {
ToastUtils.a(getString("photo_get_error"));
}
else
ToastUtils.a(getString("photo_get_error"));
}
return null;
}
);
}
private static String getUrlFromAttachment(PhotoAttachment attachment) {
private static String getUrlFromDocumentAttachment(DocumentAttachment attachment) {
List<ImageSize> imageSizes = null;
if (attachment.J != null) {
imageSizes = attachment.J.t1();
}
return getUrlFromImageSizeList(imageSizes != null ? imageSizes : null);
}
private static String getUrlFromPhotoAttachment(PhotoAttachment attachment) {
var imageSizes = attachment.D.Q.t1();
return getUrlFromImageSizeList(imageSizes);
}
@Nullable
private static String getUrlFromImageSizeList(List<ImageSize> imageSizes) {
if (imageSizes.isEmpty())
return null;
var max = imageSizes.get(0);
@@ -99,7 +156,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 +180,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 +210,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,82 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.utils.Preferences.preferences;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import com.facebook.drawee.generic.RoundingParams;
import ru.vtosters.lite.utils.AndroidUtils;
public class PicRoundingHook{
private static final int pref = preferences.getInt("pic_rounding", 0);
public static RoundingParams inject() {
if (pref > 0) {
return customParams();
} else {
return new RoundingParams().a(true);
}
}
public static RoundingParams inject(float orig) {
if (pref > 0) {
return customParams();
} else {
return new RoundingParams().b(orig);
}
}
public static RoundingParams inject(float orig, float orig2, float orig3, float orig4) {
if (pref > 0) {
return new RoundingParams().a(AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref));
} else {
return new RoundingParams().a(orig, orig2, orig3, orig4);
}
}
public static void inject(float orig, Canvas canvas, Paint paint){
if (pref > 0) {
canvas.drawRoundRect(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), paint);
} else {
canvas.drawCircle(orig, orig, orig, paint);
}
}
public static void inject(Canvas canvas, Paint paint, float orig){
if (pref > 0) {
canvas.drawRoundRect(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), paint);
} else {
canvas.drawCircle(canvas.getClipBounds().exactCenterX(), canvas.getClipBounds().exactCenterY(), orig, paint);
}
}
public static void inject(Canvas canvas, float orig, float orig2, float orig3, Paint paint){
if (pref > 0) {
canvas.drawRoundRect(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), paint);
} else {
canvas.drawCircle(orig, orig2, orig3, paint);
}
}
public static void inject(Bitmap bitmap, Bitmap bitmap2, Paint b2) {
Shader.TileMode tileMode = Shader.TileMode.CLAMP;
b2.setShader(new BitmapShader(bitmap2, tileMode, tileMode));
Canvas canvas = new Canvas(bitmap);
float width = bitmap2.getWidth() / 2;
if (pref > 0) {
canvas.drawRoundRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), b2);
} else {
canvas.drawCircle(width, width, width, b2);
}
}
private static RoundingParams customParams(){
return RoundingParams.b(AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref), AndroidUtils.dp2px(pref));
}
}
@@ -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,19 +1,19 @@
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.proxy.ProxyUtils.isRandomProxyEnabled;
import static ru.vtosters.lite.proxy.ProxyUtils.isVikaProxyEnabled;
import static ru.vtosters.lite.proxy.ProxyUtils.isZaboronaEnabled;
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
import static ru.vtosters.lite.utils.AndroidUtils.edit;
import static ru.vtosters.lite.utils.LifecycleUtils.restartApplication;
import static ru.vtosters.lite.utils.ThemesUtils.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;
import android.content.DialogInterface;
import android.content.Intent;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.widget.RadioButton;
@@ -26,57 +26,74 @@ import com.vk.auth.ui.VkAuthTextView;
import com.vk.navigation.Navigator;
import ru.vtosters.lite.ui.fragments.ProxySettingsFragment;
import ru.vtosters.lite.utils.AndroidUtils;
public class ProxyHook{
public static void hookAuth(View v){
public class ProxyHook {
public static void hookAuth(View v) {
VkAuthTextView button = (VkAuthTextView) v;
button.setText("Настроить прокси");
button.setText(AndroidUtils.getString("proxy_setup"));
button.setOnClickListener(v1 -> callProxyDialog(v1.getContext()));
}
@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));
RadioButton rgProxy = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
RadioButton rgZaborona = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
RadioButton rgRandomProxy = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
RadioButton rgVika = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
rg.addView(rgDefault);
rg.addView(rgProxy);
rg.addView(rgVika);
rg.addView(rgZaborona);
rg.addView(rgRandomProxy);
rgDefault.setTextSize(TypedValue.COMPLEX_UNIT_PX, convertDpToPixel(14f));
rgProxy.setTextSize(TypedValue.COMPLEX_UNIT_PX, convertDpToPixel(14f));
rgDefault.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
rgZaborona.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
rgRandomProxy.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
rgVika.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.setText(AndroidUtils.getString("proxy_disable"));
rgDefault.setTextColor(getTextAttr());
rgProxy.setText("Включить (Zaborona)");
rgProxy.setTextColor(getTextAttr());
rgZaborona.setText(AndroidUtils.getString("proxy_enable") + " (Zaborona)");
rgZaborona.setTextColor(getTextAttr());
rgProxy.setChecked(isZaboronaEnabled());
rgDefault.setChecked(!isZaboronaEnabled());
rgRandomProxy.setText(AndroidUtils.getString("proxy_enable") + " (Random Socks Proxy)");
rgRandomProxy.setTextColor(getTextAttr());
rgVika.setText(AndroidUtils.getString("proxy_enable") + " (Vika Mobile)");
rgVika.setTextColor(getTextAttr());
rgZaborona.setChecked(isZaboronaEnabled());
rgDefault.setChecked(!isZaboronaEnabled() && !isRandomProxyEnabled() && !isVikaProxyEnabled());
rgRandomProxy.setChecked(isRandomProxyEnabled());
rgVika.setChecked(isVikaProxyEnabled());
AlertDialog.Builder builder = new AlertDialog.Builder(ctx, getAlertStyle());
builder.setTitle("Прокси");
builder.setMessage("Zaborona никак не связана с ВТостерс и мы не можем гарантировать её работу и безопасность");
builder.setTitle(AndroidUtils.getString("vtlproxy"));
builder.setMessage(AndroidUtils.getString("proxy_warning"));
builder.setView(rg);
builder.setPositiveButton("Применить", ((dialog, which) -> {
if (rgProxy.isChecked()) {
builder.setPositiveButton(AndroidUtils.getString("vtl_confirm"), ((dialog, which) -> { // Применить
if (rgZaborona.isChecked()) {
edit().putString("proxy", "zaborona").commit();
restartApplication();
} else if (rgRandomProxy.isChecked()) {
edit().putString("proxy", "randomproxy").commit();
restartApplication();
} else if (rgVika.isChecked()) {
edit().putString("proxy", "vika").commit();
restartApplication();
} else {
if (isZaboronaEnabled()) {
edit().putString("proxy", "noproxy").commit();
restartApplication();
}
edit().putString("proxy", "noproxy").commit();
restartApplication();
}
}));
builder.setNeutralButton("Настройки прокси", ((dialog, which) -> {
builder.setNeutralButton(AndroidUtils.getString("proxy_settings"), ((dialog, which) -> {
Intent a2 = new Navigator(ProxySettingsFragment.class).b(ctx);
a2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ctx.startActivity(a2);
@@ -89,47 +106,4 @@ public class ProxyHook{
alert.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(getAccentColor());
alert.getButton(DialogInterface.BUTTON_NEUTRAL).setTextColor(getAccentColor());
}
public static String linkReplacer(String link){
var vkapi = "api.vk.com";
var oauth = "oauth.vk.com";
var vkstatic = "static.vk.com";
var proxyapi = getPrefsValue("proxyapi");
var proxyoauth = getPrefsValue("proxyoauth");
var proxystatic = getPrefsValue("proxystatic");
if (!apiproxy() || link.isEmpty()) {
return link;
}
if (proxyapi.isEmpty() || proxyoauth.isEmpty() || proxystatic.isEmpty()) {
Log.d("VTLite", "Proxy is not set" + " " + proxyapi + " " + proxyoauth + " " + proxystatic);
return link;
}
if (link.contains(vkapi)) {
return link.replace(proxyapi, vkapi);
}
if (link.contains(oauth)) {
return link.replace(proxyoauth, oauth);
}
if (link.contains(vkstatic)) {
return link.replace(proxystatic, vkstatic);
}
return link;
}
public static String getAwayPhpCom(){
var proxyapi = getPrefsValue("proxyapi");
if (apiproxy() & !proxyapi.isEmpty()) {
return proxyapi;
}
return "m.vk.com";
}
}
@@ -0,0 +1,25 @@
package ru.vtosters.lite.hooks;
import static ru.vtosters.lite.encryption.EncryptProvider.decryptMessage;
import com.vk.im.engine.models.ProfilesSimpleInfo;
import com.vk.im.engine.models.messages.MsgFromUser;
import com.vk.im.engine.models.messages.NestedMsg;
import com.vk.im.ui.views.ReplyView;
public class ReplyMsgHook {
public static void injectWithDecrypt(ReplyView replyView, MsgFromUser msgFromUser, ProfilesSimpleInfo profilesSimpleInfo, boolean someBool) {
msgFromUser.d(decryptMessage(msgFromUser)); // set new value of text in MsgFromUser class
replyView.a(msgFromUser, profilesSimpleInfo, someBool);
}
public static void injectWithDecrypt(ReplyView replyView, NestedMsg nestedMsg, ProfilesSimpleInfo profilesSimpleInfo, boolean someBool) {
nestedMsg.d(decryptMessage(nestedMsg.f(), nestedMsg.t1())); // set new value of text in NestedMsg class
replyView.a(nestedMsg, profilesSimpleInfo, someBool);
}
public static void injectWithDecrypt(ReplyView replyView, NestedMsg nestedMsg, ProfilesSimpleInfo profilesSimpleInfo, boolean someBool, int i) {
if ((i & 4) != 0) someBool = false;
injectWithDecrypt(replyView, nestedMsg, profilesSimpleInfo, someBool);
}
}
@@ -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<String, String> params, String apiver) {
if (method.contains("execute.getGiftByStickerId") ) {
apiver = "5.186";
}
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,6 +1,7 @@
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;
@@ -8,12 +9,11 @@ import static ru.vtosters.lite.utils.Preferences.useNewSettings;
import static ru.vtosters.lite.utils.Preferences.vkme;
import com.vk.apps.AppsFragment;
import com.vk.discover.ThemedFeedFragment;
import com.vk.discover.DiscoverFragment;
import com.vk.fave.fragments.FaveTabFragment;
import com.vk.menu.MenuFragment;
import com.vk.menu.SearchMenuFragment;
import com.vk.music.fragment.MusicCatalogFragment1;
import com.vk.music.fragment.MusicFragment;
import com.vk.newsfeed.HomeFragment;
import com.vk.newsfeed.NewsfeedFragment;
import com.vk.notifications.NotificationsContainerFragment;
@@ -27,16 +27,17 @@ import com.vtosters.lite.fragments.money.MoneyTransfersFragment;
import com.vtosters.lite.fragments.p2.DocumentsViewFragment;
import com.vtosters.lite.fragments.s2.GroupsFragment1;
import com.vtosters.lite.fragments.t2.c.DialogsFragment;
import com.vtosters.lite.fragments.y2.VideoCatalogFragment;
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":
@@ -44,19 +45,19 @@ public class StartFragmentHook{
case "groups":
return milkshake() ? CommunitiesCatalogFragment.class : GroupsFragment1.class;
case "music":
return getBoolValue("musicnewcatalog", true) ? MusicCatalogFragment1.class : MusicFragment.class;
return MusicCatalogFragment1.class;
case "friends":
return FriendsFragment.class;
case "photos":
return PhotosFragment.class;
case "videos":
return VideosFragment.class;
return VideoCatalogFragment.class;
case "settings":
return useNewSettings();
case "apps":
return AppsFragment.class;
case "discover":
return ThemedFeedFragment.class;
return DiscoverFragment.class;
case "notifications":
return NotificationsContainerFragment.class;
case "money":
@@ -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,20 +1,18 @@
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.musicnewcatalog;
import static ru.vtosters.lite.utils.Preferences.miniapps;
import static ru.vtosters.lite.utils.Preferences.postsredesign;
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,11 +42,8 @@ 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_MUSIC_STOP_PLAYER_ON_TASK_REMOVAL:
case FEATURE_MUS_PUSH_RES_COUNT:
case FEATURE_NARRATIVE_SNIPPET_TYPE:
case FEATURE_NEWS_GAMES_IN_DISCOVER:
case FEATURE_NEWS_HEADER_SCROLL:
@@ -126,8 +121,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:
@@ -137,16 +132,12 @@ public class TogglesHook{
case FEATURE_MILKSHAKE_FORCE_DISABLED:
case FEATURE_MILKSHAKE_ACTIVATION_DISABLED:
return !milkshake();
case FEATURE_MUSIC_NEW_CATALOG:
return musicnewcatalog();
case AB_NEWS_VIDEO_LAYOUT_TEXT:
case FEATURE_COMPACT_REPOST:
case EXPERIMENT_NEWS_VIDEO_LAYOUT_TEXT:
return postsredesign();
case FEATURE_IMAGE_QUALITY_UPGRADE:
return !getBoolValue("compressPhotos", true);
case FEATURE_MUSIC_STOP_PLAYER_ON_TASK_REMOVAL:
return getBoolValue("musictask", false);
case FEATURE_MENU_GAMES_CAROUSEL:
return miniapps();
default:
@@ -154,7 +145,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();
}
}
@@ -0,0 +1,52 @@
package ru.vtosters.lite.hooks.ui;
import android.util.Log;
import com.vk.dto.music.MusicTrack;
import com.vk.dto.music.Playlist;
import com.vk.music.bottomsheets.a.MusicAction;
import com.vk.music.common.MusicPlaybackLaunchContext;
import com.vtosters.lite.R;
import java.util.ArrayList;
import bruhcollective.itaysonlab.libvkx.client.LibVKXClient;
import bruhcollective.itaysonlab.libvkx.client.LibVKXClientImpl;
import ru.vtosters.lite.utils.AndroidUtils;
public class MusicBottomSheetHook {
public static ArrayList<MusicAction> hook(ArrayList<MusicAction> actions) {
if (LibVKXClient.isVkxInstalled()) {
actions.add(getPlayInVKXAction());
}
return actions;
}
public static boolean tryPlayInVKX(int actionId, MusicTrack track, MusicPlaybackLaunchContext context, Playlist playlist) {
if (actionId != AndroidUtils.getIdentifier("play_in_vkx", "id")) {
return false;
}
var trackList = new ArrayList<MusicTrack>();
if (playlist != null) {
trackList.addAll(playlist.R);
} else {
trackList.add(track);
}
LibVKXClientImpl.LibVKXAction action = iLibVkxService -> LibVKXClient.lambdaplay(trackList, track, iLibVkxService, context);
return LibVKXClient.getInstance().runOnService(action);
}
private static MusicAction getPlayInVKXAction() {
return new MusicAction(
AndroidUtils.getIdentifier("play_in_vkx", "id"),
R.drawable.ic_music_24,
AndroidUtils.getIdentifier("play_in_vkx", "string"),
R.color.caption_gray,
R.string.music_talkback_empty,
false
);
}
}
@@ -0,0 +1,24 @@
package ru.vtosters.lite.hooks.ui;
import android.content.res.Configuration;
import ru.vtosters.lite.utils.Preferences;
import ru.vtosters.lite.utils.ThemesUtils;
public class SystemThemeChangerHook {
public static void onThemeChanged(Configuration configuration) {
if (Preferences.systemtheme()) {
switch (configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK) {
case Configuration.UI_MODE_NIGHT_YES:
// Night mode is active, we're using dark theme
ThemesUtils.applyTheme(ThemesUtils.getDarkTheme());
break;
case Configuration.UI_MODE_NIGHT_NO:
case Configuration.UI_MODE_NIGHT_UNDEFINED:
// Night mode is not active, we're using light theme
ThemesUtils.applyTheme(ThemesUtils.getLightTheme());
break;
}
}
}
}
@@ -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");
ToastUtils.a(AndroidUtils.getString("ffmpegkit_copy"));
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();
}
}

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