Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e12f50a7f | ||
|
|
9ff220475d | ||
|
|
2c6619a512 | ||
|
|
5ea599b61e | ||
|
|
4eea4e2011 | ||
|
|
f1a7816e69 | ||
|
|
12c01133e1 | ||
|
|
3856932a3f | ||
|
|
a10c333cc6 | ||
|
|
4d950e5c68 | ||
|
|
c72e102076 | ||
|
|
43f3df487b | ||
|
|
ca48f97d83 | ||
|
|
b69beff4d2 | ||
|
|
67401c6868 | ||
|
|
9fa8df30eb | ||
|
|
ecf896e44e | ||
|
|
58a9b69dd9 | ||
|
|
26a64545ff | ||
|
|
05c557a8f7 | ||
|
|
c8c8678785 | ||
|
|
4e6eb74a8e | ||
|
|
52cb007a67 | ||
|
|
657d038d9c | ||
|
|
de4d283f75 | ||
|
|
3b37412a58 | ||
|
|
dd6b9b32b8 | ||
|
|
31a456582b | ||
|
|
6ab317cbf5 | ||
|
|
32c469d870 | ||
|
|
e0f09cea24 | ||
|
|
e668cfb2a3 | ||
|
|
857b63a356 | ||
|
|
0c03406774 | ||
|
|
ac3cb847f4 | ||
|
|
05ed60b86d | ||
|
|
020ec70221 | ||
|
|
478825e708 | ||
|
|
6ce0e630db | ||
|
|
6e538f44b5 | ||
|
|
bd3bec2a31 | ||
|
|
cf25e39485 | ||
|
|
1f87d7a403 | ||
|
|
10da74285c | ||
|
|
3a2607274f | ||
|
|
6cbe7caec1 | ||
|
|
452b4aa667 | ||
|
|
c4d77e40f4 | ||
|
|
3c9a787a77 | ||
|
|
d400da3ab9 | ||
|
|
ded67ac699 | ||
|
|
2c3d78b0b4 | ||
|
|
ed9701a04b | ||
|
|
9af33a4a01 | ||
|
|
481abbc3d8 | ||
|
|
d9065c3073 | ||
|
|
46295e5216 | ||
|
|
5eeff2f08d | ||
|
|
341a368656 | ||
|
|
f9657af36c | ||
|
|
5bead1b88f | ||
|
|
c4d915e60d | ||
|
|
834f70b585 | ||
|
|
a5243e6839 | ||
|
|
03487678ac | ||
|
|
c482e82ebe | ||
|
|
14ecc21937 | ||
|
|
65aa04a7e3 | ||
|
|
d8e1ce12f7 | ||
|
|
9a84b5b87d | ||
|
|
0a42040188 | ||
|
|
8e66f75baf | ||
|
|
72e1371fe0 | ||
|
|
e9c8170ee4 | ||
|
|
330793f8bc | ||
|
|
45015c571f | ||
|
|
b6fcf0330d | ||
|
|
cc95856e47 | ||
|
|
cbab131610 | ||
|
|
879c218f0c | ||
|
|
ef0e2caabf | ||
|
|
d4ab0a1366 | ||
|
|
9cbc45dea3 | ||
|
|
b6133da808 | ||
|
|
59fb11dbaa | ||
|
|
3de88254f6 | ||
|
|
306338992e | ||
|
|
3476e4eed4 | ||
|
|
be2b7c99fc | ||
|
|
1e16a43b1e | ||
|
|
e8dea04d5d | ||
|
|
7d3c4ce4a6 | ||
|
|
b49813e2b1 | ||
|
|
9bd5cafc2d | ||
|
|
433801a9d0 | ||
|
|
3dd4e4df38 | ||
|
|
3c90940695 | ||
|
|
c7e5c57248 | ||
|
|
0fbdccbecc | ||
|
|
c5a0d7d05c | ||
|
|
d365cd9068 | ||
|
|
6ea4822f41 | ||
|
|
cc16f4727f | ||
|
|
79c2fc9010 | ||
|
|
e9047274b3 | ||
|
|
5f57558c52 | ||
|
|
3c8b394a4b | ||
|
|
f5037dced3 | ||
|
|
274e1bd0df | ||
|
|
32daac436e | ||
|
|
820ca12c3e | ||
|
|
f3cda292e0 | ||
|
|
75c98b98dd | ||
|
|
cc6e3c2dd8 | ||
|
|
9a9a73e89a | ||
|
|
a6f52af5d1 | ||
|
|
fa12e8f7e0 | ||
|
|
3a7a05e630 | ||
|
|
e05fe77fb4 | ||
|
|
b86128ac66 | ||
|
|
3e9058002b | ||
|
|
76775f0ad4 | ||
|
|
086210718c | ||
|
|
bc1f11da61 | ||
|
|
63075ca216 | ||
|
|
4876a881d2 | ||
|
|
fef7082e66 | ||
|
|
4dc7223629 | ||
|
|
9fbb2fada4 | ||
|
|
a31d75ea41 | ||
|
|
efa28aa3d6 | ||
|
|
9dd3a26bab | ||
|
|
f49bc4d05d | ||
|
|
0ca4ba2697 | ||
|
|
09333dc64d | ||
|
|
91bfea9917 | ||
|
|
042595f238 | ||
|
|
174151b52b | ||
|
|
7fed263a0e | ||
|
|
79fd0350e4 | ||
|
|
4f760b5a4d | ||
|
|
f19a4275de | ||
|
|
7e36bbf83e | ||
|
|
0a7338bf89 | ||
|
|
c1197e461b | ||
|
|
7baaf08167 | ||
|
|
0d75bec938 | ||
|
|
0af00ab7d1 | ||
|
|
2011901666 | ||
|
|
b75ce047df | ||
|
|
bfd258ba54 | ||
|
|
e499d98050 | ||
|
|
7299c9e33a | ||
|
|
4d0573ffe5 | ||
|
|
83d13dce1e | ||
|
|
55dbb029c0 | ||
|
|
3df51d0685 | ||
|
|
9bc87a1d79 | ||
|
|
94667ac741 | ||
|
|
3a354b359a | ||
|
|
09443d6ec1 | ||
|
|
ca27776aaf | ||
|
|
3b6cdacf96 | ||
|
|
c7621c44d5 | ||
|
|
89997317bf | ||
|
|
c87be6c9b8 | ||
|
|
4ae5ea8e57 | ||
|
|
b967e72a04 | ||
|
|
cc66af3e3a | ||
|
|
f82ef2f64e | ||
|
|
646329f93b | ||
|
|
3f7b9eb796 | ||
|
|
a3d8a9ba70 | ||
|
|
8d05973848 | ||
|
|
2b553d263c | ||
|
|
265d3afbff | ||
|
|
858fced1aa | ||
|
|
a01d12b012 | ||
|
|
8bde61b059 | ||
|
|
05eec57058 | ||
|
|
c2a1a4bb5f | ||
|
|
5e01ebcff6 | ||
|
|
ffe0955ef1 | ||
|
|
f4ca7c9e66 | ||
|
|
57b19369a0 | ||
|
|
4019219293 | ||
|
|
5d6c001dfb | ||
|
|
1f2b1b1180 | ||
|
|
cb7862a0e2 | ||
|
|
1cd23341e2 | ||
|
|
f85dac2ff8 | ||
|
|
992b29894e | ||
|
|
9e67ded6bd | ||
|
|
24607e1ea5 | ||
|
|
8e260a9de4 | ||
|
|
de045f749a | ||
|
|
fde1628fac | ||
|
|
fdeaa05360 | ||
|
|
d0197142cd | ||
|
|
8257393909 | ||
|
|
9542317b23 | ||
|
|
de595c93f4 | ||
|
|
7596b4117a | ||
|
|
8b6ef6d3af | ||
|
|
1d71def416 | ||
|
|
18799ce11c | ||
|
|
b4e34e34b1 | ||
|
|
cd6f975e56 | ||
|
|
de73c6216b | ||
|
|
129ae95121 | ||
|
|
78cd5cac9a | ||
|
|
f7fab596ba | ||
|
|
85afaa5057 | ||
|
|
f1ed0fc221 | ||
|
|
b64b17038d | ||
|
|
e5b5bf9d48 | ||
|
|
c58e511040 | ||
|
|
a067a35040 | ||
|
|
dbee2a5a42 | ||
|
|
104ca05772 | ||
|
|
ad5eca635a | ||
|
|
6c86b49e97 | ||
|
|
ad8f2b5b5a | ||
|
|
3058c220a8 | ||
|
|
6531a21fb4 | ||
|
|
3366d28e7e | ||
|
|
39b08702d5 | ||
|
|
b90b27e8ce | ||
|
|
9b03299c7b | ||
|
|
a9343c6777 | ||
|
|
a03505f27f | ||
|
|
b9126aa184 | ||
|
|
613a101c82 | ||
|
|
43fe0577cd | ||
|
|
6208c966d0 | ||
|
|
636341b4f2 | ||
|
|
576ce7d6b0 | ||
|
|
e74001e17e | ||
|
|
48f6b35abe | ||
|
|
5beea5d273 | ||
|
|
842130628e | ||
|
|
ab26bab35d | ||
|
|
6ffcbe8329 | ||
|
|
ca3d1e9585 | ||
|
|
05a9e9a12c | ||
|
|
9e2f3bb048 | ||
|
|
91aef33725 | ||
|
|
32c5aa9ac2 | ||
|
|
e32c3ec74b | ||
|
|
3fea0e9c40 | ||
|
|
c9c5c96d63 | ||
|
|
2a91238b4f | ||
|
|
e4d740061d | ||
|
|
f96f2cb7d7 | ||
|
|
0482f75172 | ||
|
|
eaed8fc752 | ||
|
|
f871e63002 | ||
|
|
189d699d48 | ||
|
|
f3b6b3c1b0 | ||
|
|
519722d613 | ||
|
|
3aaca80da1 | ||
|
|
b889015368 | ||
|
|
1d3463df0c | ||
|
|
60ac497e6d | ||
|
|
f8192c7169 | ||
|
|
3f2e0c9b98 | ||
|
|
2a9ea90df5 | ||
|
|
aa40bbb390 | ||
|
|
4782401f0a | ||
|
|
0255cfb1b9 | ||
|
|
764b68d47f | ||
|
|
126154fc9b | ||
|
|
ec2df87e42 | ||
|
|
e963080385 | ||
|
|
23286a21f0 | ||
|
|
4e48faec16 | ||
|
|
666c562092 | ||
|
|
4f5cbe426a | ||
|
|
5635cd4139 | ||
|
|
4bb31d492a | ||
|
|
f85fe81881 | ||
|
|
5295e465e9 | ||
|
|
7f30e66c0c | ||
|
|
d55361fd72 | ||
|
|
63d1c1a3b0 | ||
|
|
4cc6bfabd0 | ||
|
|
802f639633 | ||
|
|
8a90602328 | ||
|
|
6f607e9ae8 | ||
|
|
dd0f238701 | ||
|
|
600a9da953 | ||
|
|
d14dec88bc | ||
|
|
6e216830d1 | ||
|
|
2b6012b1e7 | ||
|
|
ded283df35 | ||
|
|
86a5c60f7f | ||
|
|
1d964762ca | ||
|
|
4a2d2b23f2 | ||
|
|
a06d129c8d | ||
|
|
a0b1adbfe9 | ||
|
|
0093463fae | ||
|
|
9e572d7844 | ||
|
|
900dbcfe0a | ||
|
|
e3e06d1638 | ||
|
|
69a4cfa715 | ||
|
|
21d9c13fdf | ||
|
|
09bf8e26ce | ||
|
|
21c0ccd9fc | ||
|
|
aa95b368f8 | ||
|
|
4be234632c | ||
|
|
00d37e3721 | ||
|
|
4c4a3ae11c | ||
|
|
7e09e6d4e6 | ||
|
|
b92fa69628 | ||
|
|
d127a84b07 | ||
|
|
95916b4289 | ||
|
|
5cb5d06993 | ||
|
|
f0da269968 | ||
|
|
2fb021ad05 | ||
|
|
1981bc9d14 | ||
|
|
c60cce5467 | ||
|
|
2035d513f1 | ||
|
|
3849569794 | ||
|
|
9f2f6d6f60 | ||
|
|
586a82a15f | ||
|
|
eba922871f | ||
|
|
337aa7493e | ||
|
|
1ed9f871c3 | ||
|
|
083d96707c | ||
|
|
10e0bd50da | ||
|
|
2864056186 | ||
|
|
8876a66449 | ||
|
|
41a1d29c4b | ||
|
|
1bb10807c4 | ||
|
|
7f8100660a | ||
|
|
274a1b9fa8 | ||
|
|
03c5f83a42 | ||
|
|
f394bdfec5 | ||
|
|
19c9dd102f | ||
|
|
d38038f848 | ||
|
|
8ab5cdd860 | ||
|
|
2f30d070ec | ||
|
|
401fc44e91 | ||
|
|
028b3aad59 | ||
|
|
8a7c21c549 | ||
|
|
918967f502 | ||
|
|
95636ad4f4 | ||
|
|
561afe8765 | ||
|
|
929e481b3d | ||
|
|
69266ed31f | ||
|
|
742e0c46b3 | ||
|
|
319f3c421a | ||
|
|
3b5eb3cd10 | ||
|
|
55f71bfd8b | ||
|
|
1ac755a98b | ||
|
|
00d0b9d237 | ||
|
|
edd04586ea | ||
|
|
98b1cf8db3 | ||
|
|
d20296d4b8 | ||
|
|
7c8627f9f6 | ||
|
|
2e2be2fe4a | ||
|
|
673d5fe16c | ||
|
|
4a949e7d45 | ||
|
|
39391a4ace | ||
|
|
9a9552c369 | ||
|
|
6b9f80284c | ||
|
|
15dd2b2fde | ||
|
|
4b2a537e3b | ||
|
|
a94ca687eb | ||
|
|
06f0864cc3 | ||
|
|
1ddc2f6b14 | ||
|
|
ad6c350e69 | ||
|
|
dadbc37189 | ||
|
|
d646a0cd19 | ||
|
|
ae145691c5 | ||
|
|
a6cbf35350 | ||
|
|
aba12ad48a | ||
|
|
32ebf0e4f4 | ||
|
|
099de74ac1 | ||
|
|
dd490abf69 | ||
|
|
3468b9352e | ||
|
|
af0efb7184 | ||
|
|
592d25bf6d | ||
|
|
a53f1d7299 | ||
|
|
ea3707cebd | ||
|
|
b2ba9774bc | ||
|
|
7205c78839 | ||
|
|
26672cfbc2 | ||
|
|
941335ec02 | ||
|
|
8bbf0ebb1f | ||
|
|
9d16d4e57e | ||
|
|
cece5a2a55 | ||
|
|
fb907d68a4 | ||
|
|
dac2e10a52 | ||
|
|
0e472e985b | ||
|
|
e349193afb | ||
|
|
066beb14f1 | ||
|
|
15f8af1e3e | ||
|
|
599ee3dfab | ||
|
|
9d005cd2e0 | ||
|
|
c8747ea957 | ||
|
|
6bc33dbb31 | ||
|
|
303fe83ff9 | ||
|
|
cb122bb6c8 | ||
|
|
bb73aaa580 | ||
|
|
7e7730e825 | ||
|
|
8f291b058f | ||
|
|
0f9ab88e68 | ||
|
|
36c244be15 | ||
|
|
71d4cd09fc | ||
|
|
037f1809e8 | ||
|
|
3513844ca5 | ||
|
|
2e180d2c9c | ||
|
|
fd3eae0283 | ||
|
|
048a835b2b | ||
|
|
e144390d4f | ||
|
|
320892cdf5 | ||
|
|
1716aa51dd | ||
|
|
7157a0c664 | ||
|
|
34787ffb5b | ||
|
|
d44b363d1d | ||
|
|
3972ceba5b | ||
|
|
505a2d4553 | ||
|
|
84da0b422a | ||
|
|
ab19f6b71a | ||
|
|
9c8f962e5f | ||
|
|
ad706355cd | ||
|
|
efac38a871 | ||
|
|
049940f3bb | ||
|
|
5f68809d9c | ||
|
|
930792f983 | ||
|
|
5e7eb51127 | ||
|
|
99a387f9a0 | ||
|
|
679960045a | ||
|
|
1dc1436082 | ||
|
|
2ba602ae9f | ||
|
|
98aa6ef0f8 | ||
|
|
b8f5b0179a | ||
|
|
877670bb84 | ||
|
|
5859b93612 | ||
|
|
0f33dfc395 | ||
|
|
0330b8ad8e | ||
|
|
7d85d61eb5 | ||
|
|
28ee64fc30 | ||
|
|
19bc27059d | ||
|
|
457822de7d | ||
|
|
4c5d83fccc | ||
|
|
92c9ea2222 | ||
|
|
e6b7ea8c2c | ||
|
|
81bc85a0aa | ||
|
|
f9b02b1cce | ||
|
|
2cb6321776 | ||
|
|
bbf0ada834 | ||
|
|
8c63ff69c7 | ||
|
|
94c72eb490 | ||
|
|
d1f2a78a48 | ||
|
|
2983afcda5 | ||
|
|
fe87a5dd64 | ||
|
|
9daa346e31 | ||
|
|
816683ac8a | ||
|
|
b90fd41bf2 | ||
|
|
991f1f9eb8 | ||
|
|
2ae9df03e1 | ||
|
|
665e2dda05 | ||
|
|
a5134f1cd5 | ||
|
|
3680ff44a2 | ||
|
|
34ae44016d | ||
|
|
a0ebc913d1 | ||
|
|
1afa317e7b | ||
|
|
84c194d318 | ||
|
|
56cd2b2d39 | ||
|
|
b001517a63 | ||
|
|
cd389af2bd | ||
|
|
69a2f03656 | ||
|
|
047b547449 | ||
|
|
0912f57184 | ||
|
|
568f69db60 | ||
|
|
511c16771d | ||
|
|
321273c54a | ||
|
|
f6e0a7edb4 | ||
|
|
dd9b2a8a58 | ||
|
|
77f80883ae | ||
|
|
ec5b8b3455 | ||
|
|
cd611afbd3 | ||
|
|
943c612581 | ||
|
|
2ed8082df2 | ||
|
|
4806d97e29 | ||
|
|
c603c9844a | ||
|
|
a3b1220f18 | ||
|
|
18582c535a | ||
|
|
d002d05b2a | ||
|
|
c198a14e0c | ||
|
|
deda04cbf8 | ||
|
|
021e85d5b8 | ||
|
|
0921485959 | ||
|
|
82aacf32b7 | ||
|
|
e7b0ae0225 | ||
|
|
2fb7778717 | ||
|
|
a993993773 | ||
|
|
6f49e35b22 | ||
|
|
ea277c303f | ||
|
|
a7652e4e71 | ||
|
|
5cb7306613 | ||
|
|
1ddecb47af | ||
|
|
ac2c972b9b | ||
|
|
86798ffb59 | ||
|
|
a85a7d84b2 | ||
|
|
1ed90da1b8 | ||
|
|
a2b231f365 | ||
|
|
a618b2cc5b | ||
|
|
4e4c287111 | ||
|
|
060f24b6c6 | ||
|
|
d3840bf9fd | ||
|
|
ba216cb06b | ||
|
|
917f5b565f | ||
|
|
938c6ff633 | ||
|
|
56bf382618 | ||
|
|
eb3cc75a98 | ||
|
|
f3e3cdf79a | ||
|
|
ad808263d1 | ||
|
|
53616c8bc6 | ||
|
|
466105d69c | ||
|
|
64c9cff0bb | ||
|
|
8fbbf8b6be | ||
|
|
6c0d5619e4 | ||
|
|
c3c41f9d2e | ||
|
|
a154138fb5 | ||
|
|
0bf6821a4b | ||
|
|
470ac9dd4d | ||
|
|
b68b10f776 | ||
|
|
c06f2588a8 | ||
|
|
f6ade7a059 | ||
|
|
08d7851de3 | ||
|
|
78902110eb | ||
|
|
b7b9de4ba4 | ||
|
|
83014931dc | ||
|
|
46edd53cb6 | ||
|
|
87b1251f5a | ||
|
|
4ce73d9e55 | ||
|
|
4541ef61c1 | ||
|
|
4f3f26e3f5 | ||
|
|
1f235bfc4a | ||
|
|
548a029db2 | ||
|
|
6d1b964239 | ||
|
|
487cb6c076 | ||
|
|
5a372f6c60 | ||
|
|
81f954d25a | ||
|
|
ec3248f5c3 | ||
|
|
c959d5e5d6 | ||
|
|
49798694b2 | ||
|
|
3879555297 | ||
|
|
fc11e2d055 | ||
|
|
4905e8fed0 | ||
|
|
9a02f2a7c3 | ||
|
|
03014f245c | ||
|
|
13f247467c | ||
|
|
5116f507c5 | ||
|
|
228e6ea282 | ||
|
|
7663d4cee2 | ||
|
|
4e003d355e | ||
|
|
75982656b1 | ||
|
|
2f12cb188f | ||
|
|
46cd9c0582 | ||
|
|
8be76aa871 | ||
|
|
9d9c02bec5 | ||
|
|
30faa329e9 | ||
|
|
0a9322741c | ||
|
|
f68cc4a6bd | ||
|
|
0717fd960e | ||
|
|
0dcb2b8fd7 | ||
|
|
2581b5a1a2 | ||
|
|
36cd21f7f6 | ||
|
|
e09a6291fe | ||
|
|
f800dffb5f | ||
|
|
86ba91a77e | ||
|
|
6aade65b4b | ||
|
|
ba1aeeb4b1 | ||
|
|
4467abc181 | ||
|
|
75960a7631 | ||
|
|
8209aa6fdf | ||
|
|
38bcd40ad6 | ||
|
|
dbc358d0a0 | ||
|
|
dcb2244498 | ||
|
|
e3b6bd8219 | ||
|
|
07f1f62fb7 | ||
|
|
89f94df42b | ||
|
|
b3197aa921 | ||
|
|
cfc2c67efc | ||
|
|
d3b1e6e075 | ||
|
|
b221a8d55d | ||
|
|
9cc6d4f8e0 | ||
|
|
1a0a24df45 | ||
|
|
f74b2b1acf | ||
|
|
c7b5b7d6ca | ||
|
|
215d747dad | ||
|
|
c10b3e5619 | ||
|
|
f03d4892a2 | ||
|
|
6c84540a5d | ||
|
|
664e1fe428 | ||
|
|
328b2caecb | ||
|
|
0799757097 | ||
|
|
8c9fee306f | ||
|
|
c23624ab11 | ||
|
|
ea4315274b | ||
|
|
947183ff02 | ||
|
|
dbe80696d6 | ||
|
|
1296ab56a7 | ||
|
|
bda751e692 | ||
|
|
5135cfa347 | ||
|
|
c450ef7f87 | ||
|
|
bd470aba41 | ||
|
|
3435531cb2 | ||
|
|
e784f8a27b | ||
|
|
96e9579bbf | ||
|
|
36432e0c80 | ||
|
|
b58a918f27 | ||
|
|
e8753831b6 | ||
|
|
7068600d3d | ||
|
|
b9443f0d78 | ||
|
|
3ca54043d8 | ||
|
|
e672a6dcf4 | ||
|
|
453d90827b | ||
|
|
13f68a3b12 | ||
|
|
07a26092ae | ||
|
|
57b6ba04b3 | ||
|
|
cf744757b6 | ||
|
|
59afe0a412 | ||
|
|
488eb7c0ea | ||
|
|
2a7af94f10 | ||
|
|
1922863723 | ||
|
|
1259231653 | ||
|
|
ba8d3c42a1 | ||
|
|
ab851d3600 | ||
|
|
b80213a017 | ||
|
|
8cb4bb0a55 | ||
|
|
58cddd18e2 | ||
|
|
67c0a3eed4 | ||
|
|
e7c7dae411 | ||
|
|
f66d2af98a | ||
|
|
dc3e6293ee | ||
|
|
05397f69d0 | ||
|
|
9f341eb485 | ||
|
|
e944f5bdf5 | ||
|
|
a0a34d138f | ||
|
|
4b55279c84 | ||
|
|
b5a7852f2e | ||
|
|
b675834a6f | ||
|
|
09e509e48f | ||
|
|
e2b6a3a75e | ||
|
|
dc4c31d66a | ||
|
|
abeb31f4f0 | ||
|
|
c7b91b62e6 | ||
|
|
648369b7cd | ||
|
|
3f834cc83b | ||
|
|
4dd5f13b3a | ||
|
|
faea96a786 | ||
|
|
7882968a05 | ||
|
|
d6595f54f1 | ||
|
|
6f1ba0ca9f | ||
|
|
daee7c8665 | ||
|
|
dd591ee78b | ||
|
|
f72ff25ebe | ||
|
|
04cf3b1b8a | ||
|
|
0cd82deaa6 | ||
|
|
826b566540 | ||
|
|
a2018f85b4 | ||
|
|
f48e05badb | ||
|
|
21ad47b45b | ||
|
|
ea54706e8b | ||
|
|
db6c23d511 | ||
|
|
d06396a51d | ||
|
|
bc5cc9b6f6 | ||
|
|
b05d6fb22b | ||
|
|
3144dd07e8 | ||
|
|
247627fe08 | ||
|
|
32668111e1 | ||
|
|
c3848fdbba | ||
|
|
834367ea65 | ||
|
|
7f9e5aa11e | ||
|
|
5554b5197a | ||
|
|
a0e504a834 | ||
|
|
f5d4892ba6 | ||
|
|
32e807e130 | ||
|
|
d7ff759cde | ||
|
|
fc4f8056c5 | ||
|
|
7b073523fa | ||
|
|
7205be3749 | ||
|
|
e1915e19a3 | ||
|
|
4da341ccf8 | ||
|
|
6ef958a606 | ||
|
|
a5811047d9 | ||
|
|
75e562e92f | ||
|
|
75d537f36a | ||
|
|
b68812109c | ||
|
|
44d0f31f93 | ||
|
|
b5d5b87779 | ||
|
|
cf180f5146 | ||
|
|
430c1686c0 | ||
|
|
d1d4bb1f5b | ||
|
|
03561407a3 | ||
|
|
a9c2c6945b | ||
|
|
6ae59e0557 | ||
|
|
b1c2c785f3 | ||
|
|
aa0c2a7093 | ||
|
|
987379b7a2 | ||
|
|
7ee38e27d3 | ||
|
|
60be976861 | ||
|
|
14e1c736b3 | ||
|
|
fc6945a72d | ||
|
|
b73e8b5c99 | ||
|
|
7fad5f2db8 | ||
|
|
6119610d7f | ||
|
|
401685c1b6 | ||
|
|
bf0f78b391 | ||
|
|
0f40e271db | ||
|
|
990a392b83 | ||
|
|
9e1d0077f6 | ||
|
|
68c3619f7f | ||
|
|
0419316f32 | ||
|
|
fb8252eebe | ||
|
|
8a7763c356 | ||
|
|
6187eecac5 | ||
|
|
4d3f262d59 | ||
|
|
95feb481a9 | ||
|
|
1a42c24dab | ||
|
|
833e02bfb2 | ||
|
|
705d6bf639 | ||
|
|
1186cd4a8d | ||
|
|
4b19b59b3a | ||
|
|
066a1ed161 | ||
|
|
cc9a826f1d | ||
|
|
8dd7b2d368 | ||
|
|
d82609304a | ||
|
|
831ba0a774 | ||
|
|
15fe52d83f | ||
|
|
bce20b9ad6 | ||
|
|
291273aef5 | ||
|
|
8248418fe2 | ||
|
|
99629f0a3e | ||
|
|
9405ee352d | ||
|
|
4dd055b9b1 | ||
|
|
7769a76bea | ||
|
|
27b8b57625 | ||
|
|
682ed1c8c5 | ||
|
|
f6c30a4953 | ||
|
|
4c352713ca | ||
|
|
20efb909ae | ||
|
|
fc6f528541 | ||
|
|
1d97000bef | ||
|
|
ade116fa03 | ||
|
|
ec40c99c95 | ||
|
|
ab66804d87 | ||
|
|
126d8c7926 | ||
|
|
b936327eec | ||
|
|
7499aadec6 | ||
|
|
ed5f82cbd2 | ||
|
|
596b71ce56 | ||
|
|
af6aaf341e | ||
|
|
4f51cdec0a | ||
|
|
e4f68f4024 | ||
|
|
b2f78987f7 | ||
|
|
a567d044c6 | ||
|
|
5e6fff7b8d | ||
|
|
f4766d0a11 | ||
|
|
5b95b17703 | ||
|
|
534e33ee46 | ||
|
|
3d0b8cf0a2 | ||
|
|
764f026ab9 | ||
|
|
056fdc3b2c | ||
|
|
d4641d88c0 | ||
|
|
6a82aee5cc | ||
|
|
ffa64a0125 | ||
|
|
856eafe8de | ||
|
|
94a6b5aa96 | ||
|
|
42b02add89 | ||
|
|
034bf2dd2c | ||
|
|
0eccfbf5ea | ||
|
|
23c3bd8852 | ||
|
|
037444d813 | ||
|
|
44de228f9f | ||
|
|
7b25221fee | ||
|
|
363afa251a | ||
|
|
052e3114bf | ||
|
|
d73c5133d3 | ||
|
|
8d0b63ad72 | ||
|
|
5766d03767 | ||
|
|
7ee2f8ab46 | ||
|
|
1840c76a26 | ||
|
|
51e8219306 | ||
|
|
82d16c6a0c | ||
|
|
da087054cc | ||
|
|
5781df15d3 | ||
|
|
4c1cb174b8 | ||
|
|
fa1ef6dfa5 | ||
|
|
1389a39bea | ||
|
|
0491afacec | ||
|
|
de62447522 | ||
|
|
3ba9b8c4e4 | ||
|
|
c1760a48ca | ||
|
|
32b854baf8 | ||
|
|
5b91699c69 | ||
|
|
1f42bb9ec6 | ||
|
|
8330f7fe89 | ||
|
|
74bbb9eed9 | ||
|
|
78960e7827 | ||
|
|
3dfe10fc87 | ||
|
|
807c3b95c4 | ||
|
|
4f408e4cfa | ||
|
|
0d0caa9d83 | ||
|
|
d33e382b49 | ||
|
|
20b7e77be2 | ||
|
|
3652e8c593 | ||
|
|
755268de6b | ||
|
|
4473e68f7e | ||
|
|
65aac426b2 | ||
|
|
a186fd35be | ||
|
|
c651074d91 | ||
|
|
34335d723a | ||
|
|
6cd0cd4730 | ||
|
|
3125ba2f8a | ||
|
|
638ddd0518 | ||
|
|
429f8214b0 | ||
|
|
bdd5c80504 | ||
|
|
c11d763760 | ||
|
|
d2df533c1d | ||
|
|
db3944b8d6 | ||
|
|
0d0e5fdd37 | ||
|
|
2273d2f346 | ||
|
|
7df03fd5e6 | ||
|
|
7dd30d5169 | ||
|
|
c7820e2571 | ||
|
|
cf058d65fd | ||
|
|
3eabe1f659 | ||
|
|
f442f089bf | ||
|
|
82abf48b18 | ||
|
|
7729614f8b | ||
|
|
9b86678daf | ||
|
|
9d356e7d9d | ||
|
|
6ac6819d5d | ||
|
|
e859baf6e5 | ||
|
|
ac137e1fb6 | ||
|
|
997d861f83 | ||
|
|
91cde36777 | ||
|
|
ebf7a4070c | ||
|
|
c63a31ddd8 | ||
|
|
8a0000b678 | ||
|
|
2fc79dbdb8 | ||
|
|
037ea45448 | ||
|
|
e389f7d353 | ||
|
|
6cdba67118 | ||
|
|
3bb32dfd44 | ||
|
|
d7d3ef7549 | ||
|
|
95a029ab6f | ||
|
|
f284a96587 | ||
|
|
ca91b16647 | ||
|
|
35e5a97266 | ||
|
|
6678a361ba | ||
|
|
1e8bd2afc7 | ||
|
|
ad5f658423 | ||
|
|
24e81159f3 | ||
|
|
b6e60e3461 | ||
|
|
203b4b166b | ||
|
|
d586eea977 | ||
|
|
d33e25f95d | ||
|
|
b9508d9be4 | ||
|
|
5b39f797b1 | ||
|
|
6ceb91e8b6 | ||
|
|
94259ce68c | ||
|
|
0f035ebc13 | ||
|
|
dc605a7292 | ||
|
|
15ef4b5419 | ||
|
|
fc6cf416dc | ||
|
|
0a28430c5a | ||
|
|
3207290d77 | ||
|
|
b0fa321606 | ||
|
|
2bffa59a10 | ||
|
|
7f080970e4 | ||
|
|
f1c2527ca3 | ||
|
|
33d210af7f | ||
|
|
d7378e4674 | ||
|
|
8e40b622f7 | ||
|
|
92e4c55cb5 | ||
|
|
f498e7af73 | ||
|
|
bacf196a31 | ||
|
|
2f4603af26 | ||
|
|
203a7d00f2 | ||
|
|
f8c351cd0b | ||
|
|
93ab8d368b | ||
|
|
e38d93fa2b | ||
|
|
59518fa4ce | ||
|
|
c7b7ccfb8b | ||
|
|
e0f9ac1ea3 | ||
|
|
2fa9f76d16 | ||
|
|
7eceb08e8c | ||
|
|
41f558c34c | ||
|
|
dd5963b172 | ||
|
|
c1e3a03412 | ||
|
|
ffd60ded27 | ||
|
|
b5e02b04b7 | ||
|
|
4077621891 | ||
|
|
2d2a835bbe | ||
|
|
526c2a3b8a | ||
|
|
0bee2560d5 | ||
|
|
c4796fb9c7 | ||
|
|
504aa22064 | ||
|
|
7882532361 | ||
|
|
f4786f0479 | ||
|
|
2dc814eacb | ||
|
|
289d82e5bc | ||
|
|
1157d96589 | ||
|
|
e1044a288d | ||
|
|
2cba8fd9ef | ||
|
|
1d9285d371 | ||
|
|
f8d342ba93 | ||
|
|
eae02f4f4a | ||
|
|
f8c397e57f | ||
|
|
87c53c8a42 | ||
|
|
8615d33da9 | ||
|
|
59702a47f0 | ||
|
|
cd69714985 | ||
|
|
f4e51b79fd | ||
|
|
b6fde08278 | ||
|
|
4773f7faef | ||
|
|
33e4637b60 | ||
|
|
e676c5c4f1 | ||
|
|
58741f88f6 | ||
|
|
12077ba07a | ||
|
|
748cb47b4b | ||
|
|
c0470012eb | ||
|
|
cf3eacc14f | ||
|
|
083dc40ad9 | ||
|
|
72001373b9 | ||
|
|
1eb33b6cc5 | ||
|
|
908047fbe2 | ||
|
|
2ac791344a | ||
|
|
0b28a4d20b | ||
|
|
62fbdab39a | ||
|
|
282c82282e | ||
|
|
4b7eeed21c | ||
|
|
d6d50bdc41 | ||
|
|
3be46106a1 | ||
|
|
ea2cda888d | ||
|
|
1d59d4c5ed | ||
|
|
be47db75aa | ||
|
|
41b81641ce | ||
|
|
1faebbb490 | ||
|
|
7036c3e613 | ||
|
|
aa1fece7b5 | ||
|
|
896b420c28 | ||
|
|
ac4fe43aef | ||
|
|
98e5bfb2bb | ||
|
|
ae722e689e | ||
|
|
3abff8cad1 | ||
|
|
155fa80c95 | ||
|
|
a5a2179399 | ||
|
|
8aee5a78a4 | ||
|
|
06ce8a7e6f | ||
|
|
1cc4d7624a | ||
|
|
dd817960e1 | ||
|
|
92e0f3b55b | ||
|
|
03bdf92ae2 | ||
|
|
5492d69445 | ||
|
|
83779a1698 | ||
|
|
49c70e8162 | ||
|
|
654ba13dea | ||
|
|
e4c0b7be6c | ||
|
|
0ee809a721 | ||
|
|
683e17bee4 | ||
|
|
b9d35c2343 | ||
|
|
6b6c69fb19 | ||
|
|
960980022f | ||
|
|
f72da4bec1 | ||
|
|
08e35a811f | ||
|
|
a34c41870c | ||
|
|
25428464b7 | ||
|
|
97c65f9585 | ||
|
|
302fa7e6af | ||
|
|
ab067f242b | ||
|
|
30e5ff6f64 | ||
|
|
2838dc5e7e | ||
|
|
6f4f073ed3 | ||
|
|
564eb85575 | ||
|
|
a6de8e0be4 | ||
|
|
abc87c0254 | ||
|
|
aec302d7f2 | ||
|
|
d27d9227bc | ||
|
|
a1c23aeaaa | ||
|
|
6b05544716 | ||
|
|
161ea1d318 | ||
|
|
f500f34e78 | ||
|
|
e3716b759a | ||
|
|
abc37de666 | ||
|
|
e09994cd30 | ||
|
|
e1dfd9bd99 | ||
|
|
b4ac86ef35 | ||
|
|
3e40286e5d | ||
|
|
4a2d307410 | ||
|
|
878d68a655 | ||
|
|
a56c92f87f | ||
|
|
9095629f96 | ||
|
|
8755c2df34 | ||
|
|
888a1af9b4 | ||
|
|
e0450d3835 | ||
|
|
4e56fdf5aa | ||
|
|
c332d5c97f | ||
|
|
2977a19532 | ||
|
|
a9365a8ba8 | ||
|
|
a6ddcdb759 | ||
|
|
d9dccd53f0 | ||
|
|
3b2f964961 | ||
|
|
2d8bd820a5 | ||
|
|
56a979970c | ||
|
|
836676eb18 | ||
|
|
86a013b619 | ||
|
|
e57a76790f | ||
|
|
b4cec48bbb | ||
|
|
96676721c9 | ||
|
|
eeb8785d42 | ||
|
|
993a1a7f86 | ||
|
|
0b6f29dc70 | ||
|
|
26007f97f3 | ||
|
|
5a55cca59d | ||
|
|
cb425fd18e | ||
|
|
5889dc675e | ||
|
|
df8e7e4b54 | ||
|
|
e07d253a5e | ||
|
|
81f4e6503a | ||
|
|
d7ff250faf | ||
|
|
1d12a5f171 | ||
|
|
485d3d884a | ||
|
|
e78754e39e | ||
|
|
0b6c11f0d0 | ||
|
|
d25604ed66 | ||
|
|
4f3167064c | ||
|
|
f0d4bec116 | ||
|
|
76a1872f74 | ||
|
|
1158cb4aeb | ||
|
|
41ab384e1f | ||
|
|
3839e721db | ||
|
|
d1b84461e6 | ||
|
|
3c79cb3ef5 | ||
|
|
ea7641278a | ||
|
|
23032e8409 | ||
|
|
1d687a01c1 | ||
|
|
0b751964fa | ||
|
|
59eb43c33f | ||
|
|
dfdb056e07 | ||
|
|
cd38eba184 | ||
|
|
a4063b978f | ||
|
|
af51775844 | ||
|
|
f4039abae3 | ||
|
|
1b64f46588 | ||
|
|
ad40368639 | ||
|
|
d15159d9b0 | ||
|
|
c837f6eacc | ||
|
|
14b884daf7 | ||
|
|
63ca14bbe6 | ||
|
|
2605566f90 | ||
|
|
0bcd59d5ba | ||
|
|
a9744bb577 | ||
|
|
9b4dae4af5 | ||
|
|
319d657ab4 | ||
|
|
d9896257c5 | ||
|
|
b5d5e85ee2 | ||
|
|
9dcaddd7fd | ||
|
|
d1bec2e815 | ||
|
|
96d7f28db9 | ||
|
|
90c4ca88e0 | ||
|
|
942fe202d7 | ||
|
|
e17f888598 | ||
|
|
b089c7d7f9 | ||
|
|
afc2a5b258 | ||
|
|
1f0adb7510 | ||
|
|
aba62966b0 | ||
|
|
aaff05685c | ||
|
|
9c1bbab253 | ||
|
|
def1c699e0 | ||
|
|
e6639a63b7 | ||
|
|
1b14761e9e | ||
|
|
07a070a4fe | ||
|
|
8b13fcfd68 | ||
|
|
4088ea68fa | ||
|
|
2e95ed13ce | ||
|
|
f79091bc9c | ||
|
|
ebfc19c1f7 | ||
|
|
bdb8f3cf6f | ||
|
|
4b998f2b97 | ||
|
|
aa1d254a49 | ||
|
|
897b3300e6 | ||
|
|
9c6c9489ff | ||
|
|
6d147b081e | ||
|
|
78432057ca | ||
|
|
21b0ed8925 | ||
|
|
1040e50b32 | ||
|
|
3806a05f4a | ||
|
|
82d45915c6 | ||
|
|
80e5145742 | ||
|
|
f1b7a52f0c | ||
|
|
924952128f | ||
|
|
2fcd04a55f | ||
|
|
deb6e86854 | ||
|
|
086fa37e86 | ||
|
|
e87ecf2f4f | ||
|
|
3dc01dd945 | ||
|
|
da21999192 | ||
|
|
161efaeb52 | ||
|
|
1759fbe8d5 | ||
|
|
b1525266a8 | ||
|
|
28ede39c26 | ||
|
|
6b25eb37ba | ||
|
|
e12dcdf86a | ||
|
|
4bab1490ae | ||
|
|
2374785ae7 | ||
|
|
b338da4359 | ||
|
|
d808f453d9 | ||
|
|
b869f713eb | ||
|
|
2f9cf4751d | ||
|
|
6c7e796e17 | ||
|
|
ff40c7e576 | ||
|
|
0ccc8b2607 | ||
|
|
8febcfdfb7 | ||
|
|
9d05d077b5 | ||
|
|
63ad926078 | ||
|
|
e241848426 | ||
|
|
a82b652bc1 | ||
|
|
e59aecdc75 | ||
|
|
e56ba6b41a | ||
|
|
cfd12483ae | ||
|
|
fd18837f1b | ||
|
|
4f3e37349d | ||
|
|
20653847f4 | ||
|
|
3e294a3ba4 | ||
|
|
20ca6f96f9 | ||
|
|
70a30a5f33 | ||
|
|
b9f170e668 | ||
|
|
809dfbe338 | ||
|
|
af25a82eca | ||
|
|
50b1fcadb4 | ||
|
|
aefe1b2f07 | ||
|
|
28bc30bd83 | ||
|
|
0aeffcd79d | ||
|
|
f3863811bd | ||
|
|
e4aab2fd15 | ||
|
|
5f72a6b855 | ||
|
|
31a0444409 | ||
|
|
4522935545 | ||
|
|
67c13bd416 | ||
|
|
28d5af5fa0 | ||
|
|
15d7e71e7f | ||
|
|
49bac975d2 | ||
|
|
3878c9a1e2 | ||
|
|
a5053c4418 | ||
|
|
4cb844dea8 | ||
|
|
04afad2fd3 | ||
|
|
149efe3199 | ||
|
|
6f05867563 | ||
|
|
4442fd3265 | ||
|
|
6e49856474 | ||
|
|
cc379b71de | ||
|
|
c2a1bb4a5a | ||
|
|
cc58c33e37 | ||
|
|
012f03f7e7 | ||
|
|
28a7a3c389 | ||
|
|
6417279d65 | ||
|
|
07db680ad3 | ||
|
|
d7c97b6589 | ||
|
|
af12289d7e | ||
|
|
afeafba67d | ||
|
|
f56e49da5c | ||
|
|
d233897c73 | ||
|
|
273f1c3d07 | ||
|
|
d34812b77b | ||
|
|
375a60bafc | ||
|
|
156bd57461 | ||
|
|
dacc1b8eeb | ||
|
|
b3bb023852 | ||
|
|
8ca8272bc4 | ||
|
|
fc36f7ad77 | ||
|
|
496bdf5b54 | ||
|
|
877d625945 | ||
|
|
458710e9f0 | ||
|
|
fa6e7e44a0 | ||
|
|
bc12220d7a | ||
|
|
9d7b879e1f | ||
|
|
e4ff8a169b | ||
|
|
5a62aea978 | ||
|
|
b4d9de74c3 | ||
|
|
aa37d8b4b3 | ||
|
|
e334bc6440 | ||
|
|
9f6b9923b0 | ||
|
|
85415ae7fc | ||
|
|
f5382e9649 | ||
|
|
3ca786b820 | ||
|
|
c13908f096 | ||
|
|
d11de94e0b | ||
|
|
e2c10f7e87 | ||
|
|
b05c717981 | ||
|
|
38db5dfee4 | ||
|
|
151eeb5ec1 | ||
|
|
0d150765b8 | ||
|
|
cd6ee3048c | ||
|
|
0ed9e62283 | ||
|
|
fdb89fbf64 | ||
|
|
3fd11831f6 | ||
|
|
cd81fc8b38 | ||
|
|
b512b7d5f7 | ||
|
|
883cb34bdb | ||
|
|
c683947d20 | ||
|
|
483204a811 | ||
|
|
0b5b7bcae2 | ||
|
|
e1d517f9c2 | ||
|
|
b80b869823 | ||
|
|
386a6cbb6c | ||
|
|
9ce4c0ee90 | ||
|
|
1351b5ff90 | ||
|
|
84960a6107 | ||
|
|
5d3fdc0abd | ||
|
|
0d491f0d41 | ||
|
|
955ae91110 | ||
|
|
85fa63d2a1 | ||
|
|
6d8f02435e | ||
|
|
fc0600dfd8 | ||
|
|
1494579353 | ||
|
|
834d7e1da1 | ||
|
|
08b64834cf | ||
|
|
8265c5adec | ||
|
|
be4f2398a9 | ||
|
|
b8f2d36f5e | ||
|
|
49a2526528 | ||
|
|
a755d3d55e | ||
|
|
41a6ddb62a | ||
|
|
e32acd17ba | ||
|
|
0de0add858 | ||
|
|
9a90ca4c53 | ||
|
|
86b1fa6276 | ||
|
|
08d5fb50a7 | ||
|
|
6fca7c7940 | ||
|
|
fad14b26b6 | ||
|
|
d33fe6e185 | ||
|
|
a1db85e50f | ||
|
|
e67f1a649c | ||
|
|
e88fe21802 | ||
|
|
21875b8dd5 | ||
|
|
8f4c6a5b32 | ||
|
|
ba696abe0c | ||
|
|
7f32d8d136 | ||
|
|
e0af365ef3 | ||
|
|
caa85cef49 | ||
|
|
0cb6902519 | ||
|
|
7226473dcb | ||
|
|
222fdf51b5 | ||
|
|
381ba0f69a | ||
|
|
e4170b5f16 | ||
|
|
81294ac9be | ||
|
|
5ae0110153 | ||
|
|
930c2ef9bb | ||
|
|
f109fb33d0 | ||
|
|
eae4f99b34 | ||
|
|
241f0bec43 | ||
|
|
01ea68560f | ||
|
|
03ae42c98a | ||
|
|
ab060b0981 | ||
|
|
89ef96f2b4 | ||
|
|
b7a1af9f64 | ||
|
|
102db1f46d | ||
|
|
cc35404c7f | ||
|
|
c07fccf607 |
@@ -29,3 +29,4 @@ smali2/build/resources.zip
|
|||||||
smali/build/resources.zip
|
smali/build/resources.zip
|
||||||
smali/assets/version.properties
|
smali/assets/version.properties
|
||||||
*.keystore
|
*.keystore
|
||||||
|
gradle.properties
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<a href="https://t.me/s/vtosters">
|
<a href="https://t.me/s/vtosters">
|
||||||
<img src="https://img.shields.io/badge/-Telegram-blue?style=for-the-badge&logo=telegram&color=2AABEE"/>
|
<img src="https://img.shields.io/badge/-Telegram-blue?style=for-the-badge&logo=telegram&color=2AABEE"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://vk.com/vtosters_official">
|
<a href="https://vk.ru/vtosters_official">
|
||||||
<img src="https://img.shields.io/badge/-VK-blue?style=for-the-badge&logo=vk&color=0077FF"/>
|
<img src="https://img.shields.io/badge/-VK-blue?style=for-the-badge&logo=vk&color=0077FF"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/j9CAt3uYXj">
|
<a href="https://discord.gg/j9CAt3uYXj">
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
|
|
||||||
`android:debuggable="false"` ➝ `android:debuggable="true"`
|
`android:debuggable="false"` ➝ `android:debuggable="true"`
|
||||||
|
|
||||||
Настройки, необходимые для **отладки** вне Android Studio, находятся по этой ссылке: [vk.com/vt/debug](https://vk.com/vt/debug)
|
Настройки, необходимые для **отладки** вне Android Studio, находятся по этой ссылке: [vk.ru/vt/debug](https://vk.ru/vt/debug)
|
||||||
|
|
||||||
* Для дополнительной отладки ответов и логов необходимо включить **[Режим разработчика]**
|
* Для дополнительной отладки ответов и логов необходимо включить **[Режим разработчика]**
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@
|
|||||||
|
|
||||||
Сразу после нажатия на запись приложение начнет записывать **все ваши действия** по пути `/Download/VK/logs/com.vtosters.lite/`
|
Сразу после нажатия на запись приложение начнет записывать **все ваши действия** по пути `/Download/VK/logs/com.vtosters.lite/`
|
||||||
|
|
||||||
При следующем открытии приложения оно автоматически сохранит логи и отправит вам в [**Документы** ВК](https://vk.com/docs), откуда вы можете скачать архив логов и работать с ними.
|
При следующем открытии приложения оно автоматически сохранит логи и отправит вам в [**Документы** ВК](https://vk.ru/docs), откуда вы можете скачать архив логов и работать с ними.
|
||||||
|
|
||||||
## Разработка
|
## Разработка
|
||||||
|
|
||||||
|
|||||||
@@ -69,16 +69,15 @@ task exportDex {
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 32
|
compileSdkVersion 32
|
||||||
buildToolsVersion '32.0.0'
|
buildToolsVersion '33.0.0'
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "ru.vtosters.lite.utils.lite"
|
applicationId "ru.vtosters.lite.utils.lite"
|
||||||
minSdkVersion 21
|
minSdk 22
|
||||||
targetSdkVersion 32
|
targetSdkVersion 32
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
|
multiDexEnabled false
|
||||||
multiDexEnabled true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
@@ -89,7 +88,6 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "androidx.multidex:multidex:2.0.1"
|
|
||||||
implementation 'com.google.android.material:material:1.6.1'
|
implementation 'com.google.android.material:material:1.6.1'
|
||||||
implementation 'androidx.exifinterface:exifinterface:1.3.3'
|
implementation 'androidx.exifinterface:exifinterface:1.3.3'
|
||||||
implementation 'androidx.preference:preference:1.2.0'
|
implementation 'androidx.preference:preference:1.2.0'
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
5df53281cbfd1b6caf676bd10d2a403361a2904b
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.vk.core.util;
|
package com.vk.core.util;
|
||||||
|
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
|
||||||
import static ru.vtosters.lite.utils.Preferences.getDownloadsDir;
|
import static ru.vtosters.lite.utils.Preferences.getDownloadsDir;
|
||||||
import static ru.vtosters.lite.utils.Preferences.getMusicDir;
|
import static ru.vtosters.lite.utils.Preferences.getMusicDir;
|
||||||
import static ru.vtosters.lite.utils.Preferences.getPhotosDir;
|
import static ru.vtosters.lite.utils.Preferences.getPhotosDir;
|
||||||
@@ -12,6 +13,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteException;
|
import android.database.sqlite.SQLiteException;
|
||||||
|
import android.media.MediaScannerConnection;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -22,6 +24,7 @@ import com.vk.core.concurrent.VkExecutors;
|
|||||||
import com.vk.imageloader.VKImageLoader;
|
import com.vk.imageloader.VKImageLoader;
|
||||||
import com.vk.log.L;
|
import com.vk.log.L;
|
||||||
import com.vk.metrics.eventtracking.VkTracker;
|
import com.vk.metrics.eventtracking.VkTracker;
|
||||||
|
import com.vtosters.lite.MainActivity;
|
||||||
import com.vtosters.lite.R;
|
import com.vtosters.lite.R;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -51,7 +54,7 @@ public class DownloadUtils {
|
|||||||
ToastUtils.a(context.getString(R.string.error) + " [" + e2.getMessage() + "]");
|
ToastUtils.a(context.getString(R.string.error) + " [" + e2.getMessage() + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void b(final Context context, String str, String str2, boolean z) {
|
private static void b(final Context context, String str, String str2, boolean z) {
|
||||||
if (TextUtils.isEmpty(str2)) {
|
if (TextUtils.isEmpty(str2)) {
|
||||||
return;
|
return;
|
||||||
@@ -59,10 +62,12 @@ public class DownloadUtils {
|
|||||||
|
|
||||||
String file = a(str, str2);
|
String file = a(str, str2);
|
||||||
File b2;
|
File b2;
|
||||||
|
boolean pic = false;
|
||||||
boolean c2 = MediaUtils.c(MediaUtils.b(str2));
|
boolean c2 = MediaUtils.c(MediaUtils.b(str2));
|
||||||
|
|
||||||
if (file.endsWith(".jpg") || file.endsWith(".png") || file.endsWith(".jpeg")) {
|
if (file.endsWith(".jpg") || file.endsWith(".png") || file.endsWith(".jpeg")) {
|
||||||
b2 = new File(getPhotosDir(), file);
|
b2 = new File(getPhotosDir(), file);
|
||||||
|
pic = true;
|
||||||
} else if (file.endsWith(".mp3") || file.endsWith(".wav") || file.endsWith(".ogg") || file.endsWith(".aac") || file.endsWith(".flac") || file.endsWith(".m4a")) {
|
} else if (file.endsWith(".mp3") || file.endsWith(".wav") || file.endsWith(".ogg") || file.endsWith(".aac") || file.endsWith(".flac") || file.endsWith(".m4a")) {
|
||||||
b2 = new File(getMusicDir(), file);
|
b2 = new File(getMusicDir(), file);
|
||||||
} else if (file.endsWith(".mp4") || file.endsWith(".mkv") || file.endsWith(".avi") || file.endsWith(".flv") || file.endsWith(".wmv") || file.endsWith(".mov") || file.endsWith(".3gp")) {
|
} else if (file.endsWith(".mp4") || file.endsWith(".mkv") || file.endsWith(".avi") || file.endsWith(".flv") || file.endsWith(".wmv") || file.endsWith(".mov") || file.endsWith(".3gp")) {
|
||||||
@@ -83,14 +88,16 @@ public class DownloadUtils {
|
|||||||
if (b2.exists()) {
|
if (b2.exists()) {
|
||||||
VkExecutors.x.a().execute(() -> ToastUtils.a(context.getString(R.string.file_saved, b2.getAbsoluteFile())));
|
VkExecutors.x.a().execute(() -> ToastUtils.a(context.getString(R.string.file_saved, b2.getAbsoluteFile())));
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
L.a(e2);
|
L.a(e2);
|
||||||
}
|
}
|
||||||
|
|
||||||
CameraUtils.a(context, b2, null);
|
CameraUtils.a(context, b2, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(str2));
|
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(str2));
|
||||||
request.setDestinationUri(Uri.fromFile(b2));
|
request.setDestinationUri(Uri.fromFile(b2));
|
||||||
request.setMimeType(FileUtils.f(new File(str)));
|
request.setMimeType(FileUtils.f(new File(str)));
|
||||||
@@ -103,6 +110,9 @@ public class DownloadUtils {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
long enqueue = a2.enqueue(request);
|
long enqueue = a2.enqueue(request);
|
||||||
|
if (pic) {
|
||||||
|
CameraUtils.a(context, b2, null);
|
||||||
|
}
|
||||||
if (!z) {
|
if (!z) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,5 +35,6 @@ public enum DialogAction {
|
|||||||
pinmsg,
|
pinmsg,
|
||||||
unpinmsg,
|
unpinmsg,
|
||||||
ENCRYPT_SETT,
|
ENCRYPT_SETT,
|
||||||
ENCRYPT
|
ENCRYPT,
|
||||||
|
DOWNLOAD
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ public final class DialogActionsHelper {
|
|||||||
CollectionExt.a(arrayList, DialogAction.NOTIFICATIONS_OFF, dialog.b(b2));
|
CollectionExt.a(arrayList, DialogAction.NOTIFICATIONS_OFF, dialog.b(b2));
|
||||||
return arrayList;
|
return arrayList;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,18 +6,23 @@ 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_hide;
|
||||||
import static com.vk.im.engine.h.im_ic_pinned_msg_show;
|
import static com.vk.im.engine.h.im_ic_pinned_msg_show;
|
||||||
import static com.vk.im.engine.h.im_ic_write_msg;
|
import static com.vk.im.engine.h.im_ic_write_msg;
|
||||||
|
import static com.vk.im.ui.c.im_ic_chat_settings;
|
||||||
import static com.vk.im.ui.c.im_ic_keyboard;
|
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.hookDNR;
|
||||||
import static ru.vtosters.lite.dnr.DNRModule.hookDNT;
|
import static ru.vtosters.lite.dnr.DNRModule.hookDNT;
|
||||||
import static ru.vtosters.lite.dnr.DNRModule.isDnrEnabledFor;
|
import static ru.vtosters.lite.dnr.DNRModule.isDnrEnabledFor;
|
||||||
import static ru.vtosters.lite.dnr.DNRModule.isDntEnabledFor;
|
import static ru.vtosters.lite.dnr.DNRModule.isDntEnabledFor;
|
||||||
import static ru.vtosters.lite.encryption.EncryptProvider.decryptMessage;
|
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.AccountManagerUtils.getUserToken;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
|
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
|
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
|
||||||
|
import static ru.vtosters.lite.utils.Preferences.getDownloadsDir;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Environment;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.vk.core.network.Network;
|
import com.vk.core.network.Network;
|
||||||
@@ -33,6 +38,7 @@ import com.vk.im.ui.components.common.MsgAction;
|
|||||||
import com.vk.im.ui.components.viewcontrollers.popup.DelegateMsg;
|
import com.vk.im.ui.components.viewcontrollers.popup.DelegateMsg;
|
||||||
import com.vk.im.ui.views.dialog_actions.DialogActionsListView;
|
import com.vk.im.ui.views.dialog_actions.DialogActionsListView;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@@ -41,6 +47,7 @@ import java.util.List;
|
|||||||
import okhttp3.Headers;
|
import okhttp3.Headers;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
|
import ru.vtosters.lite.downloaders.MessagesDownloader;
|
||||||
import ru.vtosters.lite.encryption.EncryptProvider;
|
import ru.vtosters.lite.encryption.EncryptProvider;
|
||||||
import ru.vtosters.lite.encryption.base.IMProcessor;
|
import ru.vtosters.lite.encryption.base.IMProcessor;
|
||||||
import ru.vtosters.lite.hooks.CryptImHook;
|
import ru.vtosters.lite.hooks.CryptImHook;
|
||||||
@@ -49,7 +56,13 @@ import ru.vtosters.lite.utils.AndroidUtils;
|
|||||||
|
|
||||||
public class DNRInjector {
|
public class DNRInjector {
|
||||||
public static void inject(Dialog dialog, List<DialogAction> list) {
|
public static void inject(Dialog dialog, List<DialogAction> list) {
|
||||||
int peerId = dialog.getId();
|
int peerId = 0;
|
||||||
|
|
||||||
|
if (dialog != null) {
|
||||||
|
peerId = dialog.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
list.add(DialogAction.DOWNLOAD);
|
||||||
|
|
||||||
list.add(DialogAction.pinmsg);
|
list.add(DialogAction.pinmsg);
|
||||||
list.add(DialogAction.unpinmsg);
|
list.add(DialogAction.unpinmsg);
|
||||||
@@ -74,6 +87,8 @@ public class DNRInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static LinkedHashMap<DialogAction, Integer> injectToHashMap(LinkedHashMap<DialogAction, Integer> hashMap) {
|
public static LinkedHashMap<DialogAction, Integer> injectToHashMap(LinkedHashMap<DialogAction, Integer> hashMap) {
|
||||||
|
hashMap.put(DialogAction.DOWNLOAD, getIdentifier("download_dl", "string"));
|
||||||
|
|
||||||
hashMap.put(DialogAction.DNR_ON, getIdentifier("DNR_ON", "string"));
|
hashMap.put(DialogAction.DNR_ON, getIdentifier("DNR_ON", "string"));
|
||||||
hashMap.put(DialogAction.DNR_OFF, getIdentifier("DNR_OFF", "string"));
|
hashMap.put(DialogAction.DNR_OFF, getIdentifier("DNR_OFF", "string"));
|
||||||
hashMap.put(DialogAction.DNT_ON, getIdentifier("DNT_ON", "string"));
|
hashMap.put(DialogAction.DNT_ON, getIdentifier("DNT_ON", "string"));
|
||||||
@@ -90,6 +105,7 @@ public class DNRInjector {
|
|||||||
@SuppressLint("ResourceType")
|
@SuppressLint("ResourceType")
|
||||||
public static List<Object> injectToList(List<Object> actions) {
|
public static List<Object> injectToList(List<Object> actions) {
|
||||||
var list = new ArrayList<>(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
|
||||||
|
|
||||||
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_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.DNR_OFF, 2, im_ic_pinned_msg_show, getIdentifier("DNR_OFF", "string"))); // DialogAction, Int, Icon, String
|
||||||
@@ -111,8 +127,14 @@ public class DNRInjector {
|
|||||||
ImEngine1.a().a(new OnDialogUpdateEvent(null, map));
|
ImEngine1.a().a(new OnDialogUpdateEvent(null, map));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<DialogAction> injectToListAccess(List<DialogAction> actions, Dialog dialog, ProfilesSimpleInfo profilesSimpleInfo) {
|
public static List<DialogAction> injectToListAccess(List<DialogAction> actions, Dialog dialog) {
|
||||||
var peerId = dialog.getId();
|
int peerId = 0;
|
||||||
|
|
||||||
|
if (dialog != null) {
|
||||||
|
peerId = dialog.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.add(DialogAction.DOWNLOAD);
|
||||||
|
|
||||||
if (isDnrEnabledFor(peerId)) {
|
if (isDnrEnabledFor(peerId)) {
|
||||||
actions.add(DialogAction.DNR_OFF);
|
actions.add(DialogAction.DNR_OFF);
|
||||||
@@ -137,13 +159,28 @@ public class DNRInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean onClickHeader(DialogAction action, Dialog dialog) {
|
public static boolean onClickHeader(DialogAction action, Dialog dialog) {
|
||||||
var id = dialog.getId();
|
int peerId = 0;
|
||||||
|
|
||||||
|
if (dialog != null) {
|
||||||
|
peerId = dialog.getId();
|
||||||
|
}
|
||||||
|
|
||||||
if (action == DialogAction.MARK_AS_READ) {
|
if (action == DialogAction.MARK_AS_READ) {
|
||||||
DNRModule.hookRead(dialog);
|
DNRModule.hookRead(dialog);
|
||||||
forceInvalidateDialogActions(dialog);
|
forceInvalidateDialogActions(dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action == DialogAction.DOWNLOAD) {
|
||||||
|
File out = new File(Environment.getExternalStoragePublicDirectory(getDownloadsDir().getName()), "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) {
|
if (action == DialogAction.DNR_ON) {
|
||||||
setDnr(dialog, true);
|
setDnr(dialog, true);
|
||||||
forceInvalidateDialogActions(dialog);
|
forceInvalidateDialogActions(dialog);
|
||||||
@@ -165,10 +202,10 @@ public class DNRInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action == DialogAction.ENCRYPT_SETT) {
|
if (action == DialogAction.ENCRYPT_SETT) {
|
||||||
CryptImHook.hookPref(id);
|
CryptImHook.hookPref(peerId);
|
||||||
return true;
|
return true;
|
||||||
} else if (action == DialogAction.ENCRYPT) {
|
} else if (action == DialogAction.ENCRYPT) {
|
||||||
CryptImHook.hook(id, dialog);
|
CryptImHook.hook(peerId, dialog);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,12 +213,26 @@ public class DNRInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean onClick(Dialog dialog, DialogAction action) {
|
public static boolean onClick(Dialog dialog, DialogAction action) {
|
||||||
var id = dialog.getId();
|
int peerId = 0;
|
||||||
|
|
||||||
|
if (dialog != null) {
|
||||||
|
peerId = dialog.getId();
|
||||||
|
}
|
||||||
|
|
||||||
if (action == DialogAction.MARK_AS_READ) {
|
if (action == DialogAction.MARK_AS_READ) {
|
||||||
DNRModule.hookRead(dialog);
|
DNRModule.hookRead(dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action == DialogAction.DOWNLOAD) {
|
||||||
|
File out = new File(Environment.getExternalStoragePublicDirectory(getDownloadsDir().getPath()), peerId + "-dialog.html");
|
||||||
|
try {
|
||||||
|
new MessagesDownloader().downloadDialog(peerId, new MessagesDownloader.HtmlDialogDownloaderFormatProvider(), out);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (action == DialogAction.DNR_ON) {
|
if (action == DialogAction.DNR_ON) {
|
||||||
setDnr(dialog, true);
|
setDnr(dialog, true);
|
||||||
return true;
|
return true;
|
||||||
@@ -199,18 +250,18 @@ public class DNRInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action == DialogAction.pinmsg) {
|
if (action == DialogAction.pinmsg) {
|
||||||
pinnedMsg(id, true);
|
pinnedMsg(peerId, true);
|
||||||
return true;
|
return true;
|
||||||
} else if (action == DialogAction.unpinmsg) {
|
} else if (action == DialogAction.unpinmsg) {
|
||||||
pinnedMsg(id, false);
|
pinnedMsg(peerId, false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action == DialogAction.ENCRYPT_SETT) {
|
if (action == DialogAction.ENCRYPT_SETT) {
|
||||||
CryptImHook.hookPref(id);
|
CryptImHook.hookPref(peerId);
|
||||||
return true;
|
return true;
|
||||||
} else if (action == DialogAction.ENCRYPT) {
|
} else if (action == DialogAction.ENCRYPT) {
|
||||||
CryptImHook.hook(id, dialog);
|
CryptImHook.hook(peerId, dialog);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,13 +299,13 @@ public class DNRInjector {
|
|||||||
|
|
||||||
if (action == MsgAction.valueOf("TRANSLATE")) {
|
if (action == MsgAction.valueOf("TRANSLATE")) {
|
||||||
if (isTextExist && isReplyExist) {
|
if (isTextExist && isReplyExist) {
|
||||||
Translate.showTranslatedText(context, text + "\n\n" + AndroidUtils.getString("translator_reply") + "\n" + reply);
|
Translate.showTranslatedText(context, text + "\n\n" + getString("translator_reply") + "\n" + reply);
|
||||||
} else if (isReplyExist) {
|
} else if (isReplyExist) {
|
||||||
Translate.showTranslatedText(context, AndroidUtils.getString("translator_reply") + "\n" + reply);
|
Translate.showTranslatedText(context, getString("translator_reply") + "\n" + reply);
|
||||||
} else if (isTextExist) {
|
} else if (isTextExist) {
|
||||||
Translate.showTranslatedText(context, text);
|
Translate.showTranslatedText(context, text);
|
||||||
} else {
|
} else {
|
||||||
sendToast(AndroidUtils.getString("translator_no_text"));
|
sendToast(getString("translator_no_text"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,7 +316,7 @@ public class DNRInjector {
|
|||||||
Thread thread = new Thread(() -> {
|
Thread thread = new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
var request = new Request.a()
|
var request = new Request.a()
|
||||||
.b("https://api.vk.com/method/" + (needToBePinned ? "messages.pinConversation" : "messages.unpinConversation") + "?peer_id=" + dialogid + "&access_token=" + getUserToken() + "&v=5.119")
|
.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(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8"))
|
||||||
.a();
|
.a();
|
||||||
|
|
||||||
@@ -282,15 +333,27 @@ public class DNRInjector {
|
|||||||
|
|
||||||
thread.start();
|
thread.start();
|
||||||
|
|
||||||
sendToast(AndroidUtils.getString("pin_dialog") + " " + (needToBePinned ? AndroidUtils.getString("dialog_pinned") : AndroidUtils.getString("dialog_unpinned")));
|
sendToast(getString("pin_dialog") + " " + getString(needToBePinned ? "dialog_pinned" : "dialog_unpinned"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setDnr(Dialog dialog, boolean value) {
|
public static void setDnr(Dialog dialog, boolean value) {
|
||||||
hookDNR(dialog.getId());
|
int peerId = 0;
|
||||||
|
|
||||||
|
if (dialog != null) {
|
||||||
|
peerId = dialog.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
hookDNR(peerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setDnt(Dialog dialog, boolean value) {
|
public static void setDnt(Dialog dialog, boolean value) {
|
||||||
hookDNT(dialog.getId());
|
int peerId = 0;
|
||||||
|
|
||||||
|
if (dialog != null) {
|
||||||
|
peerId = dialog.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
hookDNT(peerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package ru.vtosters.lite.dnr;
|
|||||||
|
|
||||||
import static ru.vtosters.lite.net.Request.makeRequest;
|
import static ru.vtosters.lite.net.Request.makeRequest;
|
||||||
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
|
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
|
||||||
import static ru.vtosters.lite.utils.ProxyUtils.getApi;
|
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package ru.vtosters.lite.downloaders;
|
package ru.vtosters.lite.downloaders;
|
||||||
|
|
||||||
|
import static ru.vtosters.lite.utils.Preferences.getMusicDir;
|
||||||
|
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -35,7 +37,7 @@ public class AudioDownloader {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var musicPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath();
|
var musicPath = getMusicDir().getAbsolutePath();
|
||||||
var musicDir = new File(musicPath);
|
var musicDir = new File(musicPath);
|
||||||
if (!musicDir.exists()) {
|
if (!musicDir.exists()) {
|
||||||
if (musicDir.mkdirs()) {
|
if (musicDir.mkdirs()) {
|
||||||
|
|||||||
@@ -0,0 +1,549 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
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" +
|
||||||
|
"\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.ru/" + 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.ru/").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.ru/$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.ru/").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.ru/").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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO:
|
||||||
|
1) poll (опросы)
|
||||||
|
2) mini_app (поделиться миниаппом)
|
||||||
|
3) audio_playlist (плейлист песен)
|
||||||
|
4) story (история)
|
||||||
|
5) wall_reply (комментарий на стене)
|
||||||
|
6) podcast (подкаст)
|
||||||
|
7) gift (подарок)
|
||||||
|
*/
|
||||||
|
|
||||||
|
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) {
|
||||||
|
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.ru/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;
|
||||||
|
default:
|
||||||
|
rs.append("не поддерживается (").append(type).append(")");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs.append(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return rs.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 == 7) break;
|
||||||
|
++qualityIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return videoHtml.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,8 @@ import android.content.IntentFilter;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
|
|
||||||
|
import com.vk.core.dialogs.alert.VkAlertDialog;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import b.h.g.m.FileUtils;
|
import b.h.g.m.FileUtils;
|
||||||
@@ -56,16 +58,31 @@ public class OTADownloader {
|
|||||||
|
|
||||||
public static void downloadBuild(String url) {
|
public static void downloadBuild(String url) {
|
||||||
var context = AndroidUtils.getGlobalContext();
|
var context = AndroidUtils.getGlobalContext();
|
||||||
var uri = Uri.parse(url);
|
try {
|
||||||
|
var uri = Uri.parse(url);
|
||||||
|
|
||||||
context.registerReceiver(callback, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
|
context.registerReceiver(callback, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
|
||||||
|
|
||||||
var request = new DownloadManager.Request(uri);
|
var request = new DownloadManager.Request(uri);
|
||||||
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
||||||
request.setTitle("VTLite.apk");
|
request.setTitle("VTLite.apk");
|
||||||
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "VTLite.apk");
|
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "VTLite.apk");
|
||||||
|
|
||||||
var manager = (DownloadManager) AndroidUtils.getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE);
|
var manager = (DownloadManager) AndroidUtils.getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE);
|
||||||
manager.enqueue(request);
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import android.os.Environment;
|
|||||||
import com.vk.dto.common.ImageSize;
|
import com.vk.dto.common.ImageSize;
|
||||||
import com.vk.dto.stories.model.StoryEntry;
|
import com.vk.dto.stories.model.StoryEntry;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class StoryDownloader {
|
public class StoryDownloader {
|
||||||
@@ -23,8 +24,9 @@ public class StoryDownloader {
|
|||||||
String url = imageSizes.get(imageSizes.size() - 1).url;
|
String url = imageSizes.get(imageSizes.size() - 1).url;
|
||||||
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
|
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
|
||||||
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
||||||
request.setTitle("photo" + story.E.a);
|
request.setTitle("photo" + story.E.a + ".jpg");
|
||||||
request.setDestinationInExternalPublicDir(getPhotosDir().getAbsolutePath(), "/Stories/photo" + story.E.a + ".jpg");
|
request.setDestinationInExternalPublicDir(getPhotosDir().getName(), "photo" + story.E.a + ".jpg");
|
||||||
|
request.allowScanningByMediaScanner();
|
||||||
((DownloadManager) getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
|
((DownloadManager) getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package ru.vtosters.lite.downloaders;
|
package ru.vtosters.lite.downloaders;
|
||||||
|
|
||||||
import static ru.vtosters.lite.net.Request.makeRequest;
|
import static ru.vtosters.lite.net.Request.makeRequest;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
|
||||||
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
|
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
|
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
|
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
|
||||||
@@ -15,6 +16,7 @@ import android.net.Uri;
|
|||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.vk.core.dialogs.alert.VkAlertDialog;
|
||||||
import com.vk.core.dialogs.bottomsheet.MenuBottomSheetAction;
|
import com.vk.core.dialogs.bottomsheet.MenuBottomSheetAction;
|
||||||
import com.vk.core.util.ToastUtils;
|
import com.vk.core.util.ToastUtils;
|
||||||
import com.vk.dto.common.VideoFile;
|
import com.vk.dto.common.VideoFile;
|
||||||
@@ -106,30 +108,32 @@ public class VideoDownloader {
|
|||||||
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
|
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
|
||||||
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
||||||
request.setTitle(videoFile.toString());
|
request.setTitle(videoFile.toString());
|
||||||
request.setDestinationInExternalPublicDir(getVideosDir().getAbsolutePath(), videoFile + ".mp4");
|
request.allowScanningByMediaScanner();
|
||||||
|
request.setDestinationInExternalPublicDir(getVideosDir().getName(), videoFile + ".mp4");
|
||||||
((DownloadManager) getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
|
((DownloadManager) getGlobalContext().getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var builder = new AlertDialog.Builder(context);
|
var builder = new VkAlertDialog.Builder(context);
|
||||||
builder.setItems(max, ((dialog, which) -> {
|
builder.setItems(max, ((dialog, which) -> {
|
||||||
var url = urls.get(which);
|
var url = urls.get(which);
|
||||||
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
|
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
|
||||||
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
||||||
request.setTitle(videoFile.toString());
|
request.setTitle(videoFile.toString());
|
||||||
request.setDestinationInExternalPublicDir(getVideosDir().getAbsolutePath(), videoFile + ".mp4");
|
request.allowScanningByMediaScanner();
|
||||||
|
request.setDestinationInExternalPublicDir(getVideosDir().getName(), videoFile + ".mp4");
|
||||||
((DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
|
((DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
|
||||||
}));
|
}));
|
||||||
builder.show();
|
builder.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void parseVideoLink(String url, Context ctx) {
|
public static void parseVideoLink(String url, Context ctx) {
|
||||||
if (url.contains("vk.com/story")) {
|
if (url.contains("vk.ru/story") || url.contains("vk.com/story")) {
|
||||||
ToastUtils.a(AndroidUtils.getString("video_dl_stories_not_supported"));
|
ToastUtils.a(AndroidUtils.getString("video_dl_stories_not_supported"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!url.contains("vk.com/video")) {
|
if (!url.contains("vk.ru/video") || !url.contains("vk.com/video")) {
|
||||||
ToastUtils.a(AndroidUtils.getString("video_dl_wrong_link"));
|
ToastUtils.a(AndroidUtils.getString("video_dl_wrong_link"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -141,7 +145,7 @@ public class VideoDownloader {
|
|||||||
progressDialog.setMessage(AndroidUtils.getString("video_dl_progress"));
|
progressDialog.setMessage(AndroidUtils.getString("video_dl_progress"));
|
||||||
progressDialog.show();
|
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 -> {
|
response -> {
|
||||||
progressDialog.cancel();
|
progressDialog.cancel();
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import android.util.Pair;
|
|||||||
|
|
||||||
import com.vk.im.engine.models.messages.Msg;
|
import com.vk.im.engine.models.messages.Msg;
|
||||||
import com.vk.im.engine.models.messages.MsgFromUser;
|
import com.vk.im.engine.models.messages.MsgFromUser;
|
||||||
|
import com.vk.im.ui.components.msg_list.MsgListComponent;
|
||||||
|
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
@@ -51,6 +52,48 @@ public class EncryptProvider {
|
|||||||
public static int getPeerId(Msg msg) {
|
public static int getPeerId(Msg msg) {
|
||||||
return msg.v1();
|
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.
|
// This will run through EVERY single processor available.
|
||||||
public static String decryptMessage(MsgFromUser msg) {
|
public static String decryptMessage(MsgFromUser msg) {
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import static android.widget.Toast.makeText;
|
|||||||
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
|
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
|
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||||
import static ru.vtosters.lite.utils.ProxyUtils.apiproxy;
|
import static ru.vtosters.lite.proxy.ProxyUtils.isApiProxyEnabled;
|
||||||
import static ru.vtosters.lite.utils.ProxyUtils.getApi;
|
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
@@ -18,6 +18,9 @@ import androidx.exifinterface.media.ExifInterface;
|
|||||||
import com.vk.core.dialogs.alert.VkAlertDialog;
|
import com.vk.core.dialogs.alert.VkAlertDialog;
|
||||||
import com.vk.core.network.Network;
|
import com.vk.core.network.Network;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
@@ -32,11 +35,13 @@ import java.util.regex.Pattern;
|
|||||||
import okhttp3.Headers;
|
import okhttp3.Headers;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import ru.vtosters.lite.net.Request;
|
import ru.vtosters.lite.net.Request;
|
||||||
|
import ru.vtosters.lite.utils.AccountManagerUtils;
|
||||||
|
|
||||||
public class FoafBase {
|
public class FoafBase {
|
||||||
private static final Pattern FOAF_REGEX = Pattern.compile("<ya:created dc:date=\"(.+?)\"\\/>");
|
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_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 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();
|
private static final OkHttpClient client = new OkHttpClient();
|
||||||
|
|
||||||
public static long getLastSeen(long origtime, int id) throws ParseException, IOException {
|
public static long getLastSeen(long origtime, int id) throws ParseException, IOException {
|
||||||
@@ -65,15 +70,57 @@ public class FoafBase {
|
|||||||
return sdf.parse(sdf.format(date)).getTime() / 1000;
|
return sdf.parse(sdf.format(date)).getTime() / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static JSONObject getBypassedOnlineInfo(int id) throws JSONException {
|
||||||
|
var request = new okhttp3.Request.a()
|
||||||
|
.b(API_VKNEXT + Integer.toString(id))
|
||||||
|
.a();
|
||||||
|
|
||||||
|
String response = null;
|
||||||
|
|
||||||
|
var dummy = new JSONObject();
|
||||||
|
dummy.put("last_seen", 0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = client.a(request).execute().a().g();
|
||||||
|
var online_info = new JSONObject(response).optJSONObject("response").optJSONObject(Integer.toString(id));
|
||||||
|
return online_info == null ? dummy : online_info;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("GetBypassedOnlineInfo", e.getMessage());
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONObject getBypassedOnlineInfo(String ids) throws JSONException {
|
||||||
|
|
||||||
|
|
||||||
|
var request = new okhttp3.Request.a()
|
||||||
|
.b(API_VKNEXT + ids)
|
||||||
|
.a();
|
||||||
|
|
||||||
|
String response = null;
|
||||||
|
|
||||||
|
var dummy = new JSONObject();
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = client.a(request).execute().a().g();
|
||||||
|
var online_info = new JSONObject(response).optJSONObject("response");
|
||||||
|
return online_info == null ? dummy : online_info;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("GetBypassedOnlineInfo1", e.getMessage());
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static String getLink(int i) {
|
private static String getLink(int i) {
|
||||||
String str;
|
String str;
|
||||||
StringBuilder sb;
|
StringBuilder sb;
|
||||||
if (apiproxy()) {
|
if (isApiProxyEnabled()) {
|
||||||
sb = new StringBuilder();
|
sb = new StringBuilder();
|
||||||
str = "https://" + getApi() + "/_/vk.com/foaf.php?id=";
|
str = "https://" + getApi() + "/_/vk.ru/foaf.php?id=";
|
||||||
} else {
|
} else {
|
||||||
sb = new StringBuilder();
|
sb = new StringBuilder();
|
||||||
str = "https://vk.com/foaf.php?id=";
|
str = "https://vk.ru/foaf.php?id=";
|
||||||
}
|
}
|
||||||
sb.append(str);
|
sb.append(str);
|
||||||
sb.append(i);
|
sb.append(i);
|
||||||
@@ -107,7 +154,7 @@ public class FoafBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long daysPassedFromFoafDate(String str) {
|
private static long daysPassedFromFoafDate(String str) {
|
||||||
try {
|
try {
|
||||||
@SuppressLint("SimpleDateFormat")
|
@SuppressLint("SimpleDateFormat")
|
||||||
Date parse = new SimpleDateFormat("yyyy-MM-dd").parse(str.split(" ")[1]);
|
Date parse = new SimpleDateFormat("yyyy-MM-dd").parse(str.split(" ")[1]);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
|
|||||||
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
|
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
|
||||||
import static ru.vtosters.lite.utils.LifecycleUtils.getCurrentActivity;
|
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 static ru.vtosters.lite.utils.ThemesUtils.getSTextAttr;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -19,6 +20,7 @@ import com.vk.core.dialogs.alert.VkAlertDialog;
|
|||||||
import com.vk.im.engine.models.dialogs.Dialog;
|
import com.vk.im.engine.models.dialogs.Dialog;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import ru.vtosters.lite.encryption.EncryptProvider;
|
import ru.vtosters.lite.encryption.EncryptProvider;
|
||||||
import ru.vtosters.lite.encryption.base.IMProcessor;
|
import ru.vtosters.lite.encryption.base.IMProcessor;
|
||||||
@@ -78,6 +80,8 @@ public class CryptImHook{
|
|||||||
|
|
||||||
public static void hookPref(int peerId){
|
public static void hookPref(int peerId){
|
||||||
IMProcessor enabled = null;
|
IMProcessor enabled = null;
|
||||||
|
String key = null;
|
||||||
|
|
||||||
for (IMProcessor processor : EncryptProvider.processors) {
|
for (IMProcessor processor : EncryptProvider.processors) {
|
||||||
if (processor.isUsedToEncrypt(peerId)) {
|
if (processor.isUsedToEncrypt(peerId)) {
|
||||||
enabled = processor;
|
enabled = processor;
|
||||||
@@ -89,6 +93,14 @@ public class CryptImHook{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Objects.requireNonNull(enabled).getEncryptionKeyFor(peerId) != null) {
|
||||||
|
key = enabled.getEncryptionKeyFor(peerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key.equals("VTAesDefault")) {
|
||||||
|
key = null;
|
||||||
|
}
|
||||||
|
|
||||||
Context ctx = getCurrentActivity();
|
Context ctx = getCurrentActivity();
|
||||||
|
|
||||||
LinearLayout linearLayout = new LinearLayout(ctx);
|
LinearLayout linearLayout = new LinearLayout(ctx);
|
||||||
@@ -102,9 +114,10 @@ public class CryptImHook{
|
|||||||
ViewGroup.MarginLayoutParams margin = ((ViewGroup.MarginLayoutParams) editText.getLayoutParams());
|
ViewGroup.MarginLayoutParams margin = ((ViewGroup.MarginLayoutParams) editText.getLayoutParams());
|
||||||
margin.setMargins(dp2px(24f), 0, dp2px(24f), 0);
|
margin.setMargins(dp2px(24f), 0, dp2px(24f), 0);
|
||||||
editText.setLayoutParams(margin);
|
editText.setLayoutParams(margin);
|
||||||
|
editText.setText(key == null ? "" : key);
|
||||||
|
|
||||||
IMProcessor finalEnabled = enabled;
|
IMProcessor finalEnabled = enabled;
|
||||||
new AlertDialog.Builder(ctx)
|
new AlertDialog.Builder(ctx, getAlertStyle())
|
||||||
.setTitle(getString("encryption_enter_key"))
|
.setTitle(getString("encryption_enter_key"))
|
||||||
.setMessage(String.format(getString("encryption_current_algorithm_title"), enabled.getUIName()))
|
.setMessage(String.format(getString("encryption_current_algorithm_title"), enabled.getUIName()))
|
||||||
.setView(linearLayout)
|
.setView(linearLayout)
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
package ru.vtosters.lite.hooks;
|
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 static ru.vtosters.lite.utils.Preferences.getBoolValue;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.provider.Settings;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@@ -13,27 +19,30 @@ public class DeviceInfoHook{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String getDeviceId(String input) {
|
public static String getDeviceId(String input) {
|
||||||
Log.d("DeviceInfoHook", "getDeviceId: " + input);
|
return findDeviceId() + ":" + getDeviceId();
|
||||||
Log.d("DeviceInfoHook", "getDeviceId shuffled: " + shuffle(input));
|
|
||||||
if (getBoolValue("hideDeviceInfo", true)) return shuffle(input);
|
|
||||||
return input;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String shuffle(String string) {
|
public static String getDeviceId() {
|
||||||
StringBuilder sb = new StringBuilder(string.length());
|
String sb2 = Build.PRODUCT +
|
||||||
double rnd;
|
Build.BOARD +
|
||||||
for (char c: string.toCharArray()) {
|
Build.BOOTLOADER +
|
||||||
rnd = Math.random();
|
Build.BRAND +
|
||||||
if (rnd < 0.34)
|
Build.DEVICE +
|
||||||
sb.append(c);
|
Build.DISPLAY +
|
||||||
else if (rnd < 0.67)
|
Build.FINGERPRINT +
|
||||||
sb.insert(sb.length() / 2, c);
|
Build.HARDWARE +
|
||||||
else
|
Build.HOST +
|
||||||
sb.insert(0, c);
|
Build.ID +
|
||||||
|
Build.MANUFACTURER +
|
||||||
|
Build.MODEL +
|
||||||
|
Build.PRODUCT +
|
||||||
|
Build.TAGS;
|
||||||
|
|
||||||
sb.append(new Random().nextInt(10));
|
return MD5(sb2);
|
||||||
sb.deleteCharAt(0);
|
}
|
||||||
}
|
|
||||||
return sb.toString();
|
@SuppressLint("HardwareIds")
|
||||||
|
private static String findDeviceId() {
|
||||||
|
return Settings.Secure.getString(getGlobalContext().getContentResolver(), "android_id");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import com.vk.core.fragments.FragmentImpl;
|
|||||||
import com.vk.core.util.StringUtils;
|
import com.vk.core.util.StringUtils;
|
||||||
import com.vk.navigation.right.RightMenu;
|
import com.vk.navigation.right.RightMenu;
|
||||||
import com.vtosters.lite.MenuCountersState;
|
import com.vtosters.lite.MenuCountersState;
|
||||||
|
import com.vtosters.lite.fragments.ProfileFragment;
|
||||||
import com.vtosters.lite.ui.bottomnavigation.BottomNavigationMenuView;
|
import com.vtosters.lite.ui.bottomnavigation.BottomNavigationMenuView;
|
||||||
import com.vtosters.lite.ui.bottomnavigation.BottomNavigationView;
|
import com.vtosters.lite.ui.bottomnavigation.BottomNavigationView;
|
||||||
|
|
||||||
@@ -208,6 +209,7 @@ public class DockBarInjector {
|
|||||||
val = MenuCountersState.n();
|
val = MenuCountersState.n();
|
||||||
break;
|
break;
|
||||||
case tab_feedback:
|
case tab_feedback:
|
||||||
|
case tab_news:
|
||||||
if (milkshake())
|
if (milkshake())
|
||||||
val = MenuCountersState.k();
|
val = MenuCountersState.k();
|
||||||
break;
|
break;
|
||||||
@@ -286,7 +288,7 @@ public class DockBarInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Class<?> interceptClick(int id, RightMenu rightMenu) {
|
public static Class<?> interceptClick(int id, RightMenu rightMenu) {
|
||||||
if (id == tab_menu) {
|
if (id == tab_menu && rightMenu != null) {
|
||||||
rightMenu.a();
|
rightMenu.a();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,6 +296,7 @@ public class DockBarInjector {
|
|||||||
if (id == tab.id)
|
if (id == tab.id)
|
||||||
return tab.fragmentClass;
|
return tab.fragmentClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DockBarTab tab : sManager.getDisabledTabs()) {
|
for (DockBarTab tab : sManager.getDisabledTabs()) {
|
||||||
if (id == tab.id)
|
if (id == tab.id)
|
||||||
return tab.fragmentClass;
|
return tab.fragmentClass;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package ru.vtosters.lite.hooks;
|
package ru.vtosters.lite.hooks;
|
||||||
|
|
||||||
import static ru.vtosters.lite.foaf.FoafBase.getLastSeen;
|
import static ru.vtosters.lite.foaf.FoafBase.getBypassedOnlineInfo;
|
||||||
|
import static ru.vtosters.lite.hooks.OnlineFormatterHook.onlineHookProfiles;
|
||||||
import static ru.vtosters.lite.hooks.DateHook.getLocale;
|
import static ru.vtosters.lite.hooks.DateHook.getLocale;
|
||||||
|
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.AndroidUtils.getDefaultPrefs;
|
||||||
import static ru.vtosters.lite.utils.Base64Utils.decode;
|
|
||||||
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.checkCaption;
|
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.checkCaption;
|
||||||
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.checkCopyright;
|
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.checkCopyright;
|
||||||
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.isBadNews;
|
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.isBadNews;
|
||||||
@@ -74,7 +76,7 @@ public class JsonInjectors {
|
|||||||
|
|
||||||
public static JSONObject donateRecomm() throws JSONException {
|
public static JSONObject donateRecomm() throws JSONException {
|
||||||
var title = AndroidUtils.getString("donate_to_vtl");
|
var title = AndroidUtils.getString("donate_to_vtl");
|
||||||
var link = "https://vk.com/vtosters_official";
|
var link = "https://vk.ru/vtosters_official";
|
||||||
var text_color = "2D81E0";
|
var text_color = "2D81E0";
|
||||||
|
|
||||||
var json = new JSONObject();
|
var json = new JSONObject();
|
||||||
@@ -116,7 +118,7 @@ public class JsonInjectors {
|
|||||||
public static JSONObject vktesters(int id) throws JSONException {
|
public static JSONObject vktesters(int id) throws JSONException {
|
||||||
var title = AndroidUtils.getString("tester_profile");
|
var title = AndroidUtils.getString("tester_profile");
|
||||||
var text_color = "2D81E0";
|
var text_color = "2D81E0";
|
||||||
var link = "https://static.vk.com/bugs?lang=" + LangUtils.a() + "#/reporter" + id;
|
var link = "https://" + getStatic() + "/bugs?lang=" + LangUtils.a() + "#/reporter" + id;
|
||||||
|
|
||||||
var json = new JSONObject();
|
var json = new JSONObject();
|
||||||
var icons = new JSONArray();
|
var icons = new JSONArray();
|
||||||
@@ -162,23 +164,16 @@ public class JsonInjectors {
|
|||||||
var link = "https://vtosters.app"; // can be null
|
var link = "https://vtosters.app"; // can be null
|
||||||
var linktitle = "Test button"; // 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 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;
|
var isPicture = pic.endsWith(".png") || pic.endsWith(".jpg") || pic.endsWith(".jpeg") || pic.endsWith(".webp");
|
||||||
if (!hasIcon) icon = "";
|
|
||||||
if (!hasButton) buttons = "";
|
|
||||||
|
|
||||||
if (isVerified(peerid)) text = AndroidUtils.getString("i_bought") + " VTosters Premium";
|
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 (isPrometheus(peerid)) text = AndroidUtils.getString("i_bought") + " VTosters Premium Gold Prime Pro Plus";
|
||||||
if (isDeveloper(peerid)) text = AndroidUtils.getString("i_created_poop");
|
if (isDeveloper(peerid)) text = AndroidUtils.getString("i_created_poop");
|
||||||
if (!isVerified(peerid) || text.equals("")) {
|
|
||||||
|
if (!isVerified(peerid) || text.equals("") || peerid == AccountManagerUtils.getUserId() || peerid == 0) {
|
||||||
if (getBoolValue("convBarRecomm", false)) {
|
if (getBoolValue("convBarRecomm", false)) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
@@ -186,14 +181,27 @@ public class JsonInjectors {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dev()) return orig.optJSONObject("conversation_bar");
|
if (!dev()) return orig.optJSONObject("conversation_bar"); // for devs only
|
||||||
|
|
||||||
// JSONObject("{\"name\":\"group_admin_welcome\",\"text\":\"" + textverif + "\",\"buttons\":[],\"icon\":\"" + pic + "\"}");
|
var json = new JSONObject();
|
||||||
return new JSONObject(decode("eyJuYW1lIjoiZ3JvdXBfYWRtaW5fd2VsY29tZSIsInRleHQiOiI=")
|
|
||||||
+ text + decode("IiwiYnV0dG9ucyI6Ww==")
|
var buttonsJson = new JSONObject();
|
||||||
+ buttons + decode("XQ==")
|
buttonsJson.put("layout", "tertiary");
|
||||||
+ icon
|
buttonsJson.put("text", linktitle);
|
||||||
+ decode("fQ=="));
|
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 {
|
||||||
@@ -271,29 +279,82 @@ public class JsonInjectors {
|
|||||||
|
|
||||||
public static JSONObject setOnlineInfo(JSONObject json) throws ParseException, IOException, JSONException {
|
public static JSONObject setOnlineInfo(JSONObject json) throws ParseException, IOException, JSONException {
|
||||||
var id = json.optInt("id");
|
var id = json.optInt("id");
|
||||||
|
if (id == AccountManagerUtils.getUserId()) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
var onlineinfo = json.optJSONObject("online_info");
|
var onlineinfo = json.optJSONObject("online_info");
|
||||||
var time = getLastSeen(0L, id);
|
if (onlineinfo != null && !onlineinfo.optBoolean("visible")) {
|
||||||
|
var bypassed = getBypassedOnlineInfo(id);
|
||||||
|
if (bypassed.optInt("last_seen", 0) != 0) {
|
||||||
|
json.remove("online_info");
|
||||||
|
|
||||||
if (time != 0L && onlineinfo != null && !onlineinfo.optBoolean("is_online") && id != AccountManagerUtils.getUserId()) {
|
var online_info = new JSONObject()
|
||||||
json.remove("online_info");
|
.put("visible", true)
|
||||||
|
.put("last_seen", bypassed.optInt("last_seen"))
|
||||||
|
.put("is_online", bypassed.optBoolean("is_online"))
|
||||||
|
.put("app_id", bypassed.optInt("app_id"))
|
||||||
|
.put("is_mobile", bypassed.optBoolean("is_mobile"));
|
||||||
|
|
||||||
var online_info = new JSONObject()
|
var last_seen = new JSONObject()
|
||||||
.put("visible", true)
|
.put("platform", bypassed.optInt("platform"))
|
||||||
.put("last_seen", time)
|
.put("time", bypassed.optInt("last_seen"));
|
||||||
.put("is_online", false)
|
|
||||||
.put("app_id", 0)
|
|
||||||
.put("is_mobile", false);
|
|
||||||
|
|
||||||
var last_seen = new JSONObject()
|
json.put("last_seen", last_seen).put("online_info", online_info);
|
||||||
.put("platform", 4)
|
}
|
||||||
.put("time", time);
|
|
||||||
|
|
||||||
json.put("last_seen", last_seen).put("online_info", online_info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static JSONArray setOnlineInfoUsers(JSONArray profiles) throws ParseException, IOException, JSONException {
|
||||||
|
if (profiles == null || profiles.length() == 0) return profiles;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
var curVkId = AccountManagerUtils.getUserId();
|
||||||
|
for (int i=0; i < profiles.length(); i++) {
|
||||||
|
JSONObject profile = profiles.getJSONObject(i);
|
||||||
|
int id = profile.optInt("id", -1);
|
||||||
|
JSONObject onlinfo = profile.optJSONObject("online_info");
|
||||||
|
if (id == curVkId || id < 0 || onlinfo == null || onlinfo.optBoolean("visible")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sb.append(id);
|
||||||
|
sb.append(",");
|
||||||
|
}
|
||||||
|
var ids = sb.toString();
|
||||||
|
if (ids.length() > 0) {
|
||||||
|
ids = ids.substring(0, ids.length() - 1);
|
||||||
|
} else {
|
||||||
|
return profiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject bypassedObj = getBypassedOnlineInfo(ids);
|
||||||
|
for (int i=0; i < profiles.length(); i++) {
|
||||||
|
JSONObject profile = profiles.getJSONObject(i);
|
||||||
|
int id = profile.optInt("id");
|
||||||
|
JSONObject bypassed = bypassedObj.optJSONObject(Integer.toString(id));
|
||||||
|
if (bypassed == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
profile.remove("online_info");
|
||||||
|
|
||||||
|
var online_info = new JSONObject()
|
||||||
|
.put("visible", true)
|
||||||
|
.put("last_seen", bypassed.optInt("last_seen"))
|
||||||
|
.put("is_online", bypassed.optBoolean("is_online"))
|
||||||
|
.put("app_id", bypassed.optInt("app_id"))
|
||||||
|
.put("is_mobile", bypassed.optBoolean("is_mobile"));
|
||||||
|
|
||||||
|
var last_seen = new JSONObject()
|
||||||
|
.put("platform", bypassed.optInt("platform"))
|
||||||
|
.put("time", bypassed.optInt("last_seen"));
|
||||||
|
|
||||||
|
profile.put("last_seen", last_seen).put("online_info", online_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
return profiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static JSONObject storiesads(JSONObject json, boolean isDeleteFix) throws JSONException {
|
public static JSONObject storiesads(JSONObject json, boolean isDeleteFix) throws JSONException {
|
||||||
if (!adsstories()) {
|
if (!adsstories()) {
|
||||||
return json;
|
return json;
|
||||||
@@ -374,6 +435,30 @@ public class JsonInjectors {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Boolean isWhitelistedFilters(JSONObject list) throws JSONException {
|
||||||
|
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_filters_groups", Collections.synchronizedSet(new LinkedHashSet<>()));
|
||||||
|
|
||||||
|
return whitelist.contains(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean isWhitelistedAd(JSONObject list) throws JSONException {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
public static JSONArray newsfeedlist(JSONArray items) throws JSONException {
|
public static JSONArray newsfeedlist(JSONArray items) throws JSONException {
|
||||||
var selectedItems = getDefaultPrefs().getString("news_feed_selected_items", "");
|
var selectedItems = getDefaultPrefs().getString("news_feed_selected_items", "");
|
||||||
var filtersSet = getDefaultPrefs().getStringSet("news_feed_items_set", null);
|
var filtersSet = getDefaultPrefs().getStringSet("news_feed_items_set", null);
|
||||||
@@ -445,31 +530,31 @@ public class JsonInjectors {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adsgroup() && list.optInt("marked_as_ads") == 1) {
|
if (adsgroup() && list.optInt("marked_as_ads") == 1 && !isWhitelistedAd(list)) {
|
||||||
if (dev())
|
if (dev())
|
||||||
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: marked_as_ads is true");
|
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: marked_as_ads is true");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBadNews(list.optString("text"))) {
|
if (isBadNews(list.optString("text")) && !isWhitelistedFilters(list)) {
|
||||||
if (dev())
|
if (dev())
|
||||||
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: text filters");
|
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: text filters");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkCopyright(list)) {
|
if (checkCopyright(list) && !isWhitelistedFilters(list)) {
|
||||||
if (dev())
|
if (dev())
|
||||||
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: copyright filters");
|
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: copyright filters");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkCaption(list)) {
|
if (checkCaption(list) && !isWhitelistedFilters(list)) {
|
||||||
if (dev())
|
if (dev())
|
||||||
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: caption filters");
|
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: caption filters");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NewsFeedFiltersUtils.injectFiltersReposts(list)) {
|
if (NewsFeedFiltersUtils.injectFiltersReposts(list) && !isWhitelistedFilters(list)) {
|
||||||
if (dev())
|
if (dev())
|
||||||
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: repost ad");
|
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: repost ad");
|
||||||
continue;
|
continue;
|
||||||
@@ -506,7 +591,7 @@ public class JsonInjectors {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var playlists = fetchCatalogId("https://vk.com/audio?section=my_playlists");
|
var playlists = fetchCatalogId("https://vk.ru/audio?section=my_playlists");
|
||||||
if (playlists != null) {
|
if (playlists != null) {
|
||||||
var catalogarr = playlists.optJSONObject("catalog").optJSONArray("sections").optJSONObject(0);
|
var catalogarr = playlists.optJSONObject("catalog").optJSONArray("sections").optJSONObject(0);
|
||||||
|
|
||||||
@@ -519,7 +604,7 @@ public class JsonInjectors {
|
|||||||
oldItems.put(new JSONObject().put("id", id).put("title", title).put("url", url));
|
oldItems.put(new JSONObject().put("id", id).put("title", title).put("url", url));
|
||||||
}
|
}
|
||||||
|
|
||||||
var albums = fetchCatalogId("https://vk.com/audio?section=albums");
|
var albums = fetchCatalogId("https://vk.ru/audio?section=albums");
|
||||||
if (albums != null) {
|
if (albums != null) {
|
||||||
var catalogarr = albums.optJSONObject("catalog").optJSONArray("sections").optJSONObject(0);
|
var catalogarr = albums.optJSONObject("catalog").optJSONArray("sections").optJSONObject(0);
|
||||||
|
|
||||||
@@ -532,7 +617,7 @@ public class JsonInjectors {
|
|||||||
oldItems.put(new JSONObject().put("id", id).put("title", title).put("url", url));
|
oldItems.put(new JSONObject().put("id", id).put("title", title).put("url", url));
|
||||||
}
|
}
|
||||||
|
|
||||||
var recent = fetchCatalogId("https://vk.com/audio?section=recent");
|
var recent = fetchCatalogId("https://vk.ru/audio?section=recent");
|
||||||
if (recent != null) {
|
if (recent != null) {
|
||||||
var catalogarr = recent.optJSONObject("catalog").optJSONArray("sections").optJSONObject(0);
|
var catalogarr = recent.optJSONObject("catalog").optJSONArray("sections").optJSONObject(0);
|
||||||
|
|
||||||
@@ -568,7 +653,7 @@ public class JsonInjectors {
|
|||||||
if (section == null) return null;
|
if (section == null) return null;
|
||||||
|
|
||||||
var request = new Request.a()
|
var request = new Request.a()
|
||||||
.b("https://api.vk.com/method/catalog.getAudio"
|
.b("https://" + getApi() + "/method/catalog.getAudio"
|
||||||
+ "?v=5.119"
|
+ "?v=5.119"
|
||||||
+ "&https=1"
|
+ "&https=1"
|
||||||
+ "&need_blocks=1"
|
+ "&need_blocks=1"
|
||||||
@@ -592,7 +677,7 @@ public class JsonInjectors {
|
|||||||
|
|
||||||
public static JSONObject fetchCatalogPodcast() {
|
public static JSONObject fetchCatalogPodcast() {
|
||||||
var request = new Request.a()
|
var request = new Request.a()
|
||||||
.b("https://api.vk.com/method/catalog.getPodcasts"
|
.b("https://" + getApi() + "/method/catalog.getPodcasts"
|
||||||
+ "?v=5.119"
|
+ "?v=5.119"
|
||||||
+ "&https=1"
|
+ "&https=1"
|
||||||
+ "&need_blocks=1"
|
+ "&need_blocks=1"
|
||||||
@@ -612,8 +697,8 @@ public class JsonInjectors {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JSONObject friends(JSONObject json) throws JSONException {
|
public static JSONObject friends(JSONObject json) throws JSONException, ParseException, IOException {
|
||||||
JSONObject catalog = json;
|
JSONObject catalog = onlineHookProfiles(json);
|
||||||
boolean sectionexecute = true;
|
boolean sectionexecute = true;
|
||||||
boolean hasBirthday = false;
|
boolean hasBirthday = false;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package ru.vtosters.lite.hooks;
|
package ru.vtosters.lite.hooks;
|
||||||
|
|
||||||
import static java.lang.Long.MAX_VALUE;
|
import static java.lang.Long.MAX_VALUE;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.*;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
|
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
|
||||||
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.checkCaption;
|
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.checkCaption;
|
||||||
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.checkCopyright;
|
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.checkCopyright;
|
||||||
@@ -19,17 +20,24 @@ import static ru.vtosters.lite.utils.Preferences.adsslider;
|
|||||||
import static ru.vtosters.lite.utils.Preferences.authorsrecomm;
|
import static ru.vtosters.lite.utils.Preferences.authorsrecomm;
|
||||||
import static ru.vtosters.lite.utils.Preferences.friendsrecomm;
|
import static ru.vtosters.lite.utils.Preferences.friendsrecomm;
|
||||||
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
|
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
|
||||||
|
import static ru.vtosters.lite.utils.Preferences.milkshake;
|
||||||
import static ru.vtosters.lite.utils.Preferences.vkme;
|
import static ru.vtosters.lite.utils.Preferences.vkme;
|
||||||
|
|
||||||
import com.vk.core.preference.Preference;
|
import com.vk.core.preference.Preference;
|
||||||
|
import com.vtosters.lite.api.ExtendedCommunityProfile;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import ru.vtosters.lite.utils.AccountManagerUtils;
|
||||||
|
import ru.vtosters.lite.utils.AndroidUtils;
|
||||||
|
|
||||||
public class NewsfeedHook {
|
public class NewsfeedHook {
|
||||||
public static boolean injectFilters(JSONObject obj) throws JSONException {
|
public static boolean injectFilters(JSONObject obj) throws JSONException {
|
||||||
if (getBoolValue("newadblock", true)) return true;
|
if (getBoolValue("newadblock", true)) return true;
|
||||||
@@ -101,16 +109,57 @@ public class NewsfeedHook {
|
|||||||
return params.toArray(new String[0]);
|
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) {
|
public static void adsParams(HashSet<String> hashSet) {
|
||||||
if (ads() || adsslider()) {
|
if (ads()) {
|
||||||
hashSet.add("ads_disabled");
|
hashSet.add("ads_disabled");
|
||||||
|
hashSet.add("ads_app_slider");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hashSet.add("ads_app");
|
hashSet.add("ads_app");
|
||||||
hashSet.add("ads_site");
|
hashSet.add("ads_site");
|
||||||
hashSet.add("ads_post");
|
hashSet.add("ads_post");
|
||||||
hashSet.add("ads_app_slider");
|
if (adsslider()) {
|
||||||
|
hashSet.add("ads_app_slider");
|
||||||
|
}
|
||||||
hashSet.add("ads_site_slider");
|
hashSet.add("ads_site_slider");
|
||||||
hashSet.add("ads_app_video");
|
hashSet.add("ads_app_video");
|
||||||
hashSet.add("ads_post_pretty_cards");
|
hashSet.add("ads_post_pretty_cards");
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package ru.vtosters.lite.hooks;
|
package ru.vtosters.lite.hooks;
|
||||||
|
|
||||||
import static ru.vtosters.lite.hooks.JsonInjectors.setOnlineInfo;
|
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.net.Request.makeRequest;
|
||||||
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
|
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||||
@@ -8,7 +9,9 @@ import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
|
|||||||
import static ru.vtosters.lite.utils.Preferences.dev;
|
import static ru.vtosters.lite.utils.Preferences.dev;
|
||||||
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
|
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
|
||||||
import static ru.vtosters.lite.utils.Preferences.getPrefsFromFile;
|
import static ru.vtosters.lite.utils.Preferences.getPrefsFromFile;
|
||||||
import static ru.vtosters.lite.utils.ProxyUtils.getApi;
|
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
@@ -120,7 +123,7 @@ public class OnlineFormatterHook {
|
|||||||
case 5632485:
|
case 5632485:
|
||||||
return "SpaceVK";
|
return "SpaceVK";
|
||||||
case 6287487:
|
case 6287487:
|
||||||
return "vk.com";
|
return "vk.ru";
|
||||||
case 4542624:
|
case 4542624:
|
||||||
return "Black VK";
|
return "Black VK";
|
||||||
case 3917910:
|
case 3917910:
|
||||||
@@ -167,14 +170,66 @@ public class OnlineFormatterHook {
|
|||||||
return getString("custom_online") + " " + appname;
|
return getString("custom_online") + " " + appname;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JSONObject onlineHook(JSONObject json, boolean isGlobalHook) throws ParseException, IOException, JSONException {
|
public static JSONObject onlineHook(JSONObject json) throws ParseException, IOException, JSONException {
|
||||||
if (!getBoolValue("onlinefix", false)) return json;
|
if (getBoolValue("onlinefix", false)) setOnlineInfo(json);
|
||||||
|
|
||||||
if (isGlobalHook && !getBoolValue("globalUsersOnline", false)) {
|
return json;
|
||||||
return json;
|
}
|
||||||
|
|
||||||
|
public static JSONArray onlineHookList(JSONArray jsonArr) throws ParseException, IOException, JSONException {
|
||||||
|
if (!getBoolValue("onlinefix", false)) return jsonArr;
|
||||||
|
|
||||||
|
try {
|
||||||
|
setOnlineInfoUsers(jsonArr);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("onlineHookProfiles", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
setOnlineInfo(json);
|
return jsonArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONObject onlineHookProfiles(JSONObject json) throws ParseException, IOException, JSONException {
|
||||||
|
if (!getBoolValue("onlinefix", false)) return json;
|
||||||
|
|
||||||
|
try {
|
||||||
|
setOnlineInfoUsers(json.optJSONArray("profiles"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("onlineHookProfiles", e.getMessage());
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONObject onlineHookItems(JSONObject json) throws ParseException, IOException, JSONException {
|
||||||
|
if (!getBoolValue("onlinefix", false)) return json;
|
||||||
|
|
||||||
|
try {
|
||||||
|
setOnlineInfoUsers(json.optJSONArray("items"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("onlineHookItems", e.getMessage());
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONObject onlineHookRequestsAndRecommendations(JSONObject json) throws ParseException, IOException, JSONException {
|
||||||
|
if (!getBoolValue("onlinefix", false)) return json;
|
||||||
|
|
||||||
|
try {
|
||||||
|
setOnlineInfoUsers(json.optJSONObject("read_requests").optJSONArray("items"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("onlineHookItems", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
setOnlineInfoUsers(json.optJSONObject("recommendations").optJSONArray("items"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("onlineHookItems", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
setOnlineInfoUsers(json.optJSONArray("profiles"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("onlineHookItems", e.getMessage());
|
||||||
|
}
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package ru.vtosters.lite.hooks;
|
package ru.vtosters.lite.hooks;
|
||||||
|
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
|
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
|
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
|
||||||
|
|
||||||
@@ -15,10 +16,15 @@ import android.view.MenuItem;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.vk.core.dialogs.actionspopup.ActionsPopup;
|
import com.vk.core.dialogs.actionspopup.ActionsPopup;
|
||||||
import com.vk.core.drawable.RecoloredDrawable;
|
import com.vk.core.drawable.RecoloredDrawable;
|
||||||
|
import com.vk.core.util.ToastUtils;
|
||||||
import com.vk.dto.common.AttachmentWithMedia;
|
import com.vk.dto.common.AttachmentWithMedia;
|
||||||
|
import com.vk.dto.common.ImageSize;
|
||||||
import com.vtosters.lite.R;
|
import com.vtosters.lite.R;
|
||||||
|
import com.vtosters.lite.attachments.DocumentAttachment;
|
||||||
import com.vtosters.lite.attachments.PhotoAttachment;
|
import com.vtosters.lite.attachments.PhotoAttachment;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
@@ -26,6 +32,7 @@ import org.json.JSONObject;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import okhttp3.Call;
|
import okhttp3.Call;
|
||||||
import okhttp3.Callback;
|
import okhttp3.Callback;
|
||||||
@@ -36,18 +43,17 @@ import ru.vtosters.lite.utils.AndroidUtils;
|
|||||||
import ru.vtosters.lite.utils.ThemesUtils;
|
import ru.vtosters.lite.utils.ThemesUtils;
|
||||||
|
|
||||||
public class PhotoViewer {
|
public class PhotoViewer {
|
||||||
|
|
||||||
static OkHttpClient client = new OkHttpClient();
|
static OkHttpClient client = new OkHttpClient();
|
||||||
|
|
||||||
public static boolean interceptClick(AttachmentWithMedia attachment, MenuItem item, View view) {
|
public static boolean interceptClick(AttachmentWithMedia attachment, MenuItem item, View view) {
|
||||||
if (item.getItemId() == AndroidUtils.getIdentifier("search_photo", "id")) {
|
if (item.getItemId() == AndroidUtils.getIdentifier("search_photo", "id")) {
|
||||||
searchPhoto(getUrlFromAttachment((PhotoAttachment) attachment));
|
searchPhoto(getUrlFromPhotoAttachment((PhotoAttachment) attachment));
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == AndroidUtils.getIdentifier("copy_photo_url", "id")) {
|
} else if (item.getItemId() == AndroidUtils.getIdentifier("copy_photo_url", "id")) {
|
||||||
copyPhotoUrl(getUrlFromAttachment((PhotoAttachment) attachment));
|
copyPhotoUrl(getUrlFromPhotoAttachment((PhotoAttachment) attachment));
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == AndroidUtils.getIdentifier("open_original_photo", "id")) {
|
} else if (item.getItemId() == AndroidUtils.getIdentifier("open_original_photo", "id")) {
|
||||||
openUrl(getUrlFromAttachment((PhotoAttachment) attachment));
|
openUrl(getUrlFromPhotoAttachment((PhotoAttachment) attachment));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -61,7 +67,19 @@ public class PhotoViewer {
|
|||||||
: new RecoloredDrawable(AndroidUtils.getGlobalContext().getDrawable(R.drawable.ic_menu_search_outline_28), ThemesUtils.getAccentColor()),
|
: new RecoloredDrawable(AndroidUtils.getGlobalContext().getDrawable(R.drawable.ic_menu_search_outline_28), ThemesUtils.getAccentColor()),
|
||||||
false,
|
false,
|
||||||
() -> {
|
() -> {
|
||||||
searchPhoto(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;
|
return null;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -71,7 +89,19 @@ public class PhotoViewer {
|
|||||||
: new RecoloredDrawable(AndroidUtils.getGlobalContext().getDrawable(R.drawable.ic_copy_outline_28), Color.WHITE),
|
: new RecoloredDrawable(AndroidUtils.getGlobalContext().getDrawable(R.drawable.ic_copy_outline_28), Color.WHITE),
|
||||||
false,
|
false,
|
||||||
() -> {
|
() -> {
|
||||||
copyPhotoUrl(getUrlFromAttachment((PhotoAttachment) attachment));
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -82,14 +112,39 @@ public class PhotoViewer {
|
|||||||
ThemesUtils.getAccentColor()),
|
ThemesUtils.getAccentColor()),
|
||||||
false,
|
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;
|
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();
|
var imageSizes = attachment.D.Q.t1();
|
||||||
|
return getUrlFromImageSizeList(imageSizes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static String getUrlFromImageSizeList(List<ImageSize> imageSizes) {
|
||||||
if (imageSizes.isEmpty())
|
if (imageSizes.isEmpty())
|
||||||
return null;
|
return null;
|
||||||
var max = imageSizes.get(0);
|
var max = imageSizes.get(0);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package ru.vtosters.lite.hooks;
|
package ru.vtosters.lite.hooks;
|
||||||
|
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.isVikaProxyEnabled;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
|
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
|
|
||||||
import static ru.vtosters.lite.utils.LifecycleUtils.restartApplication;
|
import static ru.vtosters.lite.utils.LifecycleUtils.restartApplication;
|
||||||
import static ru.vtosters.lite.utils.ProxyUtils.apiproxy;
|
import static ru.vtosters.lite.proxy.ProxyUtils.isRandomProxyEnabled;
|
||||||
import static ru.vtosters.lite.utils.ProxyUtils.isZaboronaEnabled;
|
import static ru.vtosters.lite.proxy.ProxyUtils.isZaboronaEnabled;
|
||||||
import static ru.vtosters.lite.utils.ThemesUtils.getAccentColor;
|
import static ru.vtosters.lite.utils.ThemesUtils.getAccentColor;
|
||||||
import static ru.vtosters.lite.utils.ThemesUtils.getAlertStyle;
|
import static ru.vtosters.lite.utils.ThemesUtils.getAlertStyle;
|
||||||
import static ru.vtosters.lite.utils.ThemesUtils.getTextAttr;
|
import static ru.vtosters.lite.utils.ThemesUtils.getTextAttr;
|
||||||
@@ -14,7 +14,6 @@ import android.annotation.SuppressLint;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.util.Log;
|
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.RadioButton;
|
import android.widget.RadioButton;
|
||||||
@@ -41,40 +40,56 @@ public class ProxyHook {
|
|||||||
RadioGroup rg = new RadioGroup(ctx);
|
RadioGroup rg = new RadioGroup(ctx);
|
||||||
|
|
||||||
RadioButton rgDefault = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
|
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(rgDefault);
|
||||||
rg.addView(rgProxy);
|
rg.addView(rgZaborona);
|
||||||
|
rg.addView(rgVika);
|
||||||
|
rg.addView(rgRandomProxy);
|
||||||
|
|
||||||
rgDefault.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
|
rgDefault.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
|
||||||
rgProxy.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
|
rgZaborona.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
|
||||||
|
rgRandomProxy.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
|
||||||
|
rgVika.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
|
||||||
|
|
||||||
rg.setPadding(dp2px(18f), dp2px(12f), dp2px(18f), 0);
|
rg.setPadding(dp2px(18f), dp2px(12f), dp2px(18f), 0);
|
||||||
|
|
||||||
rgDefault.setText(AndroidUtils.getString("proxy_disable"));
|
rgDefault.setText(AndroidUtils.getString("proxy_disable"));
|
||||||
rgDefault.setTextColor(getTextAttr());
|
rgDefault.setTextColor(getTextAttr());
|
||||||
|
|
||||||
rgProxy.setText(AndroidUtils.getString("proxy_enable") + " (Zaborona)");
|
rgZaborona.setText(AndroidUtils.getString("proxy_enable") + " (Zaborona)");
|
||||||
rgProxy.setTextColor(getTextAttr());
|
rgZaborona.setTextColor(getTextAttr());
|
||||||
|
|
||||||
rgProxy.setChecked(isZaboronaEnabled());
|
rgRandomProxy.setText(AndroidUtils.getString("proxy_enable") + " (Random Proxy)");
|
||||||
rgDefault.setChecked(!isZaboronaEnabled());
|
rgRandomProxy.setTextColor(getTextAttr());
|
||||||
|
|
||||||
|
rgVika.setText(AndroidUtils.getString("proxy_enable") + " (Vika)");
|
||||||
|
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());
|
AlertDialog.Builder builder = new AlertDialog.Builder(ctx, getAlertStyle());
|
||||||
builder.setTitle(AndroidUtils.getString("vtlproxy"));
|
builder.setTitle(AndroidUtils.getString("vtlproxy"));
|
||||||
builder.setMessage(AndroidUtils.getString("proxy_warning"));
|
builder.setMessage(AndroidUtils.getString("proxy_warning"));
|
||||||
builder.setView(rg);
|
builder.setView(rg);
|
||||||
builder.setPositiveButton(AndroidUtils.getString("vtl_confirm"), ((dialog, which) -> { // Применить
|
builder.setPositiveButton(AndroidUtils.getString("vtl_confirm"), ((dialog, which) -> { // Применить
|
||||||
if (rgProxy.isChecked()) {
|
if (rgZaborona.isChecked()) {
|
||||||
edit().putString("proxy", "zaborona").commit();
|
edit().putString("proxy", "zaborona").commit();
|
||||||
restartApplication();
|
restartApplication();
|
||||||
|
} else if (rgRandomProxy.isChecked()) {
|
||||||
|
edit().putString("proxy", "randomproxy").commit();
|
||||||
|
restartApplication();
|
||||||
|
} else if (rgVika.isChecked()) {
|
||||||
|
edit().putString("proxy", "vika").commit();
|
||||||
|
restartApplication();
|
||||||
} else {
|
} else {
|
||||||
if (isZaboronaEnabled()) {
|
|
||||||
edit().putString("proxy", "noproxy").commit();
|
|
||||||
restartApplication();
|
|
||||||
}
|
|
||||||
|
|
||||||
edit().putString("proxy", "noproxy").commit();
|
edit().putString("proxy", "noproxy").commit();
|
||||||
|
restartApplication();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -91,47 +106,4 @@ public class ProxyHook {
|
|||||||
alert.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(getAccentColor());
|
alert.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(getAccentColor());
|
||||||
alert.getButton(DialogInterface.BUTTON_NEUTRAL).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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package ru.vtosters.lite.music;
|
package ru.vtosters.lite.music;
|
||||||
|
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
|
||||||
import static ru.vtosters.lite.utils.Preferences.getMusicDir;
|
import static ru.vtosters.lite.utils.Preferences.getMusicDir;
|
||||||
|
|
||||||
import android.app.DownloadManager;
|
import android.app.DownloadManager;
|
||||||
@@ -28,7 +29,7 @@ import ru.vtosters.lite.utils.AndroidUtils;
|
|||||||
|
|
||||||
public class MP3Downloader {
|
public class MP3Downloader {
|
||||||
|
|
||||||
private static final String URL_FORMAT = "https://api.vk.com/method/audio.getById?v=5.131&access_token=%s&audios=%s©right=https://vtosters.app/";
|
private static final String URL_FORMAT = "https://" + getApi() + "/method/audio.getById?v=5.131&access_token=%s&audios=%s©right=https://vtosters.app/";
|
||||||
private static final OkHttpClient client = new OkHttpClient();
|
private static final OkHttpClient client = new OkHttpClient();
|
||||||
|
|
||||||
public static void execute(MusicTrack track) {
|
public static void execute(MusicTrack track) {
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package ru.vtosters.lite.proxy;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
|
||||||
|
public class GithubList{
|
||||||
|
private static final OkHttpClient mClient = new OkHttpClient();
|
||||||
|
|
||||||
|
public static ArrayList<String> getProxy(String url, String proxyname) throws IOException{
|
||||||
|
Request link = new Request.a()
|
||||||
|
.b(url)
|
||||||
|
.a();
|
||||||
|
|
||||||
|
var response = mClient.a(link).execute().a().g();
|
||||||
|
|
||||||
|
if (!response.contains(":")) {
|
||||||
|
Log.d(proxyname, "No proxy found");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(proxyname, response);
|
||||||
|
|
||||||
|
return new ArrayList<>(Arrays.asList(response.split("\n")));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
package ru.vtosters.lite.proxy;
|
||||||
|
|
||||||
|
import static java.lang.System.clearProperty;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.util.ArrayMap;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import ru.vtosters.lite.proxy.http.CustomHttp;
|
||||||
|
import ru.vtosters.lite.proxy.https.CustomHttps;
|
||||||
|
import ru.vtosters.lite.proxy.socks.CustomSocks;
|
||||||
|
import ru.vtosters.lite.proxy.socks.Zaborona;
|
||||||
|
|
||||||
|
public class ProxyUtils{
|
||||||
|
public static String getApi(){
|
||||||
|
var proxyapi = getPrefsValue("proxyapi");
|
||||||
|
|
||||||
|
if (isApiProxyEnabled() & !proxyapi.isEmpty()) {
|
||||||
|
return proxyapi;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "api.vk.ru";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getOauth(){
|
||||||
|
var oauth = getPrefsValue("proxyoauth");
|
||||||
|
|
||||||
|
if (isApiProxyEnabled() & !oauth.isEmpty()) {
|
||||||
|
return oauth;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "oauth.vk.ru";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getStatic(){
|
||||||
|
var oauth = getPrefsValue("proxystatic");
|
||||||
|
|
||||||
|
if (isApiProxyEnabled() & !oauth.isEmpty()) {
|
||||||
|
return oauth;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "static.vk.ru";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean isZaboronaEnabled(){
|
||||||
|
return getPrefsValue("proxy").equals("zaborona");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean isRandomProxyEnabled(){
|
||||||
|
return getPrefsValue("proxy").equals("randomproxy");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean isApiProxyEnabled(){
|
||||||
|
return getPrefsValue("proxy").equals("apiproxy") || getPrefsValue("proxy").equals("vika");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean isVikaProxyEnabled(){
|
||||||
|
return getPrefsValue("proxy").equals("vika");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void forceProxyApplying(){
|
||||||
|
Log.d("Proxy", "Setting proxy...");
|
||||||
|
try {
|
||||||
|
var context = getGlobalContext().getApplicationContext();
|
||||||
|
Class<?> applicationClass = Class.forName("android.app.Application");
|
||||||
|
@SuppressLint("DiscouragedPrivateApi") @SuppressWarnings("JavaReflectionMemberAccess")
|
||||||
|
Field mLoadedApkField = applicationClass.getDeclaredField("mLoadedApk");
|
||||||
|
mLoadedApkField.setAccessible(true);
|
||||||
|
Object mLoadedApkObject = mLoadedApkField.get(context);
|
||||||
|
|
||||||
|
@SuppressLint("PrivateApi")
|
||||||
|
Class<?> loadedApkClass = Class.forName("android.app.LoadedApk");
|
||||||
|
@SuppressLint("DiscouragedPrivateApi") Field mReceiversField = loadedApkClass.getDeclaredField("mReceivers");
|
||||||
|
mReceiversField.setAccessible(true);
|
||||||
|
ArrayMap<?, ?> receivers = (ArrayMap<?, ?>) mReceiversField.get(mLoadedApkObject);
|
||||||
|
if (receivers != null) {
|
||||||
|
for (Object receiverMap : receivers.values()) {
|
||||||
|
for (Object receiver : ((ArrayMap<?, ?>) receiverMap).keySet()) {
|
||||||
|
Class<?> receiverClass = receiver.getClass();
|
||||||
|
|
||||||
|
if (receiverClass.getName().contains("ProxyChangeListener")) {
|
||||||
|
Method onReceiveMethod = receiverClass.getDeclaredMethod("onReceive", Context.class, Intent.class);
|
||||||
|
Intent intent = new Intent(android.net.Proxy.PROXY_CHANGE_ACTION);
|
||||||
|
onReceiveMethod.invoke(receiver, context, intent);
|
||||||
|
} else {
|
||||||
|
for (Field field : receiverClass.getDeclaredFields()) {
|
||||||
|
if (field.getType().getName().contains("ProxyChangeListener")) {
|
||||||
|
Method onReceiveMethod = receiverClass.getDeclaredMethod("onReceive", Context.class, Intent.class);
|
||||||
|
Intent intent = new Intent(android.net.Proxy.PROXY_CHANGE_ACTION);
|
||||||
|
onReceiveMethod.invoke(receiver, context, intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d("Proxy", "Setting proxy successful!");
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.d("Proxy", "Setting proxy failed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean hasProxy(String list){
|
||||||
|
return list.contains(":"); // proxy format: ip:port
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setProxy() throws IOException{
|
||||||
|
switch(getPrefsValue("proxy")) {
|
||||||
|
case "zaborona":
|
||||||
|
Zaborona.loadProxy();
|
||||||
|
break;
|
||||||
|
case "randomproxy":
|
||||||
|
RandomProxy.loadProxy();
|
||||||
|
break;
|
||||||
|
case "socks":
|
||||||
|
CustomSocks.loadProxy();
|
||||||
|
break;
|
||||||
|
case "http":
|
||||||
|
CustomHttp.loadProxy();
|
||||||
|
break;
|
||||||
|
case "https":
|
||||||
|
CustomHttps.loadProxy();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
resetProxy();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resetProxy(){
|
||||||
|
clearProperty("https.proxyHost");
|
||||||
|
clearProperty("https.proxyPort");
|
||||||
|
clearProperty("https.proxyUser");
|
||||||
|
clearProperty("https.proxyPassword");
|
||||||
|
clearProperty("http.proxyHost");
|
||||||
|
clearProperty("http.proxyPort");
|
||||||
|
clearProperty("http.proxyUser");
|
||||||
|
clearProperty("http.proxyPassword");
|
||||||
|
clearProperty("socksProxyHost");
|
||||||
|
clearProperty("socksPortHost");
|
||||||
|
} // Reset all proxies
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package ru.vtosters.lite.proxy;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.resetProxy;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
|
||||||
|
import static ru.vtosters.lite.utils.Preferences.preferences;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import ru.vtosters.lite.proxy.socks.Hookzof;
|
||||||
|
import ru.vtosters.lite.proxy.socks.Jetkai;
|
||||||
|
import ru.vtosters.lite.proxy.socks.Roosterkid;
|
||||||
|
import ru.vtosters.lite.proxy.socks.TheSpeedX;
|
||||||
|
|
||||||
|
public class RandomProxy{
|
||||||
|
public static String type = preferences.getString("random_type", "none");
|
||||||
|
public static String host = preferences.getString("random_host", "");
|
||||||
|
public static boolean showProxyResult = false;
|
||||||
|
|
||||||
|
public static void loadProxy() throws IOException{
|
||||||
|
if (host.isEmpty()) {
|
||||||
|
getProxy();
|
||||||
|
loadProxy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case "socks":
|
||||||
|
System.setProperty("socksProxyHost", host.split(":")[0]);
|
||||||
|
System.setProperty("socksProxyPort", host.split(":")[1]);
|
||||||
|
break;
|
||||||
|
case "http":
|
||||||
|
System.setProperty("http.proxyHost", host.split(":")[0]);
|
||||||
|
System.setProperty("http.proxyPort", host.split(":")[1]);
|
||||||
|
break;
|
||||||
|
case "https":
|
||||||
|
System.setProperty("https.proxyHost", host.split(":")[0]);
|
||||||
|
System.setProperty("https.proxyPort", host.split(":")[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setupNewProxy() throws IOException{
|
||||||
|
edit().putString("random_type", "none").putString("random_host", "").commit();
|
||||||
|
|
||||||
|
resetProxy();
|
||||||
|
forceProxyApplying();
|
||||||
|
|
||||||
|
showProxyResult = true;
|
||||||
|
getProxy();
|
||||||
|
edit().putString("proxy", "randomproxy").commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void getProxy() throws IOException{
|
||||||
|
var random = new java.util.Random();
|
||||||
|
var randomInt = random.nextInt(7);
|
||||||
|
switch(randomInt) {
|
||||||
|
case 0:
|
||||||
|
Hookzof.loadProxy();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
TheSpeedX.loadProxy();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Jetkai.loadProxy();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
Roosterkid.loadProxy();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
ru.vtosters.lite.proxy.http.Jetkai.loadProxy();
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
ru.vtosters.lite.proxy.http.TheSpeedX.loadProxy();
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
ru.vtosters.lite.proxy.https.Jetkai.loadProxy();
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
ru.vtosters.lite.proxy.https.Roosterkid.loadProxy();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package ru.vtosters.lite.proxy.api;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.isApiProxyEnabled;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.isVikaProxyEnabled;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class ApiProxy{
|
||||||
|
public static String linkReplacer(String link){
|
||||||
|
var vkapi = "api.vk.ru";
|
||||||
|
var oauth = "oauth.vk.ru";
|
||||||
|
var vkstatic = "static.vk.ru";
|
||||||
|
var vkapiold = "api.vk.com";
|
||||||
|
var oauthold = "oauth.vk.com";
|
||||||
|
var vkstaticold = "static.vk.com";
|
||||||
|
|
||||||
|
var proxyapi = getPrefsValue("proxyapi");
|
||||||
|
var proxyoauth = getPrefsValue("proxyoauth");
|
||||||
|
var proxystatic = getPrefsValue("proxystatic");
|
||||||
|
|
||||||
|
if (isVikaProxyEnabled()) {
|
||||||
|
proxyapi = VikaMobile.getApiHost();
|
||||||
|
proxyoauth = VikaMobile.getOauthHost();
|
||||||
|
proxystatic = VikaMobile.getStaticHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!isApiProxyEnabled() || !isVikaProxyEnabled()) || 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.replaceAll(vkapi, proxyapi);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link.contains(oauth)) {
|
||||||
|
return link.replaceAll(oauth, proxyoauth);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link.contains(vkstatic)) {
|
||||||
|
return link.replaceAll(vkstatic, proxystatic);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link.contains(vkapiold)) {
|
||||||
|
return link.replaceAll(vkapiold, proxyapi);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link.contains(oauthold)) {
|
||||||
|
return link.replaceAll(vkapiold, proxyoauth);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link.contains(vkstaticold)) {
|
||||||
|
return link.replaceAll(vkapiold, proxystatic);
|
||||||
|
}
|
||||||
|
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String staticFix(String str) {
|
||||||
|
var string = getPrefsValue("proxystatic");
|
||||||
|
|
||||||
|
if (isVikaProxyEnabled()) {
|
||||||
|
string = VikaMobile.getStaticHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((isApiProxyEnabled() || isVikaProxyEnabled()) && string.isEmpty()) return str;
|
||||||
|
|
||||||
|
return str.replaceAll(string, "static.vk.ru");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getAwayPhpCom(){
|
||||||
|
var proxyapi = getPrefsValue("proxyapi");
|
||||||
|
|
||||||
|
if ((isApiProxyEnabled() || isVikaProxyEnabled()) & !proxyapi.isEmpty()) {
|
||||||
|
return proxyapi;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "m.vk.ru";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package ru.vtosters.lite.proxy.api;
|
||||||
|
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
|
||||||
|
|
||||||
|
public class VikaMobile{
|
||||||
|
public static String getApiHost(){
|
||||||
|
return isAlternativeHost() ? "vk-api-proxy.vikamobile.ru" : "vk-api-proxy.symbian.live";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getOauthHost(){
|
||||||
|
return isAlternativeHost() ? "vk-oauth-proxy.vikamobile.ru" : "vk-oauth-proxy.symbian.live";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getStaticHost(){
|
||||||
|
return isAlternativeHost() ? "vk-static-proxy.vikamobile.ru" : "vk-static-proxy.symbian.live";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean isAlternativeHost(){
|
||||||
|
return getBoolValue("altervika", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package ru.vtosters.lite.proxy.http;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
|
||||||
|
|
||||||
|
public class CustomHttp{
|
||||||
|
public static void loadProxy(){
|
||||||
|
System.setProperty("http.proxyHost", proxyHostHTTP());
|
||||||
|
System.setProperty("http.proxyPort", proxyPortHTTP());
|
||||||
|
System.setProperty("http.proxyUser", proxyUserHTTP());
|
||||||
|
System.setProperty("http.proxyPassword", proxyPassHTTP());
|
||||||
|
forceProxyApplying();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String proxyHostHTTP(){
|
||||||
|
var string = getPrefsValue("proxyHostHTTP");
|
||||||
|
return string.isEmpty() ? "192.168.0.1" : string;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String proxyPortHTTP(){
|
||||||
|
var string = getPrefsValue("proxyPortHTTP");
|
||||||
|
return string.isEmpty() ? "8888" : string;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String proxyUserHTTP(){
|
||||||
|
var string = getPrefsValue("proxyUserHTTP");
|
||||||
|
return string.isEmpty() ? "" : string;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String proxyPassHTTP(){
|
||||||
|
var string = getPrefsValue("proxyPassHTTP");
|
||||||
|
return string.isEmpty() ? "" : string;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package ru.vtosters.lite.proxy.http;
|
||||||
|
import static ru.vtosters.lite.proxy.GithubList.getProxy;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.hasProxy;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import ru.vtosters.lite.proxy.RandomProxy;
|
||||||
|
import ru.vtosters.lite.utils.AndroidUtils;
|
||||||
|
|
||||||
|
public class Jetkai{
|
||||||
|
private static final String TAG = "Jetkai_Http";
|
||||||
|
|
||||||
|
public static void loadProxy() throws IOException{
|
||||||
|
ArrayList<String> proxyList = getProxy("https://raw.githubusercontent.com/jetkai/proxy-list/main/online-proxies/txt/proxies-http.txt", TAG);
|
||||||
|
|
||||||
|
if (proxyList == null) {
|
||||||
|
Log.d(TAG, "No proxy found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String proxy = proxyList.get(new java.util.Random().nextInt(proxyList.size()));
|
||||||
|
|
||||||
|
if (!hasProxy(proxy)) {
|
||||||
|
Log.d(TAG, "No proxy port found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "Setting proxy: " + proxy.split(":")[0] + ":" + proxy.split(":")[1]);
|
||||||
|
|
||||||
|
if (RandomProxy.showProxyResult) {
|
||||||
|
AndroidUtils.sendToast(getString("proxy_setup_success") + " " + proxy);
|
||||||
|
RandomProxy.showProxyResult = false;
|
||||||
|
RandomProxy.showProxyResult = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
edit().putString("random_type", "http").putString("random_host", proxy).commit();
|
||||||
|
|
||||||
|
System.setProperty("http.proxyHost", proxy.split(":")[0]);
|
||||||
|
System.setProperty("http.proxyPort", proxy.split(":")[1]);
|
||||||
|
forceProxyApplying();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package ru.vtosters.lite.proxy.http;
|
||||||
|
import static ru.vtosters.lite.proxy.GithubList.getProxy;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.hasProxy;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import ru.vtosters.lite.proxy.RandomProxy;
|
||||||
|
import ru.vtosters.lite.utils.AndroidUtils;
|
||||||
|
|
||||||
|
public class TheSpeedX{
|
||||||
|
private static final String TAG = "TheSpeedX_Http";
|
||||||
|
|
||||||
|
public static void loadProxy() throws IOException{
|
||||||
|
ArrayList<String> proxyList = getProxy("https://raw.githubusercontent.com/TheSpeedX/PROXY-List/master/http.txt", TAG);
|
||||||
|
|
||||||
|
if (proxyList == null) {
|
||||||
|
Log.d(TAG, "No proxy found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String proxy = proxyList.get(new java.util.Random().nextInt(proxyList.size()));
|
||||||
|
|
||||||
|
if (!hasProxy(proxy)) {
|
||||||
|
Log.d(TAG, "No proxy port found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "Setting proxy: " + proxy.split(":")[0] + ":" + proxy.split(":")[1]);
|
||||||
|
|
||||||
|
if (RandomProxy.showProxyResult) {
|
||||||
|
AndroidUtils.sendToast(getString("proxy_setup_success") + " " + proxy);
|
||||||
|
RandomProxy.showProxyResult = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
edit().putString("random_type", "http").putString("random_host", proxy).commit();
|
||||||
|
|
||||||
|
System.setProperty("http.proxyHost", proxy.split(":")[0]);
|
||||||
|
System.setProperty("http.proxyPort", proxy.split(":")[1]);
|
||||||
|
forceProxyApplying();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package ru.vtosters.lite.proxy.https;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
|
||||||
|
|
||||||
|
public class CustomHttps{
|
||||||
|
public static void loadProxy(){
|
||||||
|
System.setProperty("https.proxyHost", proxyHostHTTPS());
|
||||||
|
System.setProperty("https.proxyPort", proxyPortHTTPS());
|
||||||
|
System.setProperty("https.proxyUser", proxyUserHTTPS());
|
||||||
|
System.setProperty("https.proxyPassword", proxyPassHTTPS());
|
||||||
|
forceProxyApplying();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String proxyHostHTTPS(){
|
||||||
|
var string = getPrefsValue("proxyHostHTTPS");
|
||||||
|
return string.isEmpty() ? "192.168.0.1" : string;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String proxyPortHTTPS(){
|
||||||
|
var string = getPrefsValue("proxyPortHTTPS");
|
||||||
|
return string.isEmpty() ? "8888" : string;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String proxyUserHTTPS(){
|
||||||
|
var string = getPrefsValue("proxyUserHTTPS");
|
||||||
|
return string.isEmpty() ? "" : string;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String proxyPassHTTPS(){
|
||||||
|
String string = getPrefsValue("proxyPassHTTPS");
|
||||||
|
return string.isEmpty() ? "" : string;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package ru.vtosters.lite.proxy.https;
|
||||||
|
import static ru.vtosters.lite.proxy.GithubList.getProxy;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.hasProxy;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import ru.vtosters.lite.proxy.RandomProxy;
|
||||||
|
import ru.vtosters.lite.utils.AndroidUtils;
|
||||||
|
|
||||||
|
public class Jetkai{
|
||||||
|
private static final String TAG = "Jetkai_Https";
|
||||||
|
|
||||||
|
public static void loadProxy() throws IOException{
|
||||||
|
ArrayList<String> proxyList = getProxy("https://raw.githubusercontent.com/jetkai/proxy-list/main/online-proxies/txt/proxies-https.txt", TAG);
|
||||||
|
|
||||||
|
if (proxyList == null) {
|
||||||
|
Log.d(TAG, "No proxy found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String proxy = proxyList.get(new java.util.Random().nextInt(proxyList.size()));
|
||||||
|
|
||||||
|
if (!hasProxy(proxy)) {
|
||||||
|
Log.d(TAG, "No proxy port found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "Setting proxy: " + proxy.split(":")[0] + ":" + proxy.split(":")[1]);
|
||||||
|
|
||||||
|
if (RandomProxy.showProxyResult) {
|
||||||
|
AndroidUtils.sendToast(getString("proxy_setup_success") + " " + proxy);
|
||||||
|
RandomProxy.showProxyResult = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
edit().putString("random_type", "https").putString("random_host", proxy).commit();
|
||||||
|
|
||||||
|
System.setProperty("https.proxyHost", proxy.split(":")[0]);
|
||||||
|
System.setProperty("https.proxyPort", proxy.split(":")[1]);
|
||||||
|
forceProxyApplying();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package ru.vtosters.lite.proxy.https;
|
||||||
|
import static ru.vtosters.lite.proxy.GithubList.getProxy;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.hasProxy;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import ru.vtosters.lite.proxy.RandomProxy;
|
||||||
|
import ru.vtosters.lite.utils.AndroidUtils;
|
||||||
|
|
||||||
|
public class Roosterkid{
|
||||||
|
private static final String TAG = "Roosterkid_Https";
|
||||||
|
|
||||||
|
public static void loadProxy() throws IOException{
|
||||||
|
ArrayList<String> proxyList = getProxy("https://raw.githubusercontent.com/roosterkid/openproxylist/main/HTTPS_RAW.txt", TAG);
|
||||||
|
|
||||||
|
if (proxyList == null) {
|
||||||
|
Log.d(TAG, "No proxy found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String proxy = proxyList.get(new java.util.Random().nextInt(proxyList.size()));
|
||||||
|
|
||||||
|
if (!hasProxy(proxy)) {
|
||||||
|
Log.d(TAG, "No proxy port found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "Setting proxy: " + proxy.split(":")[0] + ":" + proxy.split(":")[1]);
|
||||||
|
|
||||||
|
if (RandomProxy.showProxyResult) {
|
||||||
|
AndroidUtils.sendToast(getString("proxy_setup_success") + " " + proxy);
|
||||||
|
RandomProxy.showProxyResult = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
edit().putString("random_type", "https").putString("random_host", proxy).commit();
|
||||||
|
|
||||||
|
System.setProperty("https.proxyHost", proxy.split(":")[0]);
|
||||||
|
System.setProperty("https.proxyPort", proxy.split(":")[1]);
|
||||||
|
forceProxyApplying();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package ru.vtosters.lite.proxy.socks;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
|
||||||
|
|
||||||
|
public class CustomSocks{
|
||||||
|
public static void loadProxy(){
|
||||||
|
System.setProperty("socksProxyHost", proxyHostSocks());
|
||||||
|
System.setProperty("socksProxyPort", proxyPortSocks());
|
||||||
|
forceProxyApplying();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String proxyHostSocks(){
|
||||||
|
var string = getPrefsValue("proxyHostSocks");
|
||||||
|
return string.isEmpty() ? "192.168.0.1" : string;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String proxyPortSocks(){
|
||||||
|
var string = getPrefsValue("proxyPortSocks");
|
||||||
|
return string.isEmpty() ? "8888" : string;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package ru.vtosters.lite.proxy.socks;
|
||||||
|
import static ru.vtosters.lite.proxy.GithubList.getProxy;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.hasProxy;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import ru.vtosters.lite.proxy.RandomProxy;
|
||||||
|
import ru.vtosters.lite.utils.AndroidUtils;
|
||||||
|
|
||||||
|
public class Hookzof{
|
||||||
|
private static final String TAG = "Hookzof_Socks";
|
||||||
|
|
||||||
|
public static void loadProxy() throws IOException{
|
||||||
|
ArrayList<String> proxyList = getProxy("https://raw.githubusercontent.com/hookzof/socks5_list/master/proxy.txt", TAG);
|
||||||
|
|
||||||
|
if (proxyList == null) {
|
||||||
|
Log.d(TAG, "No proxy found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String proxy = proxyList.get(new java.util.Random().nextInt(proxyList.size()));
|
||||||
|
|
||||||
|
if (!hasProxy(proxy)) {
|
||||||
|
Log.d(TAG, "No proxy port found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "Setting proxy: " + proxy.split(":")[0] + ":" + proxy.split(":")[1]);
|
||||||
|
|
||||||
|
if (RandomProxy.showProxyResult) {
|
||||||
|
AndroidUtils.sendToast(getString("proxy_setup_success") + " " + proxy);
|
||||||
|
RandomProxy.showProxyResult = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
edit().putString("random_type", "socks").putString("random_host", proxy).commit();
|
||||||
|
|
||||||
|
System.setProperty("socksProxyHost", proxy.split(":")[0]);
|
||||||
|
System.setProperty("socksProxyPort", proxy.split(":")[1]);
|
||||||
|
forceProxyApplying();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package ru.vtosters.lite.proxy.socks;
|
||||||
|
import static ru.vtosters.lite.proxy.GithubList.getProxy;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.hasProxy;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import ru.vtosters.lite.proxy.RandomProxy;
|
||||||
|
import ru.vtosters.lite.utils.AndroidUtils;
|
||||||
|
|
||||||
|
public class Jetkai{
|
||||||
|
private static final String TAG = "Jetkai_Socks";
|
||||||
|
|
||||||
|
public static void loadProxy() throws IOException{
|
||||||
|
ArrayList<String> proxyList = getProxy("https://raw.githubusercontent.com/jetkai/proxy-list/main/online-proxies/txt/proxies-socks5.txt", TAG);
|
||||||
|
|
||||||
|
if (proxyList == null) {
|
||||||
|
Log.d(TAG, "No proxy found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String proxy = proxyList.get(new java.util.Random().nextInt(proxyList.size()));
|
||||||
|
|
||||||
|
if (!hasProxy(proxy)) {
|
||||||
|
Log.d(TAG, "No proxy port found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "Setting proxy: " + proxy.split(":")[0] + ":" + proxy.split(":")[1]);
|
||||||
|
|
||||||
|
if (RandomProxy.showProxyResult) {
|
||||||
|
AndroidUtils.sendToast(getString("proxy_setup_success") + " " + proxy);
|
||||||
|
RandomProxy.showProxyResult = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
edit().putString("random_type", "socks").putString("random_host", proxy).commit();
|
||||||
|
|
||||||
|
System.setProperty("socksProxyHost", proxy.split(":")[0]);
|
||||||
|
System.setProperty("socksProxyPort", proxy.split(":")[1]);
|
||||||
|
forceProxyApplying();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package ru.vtosters.lite.proxy.socks;
|
||||||
|
import static ru.vtosters.lite.proxy.GithubList.getProxy;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.hasProxy;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import ru.vtosters.lite.proxy.RandomProxy;
|
||||||
|
import ru.vtosters.lite.utils.AndroidUtils;
|
||||||
|
|
||||||
|
public class Roosterkid{
|
||||||
|
private static final String TAG = "Roosterkid_Socks";
|
||||||
|
|
||||||
|
public static void loadProxy() throws IOException{
|
||||||
|
ArrayList<String> proxyList = getProxy("https://raw.githubusercontent.com/roosterkid/openproxylist/main/SOCKS5_RAW.txt", TAG);
|
||||||
|
|
||||||
|
if (proxyList == null) {
|
||||||
|
Log.d(TAG, "No proxy found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String proxy = proxyList.get(new java.util.Random().nextInt(proxyList.size()));
|
||||||
|
|
||||||
|
if (!hasProxy(proxy)) {
|
||||||
|
Log.d(TAG, "No proxy port found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "Setting proxy: " + proxy.split(":")[0] + ":" + proxy.split(":")[1]);
|
||||||
|
|
||||||
|
if (RandomProxy.showProxyResult) {
|
||||||
|
AndroidUtils.sendToast(getString("proxy_setup_success") + " " + proxy);
|
||||||
|
RandomProxy.showProxyResult = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
edit().putString("random_type", "socks").putString("random_host", proxy).commit();
|
||||||
|
|
||||||
|
System.setProperty("socksProxyHost", proxy.split(":")[0]);
|
||||||
|
System.setProperty("socksProxyPort", proxy.split(":")[1]);
|
||||||
|
forceProxyApplying();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package ru.vtosters.lite.proxy.socks;
|
||||||
|
import static ru.vtosters.lite.proxy.GithubList.getProxy;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.hasProxy;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import ru.vtosters.lite.proxy.RandomProxy;
|
||||||
|
import ru.vtosters.lite.utils.AndroidUtils;
|
||||||
|
|
||||||
|
public class TheSpeedX{
|
||||||
|
private static final String TAG = "TheSpeedX_Socks";
|
||||||
|
|
||||||
|
public static void loadProxy() throws IOException{
|
||||||
|
ArrayList<String> proxyList = getProxy("https://raw.githubusercontent.com/TheSpeedX/PROXY-List/master/socks5.txt", TAG);
|
||||||
|
|
||||||
|
if (proxyList == null) {
|
||||||
|
Log.d(TAG, "No proxy found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String proxy = proxyList.get(new java.util.Random().nextInt(proxyList.size()));
|
||||||
|
|
||||||
|
if (!hasProxy(proxy)) {
|
||||||
|
Log.d(TAG, "No proxy port found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "Setting proxy: " + proxy.split(":")[0] + ":" + proxy.split(":")[1]);
|
||||||
|
|
||||||
|
if (RandomProxy.showProxyResult) {
|
||||||
|
AndroidUtils.sendToast(getString("proxy_setup_success") + " " + proxy);
|
||||||
|
RandomProxy.showProxyResult = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
edit().putString("random_type", "socks").putString("random_host", proxy).commit();
|
||||||
|
|
||||||
|
System.setProperty("socksProxyHost", proxy.split(":")[0]);
|
||||||
|
System.setProperty("socksProxyPort", proxy.split(":")[1]);
|
||||||
|
forceProxyApplying();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package ru.vtosters.lite.proxy.socks;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.forceProxyApplying;
|
||||||
|
|
||||||
|
public class Zaborona{
|
||||||
|
public static void loadProxy(){
|
||||||
|
System.setProperty("socksProxyHost", "socks.zaboronahelp.pp.ua");
|
||||||
|
System.setProperty("socksProxyPort", "1488");
|
||||||
|
forceProxyApplying();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package ru.vtosters.lite.ui.activities;
|
package ru.vtosters.lite.ui.activities;
|
||||||
|
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.getOauth;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@@ -20,7 +22,7 @@ import ru.vtosters.lite.utils.LayoutUtils;
|
|||||||
|
|
||||||
public class VKAdminTokenActivity extends AppCompatActivity {
|
public class VKAdminTokenActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private static final String URL = "https://oauth.vk.com/authorize?client_id=6121396&scope=1073737727&redirect_uri=https://oauth.vk.com/blank.html&display=page&response_type=token&revoke=1";
|
private static final String URL = "https://" + getOauth() +"/authorize?client_id=6121396&scope=1073737727&redirect_uri=https://oauth.vk.ru/blank.html&display=page&response_type=token&revoke=1";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable Bundle bundle) {
|
protected void onCreate(@Nullable Bundle bundle) {
|
||||||
@@ -37,7 +39,7 @@ public class VKAdminTokenActivity extends AppCompatActivity {
|
|||||||
@Override
|
@Override
|
||||||
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
|
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
|
||||||
var url = request.getUrl().toString();
|
var url = request.getUrl().toString();
|
||||||
if (url.startsWith("https://oauth.vk.com/auth_redirect?")) {
|
if (url.startsWith("https://" + getOauth() + "/auth_redirect?")) {
|
||||||
var redirectUri = Uri.parse(URLDecoder.decode(url));
|
var redirectUri = Uri.parse(URLDecoder.decode(url));
|
||||||
var authorizeUrl = redirectUri.getQueryParameter("authorize_url");
|
var authorizeUrl = redirectUri.getQueryParameter("authorize_url");
|
||||||
var accessToken = authorizeUrl.substring(authorizeUrl.indexOf("=") + 1, authorizeUrl.indexOf("&"));
|
var accessToken = authorizeUrl.substring(authorizeUrl.indexOf("=") + 1, authorizeUrl.indexOf("&"));
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ import ru.vtosters.lite.ui.items.DockBarTab;
|
|||||||
import ru.vtosters.lite.utils.AndroidUtils;
|
import ru.vtosters.lite.utils.AndroidUtils;
|
||||||
|
|
||||||
public class DockBarEditorManager {
|
public class DockBarEditorManager {
|
||||||
|
|
||||||
public static final int MIN_SELECTED_TABS = 3;
|
public static final int MIN_SELECTED_TABS = 3;
|
||||||
public static final int MAX_SELECTED_TABS = 9;
|
public static final int MAX_SELECTED_TABS = 9;
|
||||||
|
|
||||||
@@ -98,17 +97,15 @@ public class DockBarEditorManager {
|
|||||||
private void parseSelectedTabs(String[] selectedTabsTags) {
|
private void parseSelectedTabs(String[] selectedTabsTags) {
|
||||||
List<String> allTags = new ArrayList<>(Arrays.asList("tab_news", "tab_superapps", "tab_messages", "tab_feedback", "tab_profile",
|
List<String> allTags = new ArrayList<>(Arrays.asList("tab_news", "tab_superapps", "tab_messages", "tab_feedback", "tab_profile",
|
||||||
"tab_friends", "tab_groups", "tab_photos", "tab_audios", "tab_videos", "tab_lives", "tab_games", "tab_liked",
|
"tab_friends", "tab_groups", "tab_photos", "tab_audios", "tab_videos", "tab_lives", "tab_games", "tab_liked",
|
||||||
"tab_fave", "tab_documents", "tab_payments", "tab_vk_apps", "tab_settings", "tab_menu"));
|
"tab_fave", "tab_documents", "tab_payments", "tab_vk_apps", "tab_settings"));
|
||||||
|
|
||||||
for (String tag : selectedTabsTags) {
|
for (String tag : selectedTabsTags) {
|
||||||
mSelectedTabs.add(getTabByTag(tag));
|
mSelectedTabs.add(getTabByTag(tag));
|
||||||
allTags.remove(tag);
|
allTags.remove(tag);
|
||||||
}
|
}
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
||||||
allTags.forEach(tag -> mDisabledTabs.add(getTabByTag(tag)));
|
for (String tag : allTags) {
|
||||||
} else {
|
mDisabledTabs.add(getTabByTag(tag));
|
||||||
for (String tag : allTags) {
|
|
||||||
mDisabledTabs.add(getTabByTag(tag));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,13 +260,6 @@ public class DockBarEditorManager {
|
|||||||
R.string.menu_apps,
|
R.string.menu_apps,
|
||||||
R.id.menu_vk_apps,
|
R.id.menu_vk_apps,
|
||||||
AppsFragment.class);
|
AppsFragment.class);
|
||||||
case "tab_menu":
|
|
||||||
return DockBarTab.valuesOf(
|
|
||||||
"tab_menu",
|
|
||||||
milkshake() ? R.drawable.ic_user_circle_outline_28 : R.drawable.ic_menu_more_outline_28,
|
|
||||||
milkshake() ? R.string.profile : R.string.menu,
|
|
||||||
R.id.tab_menu,
|
|
||||||
milkshake() ? ProfileFragment.class : MenuFragment.class);
|
|
||||||
case "tab_settings":
|
case "tab_settings":
|
||||||
default:
|
default:
|
||||||
return DockBarTab.valuesOf(
|
return DockBarTab.valuesOf(
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class NewsfeedListManager {
|
|||||||
var list = new ArrayList<VBListItem>();
|
var list = new ArrayList<VBListItem>();
|
||||||
|
|
||||||
if (filtersSet.size() == 0) {
|
if (filtersSet.size() == 0) {
|
||||||
sendToast(AndroidUtils.getString("newsfeed_update_feed"));
|
sendToast(AndroidUtils.getString("newsfeed_list_update_feed"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,8 +55,7 @@ public class NewsfeedListManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void resetHideItems() {
|
public static void resetHideItems() {
|
||||||
getDefaultPrefs().edit()
|
getDefaultPrefs().edit().remove("news_feed_selected_items").remove("news_feed_items_set")
|
||||||
.putString("news_feed_selected_items", "")
|
|
||||||
.apply();
|
.apply();
|
||||||
sendToast(AndroidUtils.getString("newsfeed_list_hidden_reseted"));
|
sendToast(AndroidUtils.getString("newsfeed_list_hidden_reseted"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class InstallGMS {
|
|||||||
public static void alert(final Activity activity) {
|
public static void alert(final Activity activity) {
|
||||||
if (!isGmsInstalled()) {
|
if (!isGmsInstalled()) {
|
||||||
VkAlertDialog.Builder builder = new VkAlertDialog.Builder(activity);
|
VkAlertDialog.Builder builder = new VkAlertDialog.Builder(activity);
|
||||||
builder.setTitle(getString("debug_warning"));
|
builder.setTitle(getString("warning"));
|
||||||
builder.setMessage(getString("gmsissuesumm"));
|
builder.setMessage(getString("gmsissuesumm"));
|
||||||
builder.setCancelable(false);
|
builder.setCancelable(false);
|
||||||
builder.setPositiveButton(getString("gmsissuebtn1"), (dialogInterface, i) -> edit().putBoolean("showAlertGms", false).apply());
|
builder.setPositiveButton(getString("gmsissuebtn1"), (dialogInterface, i) -> edit().putBoolean("showAlertGms", false).apply());
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class Start {
|
|||||||
activity.requestPermissions(new String[]{"android.permission.WRITE_EXTERNAL_STORAGE"}, 228);
|
activity.requestPermissions(new String[]{"android.permission.WRITE_EXTERNAL_STORAGE"}, 228);
|
||||||
}
|
}
|
||||||
VkAlertDialog.Builder builder = new VkAlertDialog.Builder(activity);
|
VkAlertDialog.Builder builder = new VkAlertDialog.Builder(activity);
|
||||||
builder.setTitle(getString("debug_warning"));
|
builder.setTitle(getString("warning"));
|
||||||
builder.setMessage(getWelcome());
|
builder.setMessage(getWelcome());
|
||||||
builder.setCancelable(false);
|
builder.setCancelable(false);
|
||||||
// android.content.DialogInterface.OnClickListener
|
// android.content.DialogInterface.OnClickListener
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package ru.vtosters.lite.ui.dialogs;
|
package ru.vtosters.lite.ui.dialogs;
|
||||||
|
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.isApiProxyEnabled;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||||
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
|
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
|
||||||
@@ -15,7 +17,7 @@ import ru.vtosters.lite.ui.fragments.VKUIwrapper;
|
|||||||
public class VKIDProtection {
|
public class VKIDProtection {
|
||||||
public static void alert(final Activity activity) {
|
public static void alert(final Activity activity) {
|
||||||
VkAlertDialog.Builder builder = new VkAlertDialog.Builder(activity);
|
VkAlertDialog.Builder builder = new VkAlertDialog.Builder(activity);
|
||||||
builder.setTitle(getString("debug_warning"));
|
builder.setTitle(getString("warning"));
|
||||||
builder.setMessage(getString("vkidsumm"));
|
builder.setMessage(getString("vkidsumm"));
|
||||||
builder.setCancelable(false);
|
builder.setCancelable(false);
|
||||||
// android.content.DialogInterface.OnClickListener
|
// android.content.DialogInterface.OnClickListener
|
||||||
@@ -23,7 +25,7 @@ public class VKIDProtection {
|
|||||||
// android.content.DialogInterface.OnClickListener
|
// android.content.DialogInterface.OnClickListener
|
||||||
builder.setNeutralButton(getString("vkiddisable"), (dialogInterface, i) -> {
|
builder.setNeutralButton(getString("vkiddisable"), (dialogInterface, i) -> {
|
||||||
edit().putBoolean("showAlertVkId", false).apply();
|
edit().putBoolean("showAlertVkId", false).apply();
|
||||||
VKUIwrapper.setLink("https://id.vk.com/account");
|
VKUIwrapper.setLink((isApiProxyEnabled() ? "https://id.vk.ru/account" : "https://" + getApi() + "/_/id.vk.ru/account"));
|
||||||
Intent a2 = new Navigator(VKUIwrapper.class).b(activity);
|
Intent a2 = new Navigator(VKUIwrapper.class).b(activity);
|
||||||
a2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
a2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
activity.startActivity(a2);
|
activity.startActivity(a2);
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
package ru.vtosters.lite.ui.fragments;
|
package ru.vtosters.lite.ui.fragments;
|
||||||
|
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getDefaultPrefs;
|
import static ru.vtosters.lite.utils.AndroidUtils.getDefaultPrefs;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
|
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
|
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
|
||||||
import static ru.vtosters.lite.utils.Preferences.copyright_post;
|
import static ru.vtosters.lite.utils.Preferences.copyright_post;
|
||||||
|
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -12,6 +17,7 @@ import android.text.TextUtils;
|
|||||||
|
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
|
import com.vk.core.dialogs.alert.VkAlertDialog;
|
||||||
import com.vk.navigation.Navigator;
|
import com.vk.navigation.Navigator;
|
||||||
import com.vk.newsfeed.NewsfeedSettingsFragment;
|
import com.vk.newsfeed.NewsfeedSettingsFragment;
|
||||||
import com.vtosters.lite.general.fragments.MaterialPreferenceToolbarFragment;
|
import com.vtosters.lite.general.fragments.MaterialPreferenceToolbarFragment;
|
||||||
@@ -34,6 +40,20 @@ public class FeedFragment extends MaterialPreferenceToolbarFragment {
|
|||||||
findPreference("spamfilters").setSummary(count(getPrefsValue("spamfilters")));
|
findPreference("spamfilters").setSummary(count(getPrefsValue("spamfilters")));
|
||||||
findPreference("sourcenamefilter").setSummary(count(getPrefsValue("sourcenamefilter")));
|
findPreference("sourcenamefilter").setSummary(count(getPrefsValue("sourcenamefilter")));
|
||||||
findPreference("linkfilter").setSummary(count(getPrefsValue("linkfilter")));
|
findPreference("linkfilter").setSummary(count(getPrefsValue("linkfilter")));
|
||||||
|
|
||||||
|
findPreference("whitelisted_ad_groups").setSummary(countSet("whitelisted_ad_groups"));
|
||||||
|
findPreference("whitelisted_filters_groups").setSummary(countSet("whitelisted_filters_groups"));
|
||||||
|
|
||||||
|
findPreference("whitelisted_ad_groups").setOnPreferenceClickListener(preference -> {
|
||||||
|
remdialog("whitelisted_ad_groups", getContext());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
findPreference("whitelisted_filters_groups").setOnPreferenceClickListener(preference -> {
|
||||||
|
remdialog("whitelisted_filters_groups", getContext());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
findPreference("newsfeedlistmanager").setOnPreferenceClickListener(preference -> {
|
findPreference("newsfeedlistmanager").setOnPreferenceClickListener(preference -> {
|
||||||
NewsfeedListManager.callEditorPopup(getActivity());
|
NewsfeedListManager.callEditorPopup(getActivity());
|
||||||
return true;
|
return true;
|
||||||
@@ -59,6 +79,38 @@ public class FeedFragment extends MaterialPreferenceToolbarFragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void remdialog(String key, Context context) {
|
||||||
|
VkAlertDialog.Builder builder = new VkAlertDialog.Builder(context);
|
||||||
|
builder.setTitle(AndroidUtils.getString("warning"));
|
||||||
|
builder.setMessage(AndroidUtils.getString("delete_elements_confirm"));
|
||||||
|
builder.setCancelable(false);
|
||||||
|
builder.setPositiveButton(AndroidUtils.getString("yes"), (dialogInterface, i) -> {
|
||||||
|
edit().remove(key).apply();
|
||||||
|
sendToast(AndroidUtils.getString("elements_deleted_success"));
|
||||||
|
});
|
||||||
|
builder.setNegativeButton(AndroidUtils.getString("cancel"), (dialogInterface, i) -> dialogInterface.dismiss());
|
||||||
|
builder.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String countSet(String key) {
|
||||||
|
var set = getDefaultPrefs().getStringSet(key, null);
|
||||||
|
StringBuilder str = new StringBuilder();
|
||||||
|
if (set != null) {
|
||||||
|
for (var s : set) {
|
||||||
|
str.append(s).append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var count = str.toString().split(", ").length;
|
||||||
|
|
||||||
|
if (count < 1 || (str.length() == 0)) {
|
||||||
|
return AndroidUtils.getString("feed_no_elements");
|
||||||
|
} else {
|
||||||
|
return String.format(AndroidUtils.getString("feed_elements_count"), count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceTreeClick(Preference preference) {
|
public boolean onPreferenceTreeClick(Preference preference) {
|
||||||
findPreference("cringecopyright").setEnabled(!copyright_post());
|
findPreference("cringecopyright").setEnabled(!copyright_post());
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
|
|||||||
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
|
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
|
||||||
import static ru.vtosters.lite.utils.Preferences.hasVerification;
|
import static ru.vtosters.lite.utils.Preferences.hasVerification;
|
||||||
import static ru.vtosters.lite.utils.Preferences.preferences;
|
import static ru.vtosters.lite.utils.Preferences.preferences;
|
||||||
import static ru.vtosters.lite.utils.ProxyUtils.isZaboronaEnabled;
|
|
||||||
import static ru.vtosters.lite.utils.ThemesUtils.getAccentColor;
|
import static ru.vtosters.lite.utils.ThemesUtils.getAccentColor;
|
||||||
import static ru.vtosters.lite.utils.ThemesUtils.getAlertStyle;
|
import static ru.vtosters.lite.utils.ThemesUtils.getAlertStyle;
|
||||||
import static ru.vtosters.lite.utils.ThemesUtils.getTextAttr;
|
import static ru.vtosters.lite.utils.ThemesUtils.getTextAttr;
|
||||||
@@ -42,6 +41,9 @@ import ru.vtosters.lite.utils.AndroidUtils;
|
|||||||
public class IconsFragment extends MaterialPreferenceToolbarFragment {
|
public class IconsFragment extends MaterialPreferenceToolbarFragment {
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
public static void callSelectDialog(Context ctx, String appicon) {
|
public static void callSelectDialog(Context ctx, String appicon) {
|
||||||
|
var defname = preferences.getString("appname", "vt");
|
||||||
|
var deficon = preferences.getString("selectedicon", "vt");
|
||||||
|
|
||||||
RadioGroup rg = new RadioGroup(ctx);
|
RadioGroup rg = new RadioGroup(ctx);
|
||||||
|
|
||||||
RadioButton rgDefault = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
|
RadioButton rgDefault = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
|
||||||
@@ -67,17 +69,14 @@ public class IconsFragment extends MaterialPreferenceToolbarFragment {
|
|||||||
rgVKontakte.setText(AndroidUtils.getString("app_name_alter"));
|
rgVKontakte.setText(AndroidUtils.getString("app_name_alter"));
|
||||||
rgVKontakte.setTextColor(getTextAttr());
|
rgVKontakte.setTextColor(getTextAttr());
|
||||||
|
|
||||||
rgVKontakte.setChecked(isZaboronaEnabled());
|
rgVKontakte.setChecked(defname.contains("vkontakte"));
|
||||||
rgVK.setChecked(isZaboronaEnabled());
|
rgVK.setChecked(defname.contains("standard"));
|
||||||
rgDefault.setChecked(!isZaboronaEnabled());
|
rgDefault.setChecked(defname.contains("vt") || defname.isEmpty());
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(ctx, getAlertStyle());
|
AlertDialog.Builder builder = new AlertDialog.Builder(ctx, getAlertStyle());
|
||||||
builder.setTitle(AndroidUtils.getString("app_name_select_title"));
|
builder.setTitle(AndroidUtils.getString("app_name_select_title"));
|
||||||
builder.setView(rg);
|
builder.setView(rg);
|
||||||
builder.setPositiveButton(AndroidUtils.getString("vtl_confirm"), ((dialog, which) -> {
|
builder.setPositiveButton(AndroidUtils.getString("vtl_confirm"), ((dialog, which) -> {
|
||||||
var defname = preferences.getString("appname", "vt");
|
|
||||||
var deficon = preferences.getString("selectedicon", "vt");
|
|
||||||
|
|
||||||
if (rgDefault.isChecked()) {
|
if (rgDefault.isChecked()) {
|
||||||
edit().putString("appname", "vt").commit();
|
edit().putString("appname", "vt").commit();
|
||||||
edit().putString("selectedicon", appicon).commit();
|
edit().putString("selectedicon", appicon).commit();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package ru.vtosters.lite.ui.fragments;
|
package ru.vtosters.lite.ui.fragments;
|
||||||
|
|
||||||
import static ru.vtosters.lite.music.Scrobbler.isLoggedIn;
|
import static ru.vtosters.lite.music.Scrobbler.isLoggedIn;
|
||||||
|
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
|
||||||
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
|
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
|
import static ru.vtosters.lite.utils.AndroidUtils.dp2px;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
||||||
@@ -68,8 +69,6 @@ public class MediaFragment extends MaterialPreferenceToolbarFragment {
|
|||||||
var prefs = getPreferences();
|
var prefs = getPreferences();
|
||||||
var editor = prefs.edit();
|
var editor = prefs.edit();
|
||||||
var actualPath = FileUriUtils.getFullPathFromTreeUri(path, getContext());
|
var actualPath = FileUriUtils.getFullPathFromTreeUri(path, getContext());
|
||||||
Log.d("MediaFragment", "onActivityResult: " + actualPath);
|
|
||||||
Log.d("MediaFragment", "onActivityResult: " + requestCode);
|
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case REQUEST_CODE_SET_DOWNLOAD_DIRECTORY:
|
case REQUEST_CODE_SET_DOWNLOAD_DIRECTORY:
|
||||||
editor.putString("downloads_directory", actualPath);
|
editor.putString("downloads_directory", actualPath);
|
||||||
@@ -246,7 +245,7 @@ public class MediaFragment extends MaterialPreferenceToolbarFragment {
|
|||||||
Thread thread = new Thread(() -> {
|
Thread thread = new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
var request = new Request.a()
|
var request = new Request.a()
|
||||||
.b("https://api.vk.com/method/" + "video.clearViewingHistoryRecords" + "?https=1" + "&access_token=" + getUserToken() + "&v=5.187")
|
.b("https://" + getApi() + "/method/" + "video.clearViewingHistoryRecords" + "?https=1" + "&access_token=" + getUserToken() + "&v=5.187")
|
||||||
.a(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8"))
|
.a(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8"))
|
||||||
.a();
|
.a();
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,31 @@
|
|||||||
package ru.vtosters.lite.ui.fragments;
|
package ru.vtosters.lite.ui.fragments;
|
||||||
|
|
||||||
|
import static ru.vtosters.lite.proxy.RandomProxy.setupNewProxy;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
|
import static ru.vtosters.lite.utils.AndroidUtils.getIdentifier;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import com.vtosters.lite.general.fragments.MaterialPreferenceToolbarFragment;
|
import com.vtosters.lite.general.fragments.MaterialPreferenceToolbarFragment;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import ru.vtosters.lite.proxy.RandomProxy;
|
||||||
|
import ru.vtosters.lite.utils.AndroidUtils;
|
||||||
|
|
||||||
public class ProxySettingsFragment extends MaterialPreferenceToolbarFragment {
|
public class ProxySettingsFragment extends MaterialPreferenceToolbarFragment {
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle bundle) {
|
public void onCreate(Bundle bundle) {
|
||||||
super.onCreate(bundle);
|
super.onCreate(bundle);
|
||||||
addPreferencesFromResource(getIdentifier("preferences_proxy", "xml"));
|
addPreferencesFromResource(getIdentifier("preferences_proxy", "xml"));
|
||||||
|
findPreference("random_proxy").setOnPreferenceClickListener(preference -> {
|
||||||
|
try {
|
||||||
|
setupNewProxy();
|
||||||
|
} catch (IOException e) {
|
||||||
|
sendToast(AndroidUtils.getString("get_proxy_error"));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public class VKPayFragment extends FragmentImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
VKUIwrapper.setLink("https://vk.com/vkpay");
|
VKUIwrapper.setLink("https://vk.ru/vkpay");
|
||||||
Intent a2 = new Navigator(VKUIwrapper.class).b(getActivity());
|
Intent a2 = new Navigator(VKUIwrapper.class).b(getActivity());
|
||||||
a2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
a2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
startActivity(a2);
|
startActivity(a2);
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ public class VTSettings extends MaterialPreferenceToolbarFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isGmsInstalled()) {
|
if (!isGmsInstalled()) {
|
||||||
addPreference(this, "", AndroidUtils.getString("installgms"), "", "ic_warning_24", preference -> {
|
addPreference(this, "", AndroidUtils.getString("installgms"), "", "ic_about_outline_28", preference -> {
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
Intent a2 = new Navigator(InstallGMSFragment.class).b(context);
|
Intent a2 = new Navigator(InstallGMSFragment.class).b(context);
|
||||||
a2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
a2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
@@ -330,7 +330,7 @@ public class VTSettings extends MaterialPreferenceToolbarFragment {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
addPreference(this, "", AndroidUtils.getString("debug_warning"), AndroidUtils.getString("vkme_mode_info"), "ic_about_outline_28", preference -> false);
|
addPreference(this, "", AndroidUtils.getString("warning"), AndroidUtils.getString("vkme_mode_info"), "ic_about_outline_28", preference -> false);
|
||||||
}
|
}
|
||||||
|
|
||||||
addPreference(this, "", AndroidUtils.getString("vtlmedia"), mediasumm, "ic_media_outline_28", preference -> {
|
addPreference(this, "", AndroidUtils.getString("vtlmedia"), mediasumm, "ic_media_outline_28", preference -> {
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package ru.vtosters.lite.ui.vkui;
|
package ru.vtosters.lite.ui.vkui;
|
||||||
|
|
||||||
import static ru.vtosters.lite.foaf.FoafBase.loadAndShow;
|
import static ru.vtosters.lite.foaf.FoafBase.loadAndShow;
|
||||||
|
import static ru.vtosters.lite.hooks.NewsfeedHook.setWhitelistedAd;
|
||||||
|
import static ru.vtosters.lite.hooks.NewsfeedHook.setWhitelistedFilter;
|
||||||
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserID;
|
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserID;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
|
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
|
||||||
|
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
@@ -24,7 +27,7 @@ import java.util.Objects;
|
|||||||
|
|
||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
import kotlin.jvm.b.Functions;
|
import kotlin.jvm.b.Functions;
|
||||||
import ru.vtosters.lite.utils.AndroidUtils;
|
import ru.vtosters.lite.hooks.NewsfeedHook;
|
||||||
import ru.vtosters.lite.utils.RenameTool;
|
import ru.vtosters.lite.utils.RenameTool;
|
||||||
|
|
||||||
public class MenuBuilder {
|
public class MenuBuilder {
|
||||||
@@ -55,18 +58,17 @@ public class MenuBuilder {
|
|||||||
try {
|
try {
|
||||||
final ExtendedUserProfile eup = (ExtendedUserProfile) pfambObject.get(mb);
|
final ExtendedUserProfile eup = (ExtendedUserProfile) pfambObject.get(mb);
|
||||||
final Context ctx = ((View) Objects.requireNonNull(apView.get(builder))).getContext();
|
final Context ctx = ((View) Objects.requireNonNull(apView.get(builder))).getContext();
|
||||||
|
addItem(builder, getString("menu_copy_id"), () -> {
|
||||||
addItem(builder, AndroidUtils.getString("menu_copy_id"), () -> {
|
|
||||||
copy(ctx, String.valueOf(getUserID(eup)));
|
copy(ctx, String.valueOf(getUserID(eup)));
|
||||||
return Unit.a;
|
return Unit.a;
|
||||||
});
|
});
|
||||||
|
|
||||||
addItem(builder, AndroidUtils.getString("menu_addon_info"), () -> {
|
addItem(builder, getString("menu_addon_info"), () -> {
|
||||||
loadAndShow(ctx, getUserID(eup));
|
loadAndShow(ctx, getUserID(eup));
|
||||||
return Unit.a;
|
return Unit.a;
|
||||||
});
|
});
|
||||||
|
|
||||||
addItem(builder, AndroidUtils.getString("menu_change_name"), () -> {
|
addItem(builder, getString("menu_change_name"), () -> {
|
||||||
RenameTool.createDialog(eup, ctx);
|
RenameTool.createDialog(eup, ctx);
|
||||||
return Unit.a;
|
return Unit.a;
|
||||||
});
|
});
|
||||||
@@ -80,17 +82,31 @@ public class MenuBuilder {
|
|||||||
try {
|
try {
|
||||||
final ExtendedCommunityProfile ecp = (ExtendedCommunityProfile) cfambObject.get(mb);
|
final ExtendedCommunityProfile ecp = (ExtendedCommunityProfile) cfambObject.get(mb);
|
||||||
final Context ctx = ((View) apView.get(builder)).getContext();
|
final Context ctx = ((View) apView.get(builder)).getContext();
|
||||||
|
final boolean isPageWhitelistedFilter = NewsfeedHook.isWhitelistedFilter(ecp);
|
||||||
|
final boolean isPageWhitelistedAds = NewsfeedHook.isWhitelistedAd(ecp);
|
||||||
|
|
||||||
addItem(builder, AndroidUtils.getString("menu_copy_id"), () -> {
|
addItem(builder, getString("menu_copy_id"), () -> {
|
||||||
copy(ctx, String.valueOf(getUserID(ecp)));
|
copy(ctx, String.valueOf(getUserID(ecp)));
|
||||||
return Unit.a;
|
return Unit.a;
|
||||||
});
|
});
|
||||||
|
|
||||||
addItem(builder, AndroidUtils.getString("menu_change_name"), () -> {
|
addItem(builder, getString("menu_change_name"), () -> {
|
||||||
RenameTool.createDialogGroup(ecp, ctx);
|
RenameTool.createDialogGroup(ecp, ctx);
|
||||||
return Unit.a;
|
return Unit.a;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addItem(builder, getString(isPageWhitelistedFilter ? "remove_from_filter_whitelist" : "add_to_filter_whitelist"), () -> {
|
||||||
|
setWhitelistedFilter(ecp, !isPageWhitelistedFilter);
|
||||||
|
sendToast(getString(isPageWhitelistedFilter ? "removed_from_whitelist_success" : "added_to_whitelist_success"));
|
||||||
|
return Unit.a;
|
||||||
|
});
|
||||||
|
|
||||||
|
addItem(builder, getString(isPageWhitelistedAds ? "remove_from_ads_whitelist" : "add_to_ads_whitelist"), () -> {
|
||||||
|
setWhitelistedAd(ecp, !isPageWhitelistedAds);
|
||||||
|
sendToast(getString(isPageWhitelistedAds ? "removed_from_whitelist_success" : "added_to_whitelist_success"));
|
||||||
|
return Unit.a;
|
||||||
|
});
|
||||||
|
|
||||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@@ -101,7 +117,7 @@ public class MenuBuilder {
|
|||||||
ClipData clip = ClipData.newPlainText("MBH-ST", txt);
|
ClipData clip = ClipData.newPlainText("MBH-ST", txt);
|
||||||
clipboard.setPrimaryClip(clip);
|
clipboard.setPrimaryClip(clip);
|
||||||
|
|
||||||
sendToast(AndroidUtils.getString("menu_copied"));
|
sendToast(getString("menu_copied"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addItem(final ActionsPopup.b builder, final String title, final Functions onClick) throws InvocationTargetException, IllegalAccessException {
|
public static void addItem(final ActionsPopup.b builder, final String title, final Functions onClick) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package ru.vtosters.lite.ui.wallpapers;
|
|||||||
|
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
|
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getResources;
|
import static ru.vtosters.lite.utils.AndroidUtils.getResources;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
@@ -130,19 +131,27 @@ public class ImageFilters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void darken(Bitmap bm) {
|
private static void darken(Bitmap bm) {
|
||||||
Canvas canvas = new Canvas(bm);
|
try {
|
||||||
Paint p = new Paint(Color.RED);
|
Canvas canvas = new Canvas(bm);
|
||||||
ColorFilter filter = new LightingColorFilter(0xFF7F7F7F, 0x00000000); // darken
|
Paint p = new Paint(Color.RED);
|
||||||
p.setColorFilter(filter);
|
ColorFilter filter = new LightingColorFilter(0xFF7F7F7F, 0x00000000); // darken
|
||||||
canvas.drawBitmap(bm, new Matrix(), p);
|
p.setColorFilter(filter);
|
||||||
|
canvas.drawBitmap(bm, new Matrix(), p);
|
||||||
|
} catch (Exception e) {
|
||||||
|
sendToast("Ошибка при работе затемнения обоев");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void lighten(Bitmap bm) {
|
private static void lighten(Bitmap bm) {
|
||||||
Canvas canvas = new Canvas(bm);
|
try {
|
||||||
Paint p = new Paint(Color.RED);
|
Canvas canvas = new Canvas(bm);
|
||||||
ColorFilter filter = new LightingColorFilter(0xFFFFFFFF, 0x00222222); // lighten
|
Paint p = new Paint(Color.RED);
|
||||||
p.setColorFilter(filter);
|
ColorFilter filter = new LightingColorFilter(0xFFFFFFFF, 0x00222222); // lighten
|
||||||
canvas.drawBitmap(bm, new Matrix(), p);
|
p.setColorFilter(filter);
|
||||||
|
canvas.drawBitmap(bm, new Matrix(), p);
|
||||||
|
} catch (Exception e) {
|
||||||
|
sendToast("Ошибка при работе осветления обоев");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bitmap applyInvertEffect(Bitmap src) {
|
public static Bitmap applyInvertEffect(Bitmap src) {
|
||||||
|
|||||||
@@ -158,6 +158,14 @@ public class WallpaperMenuFragment extends MaterialPreferenceToolbarFragment {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PreferencesUtil.addMaterialSwitchPreference(this, "compresswp", "Сжимать обои", "Значительно ускоряет открытие чатов", null, true, (preference, o) -> {
|
||||||
|
boolean value = (boolean) o;
|
||||||
|
edit().putBoolean("compresswp", value).commit();
|
||||||
|
requestUpdateWallpaper();
|
||||||
|
mWPPreviewPref.redraw();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
ListPreference blur = (ListPreference) findPreference("msg_blur_radius");
|
ListPreference blur = (ListPreference) findPreference("msg_blur_radius");
|
||||||
ListPreference dim = (ListPreference) findPreference("msg_dim");
|
ListPreference dim = (ListPreference) findPreference("msg_dim");
|
||||||
ListPreference mosaic = (ListPreference) findPreference("msg_mosaic");
|
ListPreference mosaic = (ListPreference) findPreference("msg_mosaic");
|
||||||
|
|||||||
@@ -8,15 +8,25 @@ import static ru.vtosters.lite.ui.wallpapers.ImageFilters.getMonochrome;
|
|||||||
import static ru.vtosters.lite.ui.wallpapers.ImageFilters.getMosaic;
|
import static ru.vtosters.lite.ui.wallpapers.ImageFilters.getMosaic;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
|
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
|
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
|
||||||
|
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
|
||||||
|
import static ru.vtosters.lite.utils.Preferences.getBoolValue;
|
||||||
import static ru.vtosters.lite.utils.Preferences.hasVerification;
|
import static ru.vtosters.lite.utils.Preferences.hasVerification;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
import ru.vtosters.lite.utils.AndroidUtils;
|
import ru.vtosters.lite.utils.AndroidUtils;
|
||||||
|
import ru.vtosters.lite.utils.ThemesUtils;
|
||||||
|
|
||||||
public class WallpapersHooks {
|
public class WallpapersHooks {
|
||||||
private static File mWallpaperFile;
|
private static File mWallpaperFile;
|
||||||
@@ -28,18 +38,69 @@ public class WallpapersHooks {
|
|||||||
return mWallpaperFile == null ? mWallpaperFile = new File(getGlobalContext().getFilesDir(), "wallpaper.png") : mWallpaperFile;
|
return mWallpaperFile == null ? mWallpaperFile = new File(getGlobalContext().getFilesDir(), "wallpaper.png") : mWallpaperFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Boolean eligibleWallpaperFile(File file) {
|
||||||
|
if (file.length() >= 6291456) {
|
||||||
|
sendToast("Размер файла превышает лимит 6 MB");
|
||||||
|
removeWallpaper();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File compress(File file){
|
||||||
|
try {
|
||||||
|
BitmapFactory.Options o = new BitmapFactory.Options();
|
||||||
|
o.inJustDecodeBounds = true;
|
||||||
|
o.inSampleSize = 6;
|
||||||
|
|
||||||
|
FileInputStream inputStream = new FileInputStream(file);
|
||||||
|
BitmapFactory.decodeStream(inputStream, null, o);
|
||||||
|
inputStream.close();
|
||||||
|
|
||||||
|
final int REQUIRED_SIZE=200;
|
||||||
|
|
||||||
|
int scale = 1;
|
||||||
|
while(o.outWidth / scale / 2 >= REQUIRED_SIZE && o.outHeight / scale / 2 >= REQUIRED_SIZE) {
|
||||||
|
scale *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
BitmapFactory.Options o2 = new BitmapFactory.Options();
|
||||||
|
o2.inSampleSize = scale;
|
||||||
|
inputStream = new FileInputStream(file);
|
||||||
|
|
||||||
|
Bitmap selectedBitmap = BitmapFactory.decodeStream(inputStream, null, o2);
|
||||||
|
inputStream.close();
|
||||||
|
|
||||||
|
File outPutFile = File.createTempFile("wallpaper_temp","image");
|
||||||
|
FileOutputStream outputStream = new FileOutputStream(outPutFile);
|
||||||
|
selectedBitmap.compress(Bitmap.CompressFormat.PNG, 85 , outputStream);
|
||||||
|
|
||||||
|
return outPutFile;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.d("Wallpapers", e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void setBg(View view) {
|
public static void setBg(View view) {
|
||||||
if (getWallpaper() != null) {
|
if (getWallpaper() != null) {
|
||||||
((ImageView) view).setImageDrawable(getWallpaper()); // set picture to background
|
((ImageView) view).setImageDrawable(getWallpaper()); // set picture to background
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
((ImageView) view).setColorFilter(im_bg_chat); // set default bg color
|
view.setBackgroundColor(ThemesUtils.getColorFromAttr(im_bg_chat)); // set default bg color
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getWallpaperUrl() {
|
public static String getWallpaperUrl() {
|
||||||
if (getWallpaperFile().exists())
|
if (getWallpaperFile().exists() && eligibleWallpaperFile(getWallpaperFile()))
|
||||||
return getWallpaperFile().getAbsolutePath();
|
if (compress(getWallpaperFile()) == null) {
|
||||||
|
return "default";
|
||||||
|
} else if (getBoolValue("compresswp", true)){
|
||||||
|
return compress(getWallpaperFile()).getAbsolutePath();
|
||||||
|
} else {
|
||||||
|
return getWallpaperFile().getAbsolutePath();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return "default";
|
return "default";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import b.h.g.m.FileUtils;
|
|||||||
public class CacheUtils {
|
public class CacheUtils {
|
||||||
private static CacheUtils sInstance = new CacheUtils();
|
private static CacheUtils sInstance = new CacheUtils();
|
||||||
public long size = 0;
|
public long size = 0;
|
||||||
|
public static boolean needToDelete = false;
|
||||||
|
|
||||||
public static CacheUtils getInstance() {
|
public static CacheUtils getInstance() {
|
||||||
if (sInstance == null)
|
if (sInstance == null)
|
||||||
@@ -55,7 +56,7 @@ public class CacheUtils {
|
|||||||
public void autoCleaningCache() {
|
public void autoCleaningCache() {
|
||||||
size = IOUtils.getDirSize(getGlobalContext().getCacheDir());
|
size = IOUtils.getDirSize(getGlobalContext().getCacheDir());
|
||||||
|
|
||||||
if (size >= getSizeForDelete()) {
|
if (size >= getSizeForDelete() && needToDelete) {
|
||||||
if (dev()) sendToast(AndroidUtils.getString("cache_cleaned"));
|
if (dev()) sendToast(AndroidUtils.getString("cache_cleaned"));
|
||||||
VKImageLoader.e();
|
VKImageLoader.e();
|
||||||
ImAudioMsgPlayerProvider.b().e(PlayerActionSources.a);
|
ImAudioMsgPlayerProvider.b().e(PlayerActionSources.a);
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ import static ru.vtosters.lite.utils.AndroidUtils.edit;
|
|||||||
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
|
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
|
import static ru.vtosters.lite.utils.AndroidUtils.getPreferences;
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
|
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
|
||||||
|
import static ru.vtosters.lite.utils.CacheUtils.*;
|
||||||
import static ru.vtosters.lite.utils.CacheUtils.getInstance;
|
import static ru.vtosters.lite.utils.CacheUtils.getInstance;
|
||||||
import static ru.vtosters.lite.utils.DeletedMessagesHandler.reloadMessagesList;
|
import static ru.vtosters.lite.utils.DeletedMessagesHandler.reloadMessagesList;
|
||||||
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.setupFilters;
|
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.setupFilters;
|
||||||
import static ru.vtosters.lite.utils.ProxyUtils.setProxy;
|
import static ru.vtosters.lite.proxy.ProxyUtils.setProxy;
|
||||||
import static ru.vtosters.lite.utils.SignatureChecker.validateAppSignature;
|
import static ru.vtosters.lite.utils.SignatureChecker.validateAppSignature;
|
||||||
import static ru.vtosters.lite.utils.ThemesUtils.isDarkTheme;
|
import static ru.vtosters.lite.utils.ThemesUtils.isDarkTheme;
|
||||||
import static ru.vtosters.lite.utils.VTVerifications.isPrometheus;
|
import static ru.vtosters.lite.utils.VTVerifications.isPrometheus;
|
||||||
@@ -152,10 +153,6 @@ public class Preferences {
|
|||||||
return getBoolValue("calls", false);
|
return getBoolValue("calls", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean globalUsersOnline() {
|
|
||||||
return getBoolValue("globalUsersOnline", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean dev() {
|
public static boolean dev() {
|
||||||
return getBoolValue("dev", false);
|
return getBoolValue("dev", false);
|
||||||
}
|
}
|
||||||
@@ -366,16 +363,22 @@ public class Preferences {
|
|||||||
public static long getSizeForDelete() {
|
public static long getSizeForDelete() {
|
||||||
switch (getPrefsValue("clearcache")) {
|
switch (getPrefsValue("clearcache")) {
|
||||||
case "100mb":
|
case "100mb":
|
||||||
|
needToDelete = true;
|
||||||
return 104857600L;
|
return 104857600L;
|
||||||
case "500mb":
|
case "500mb":
|
||||||
|
needToDelete = true;
|
||||||
return 524288000L;
|
return 524288000L;
|
||||||
case "1gb":
|
case "1gb":
|
||||||
|
needToDelete = true;
|
||||||
return 1073741824L;
|
return 1073741824L;
|
||||||
case "2gb":
|
case "2gb":
|
||||||
|
needToDelete = true;
|
||||||
return 2147483648L;
|
return 2147483648L;
|
||||||
case "5gb":
|
case "5gb":
|
||||||
|
needToDelete = true;
|
||||||
return 5368709120L;
|
return 5368709120L;
|
||||||
default:
|
default:
|
||||||
|
needToDelete = false;
|
||||||
return MAX_VALUE;
|
return MAX_VALUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,170 +0,0 @@
|
|||||||
package ru.vtosters.lite.utils;
|
|
||||||
|
|
||||||
import static java.lang.System.clearProperty;
|
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
|
|
||||||
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.util.ArrayMap;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
public class ProxyUtils {
|
|
||||||
public static String getApi() {
|
|
||||||
var proxyapi = getPrefsValue("proxyapi");
|
|
||||||
|
|
||||||
if (apiproxy() & !proxyapi.isEmpty()) {
|
|
||||||
return proxyapi;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "api.vk.com";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean isZaboronaEnabled() {
|
|
||||||
return getPrefsValue("proxy").equals("zaborona");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setProxyRefl() {
|
|
||||||
Log.d("Proxy", "Setting proxy...");
|
|
||||||
try {
|
|
||||||
var context = getGlobalContext().getApplicationContext();
|
|
||||||
Class<?> applicationClass = Class.forName("android.app.Application");
|
|
||||||
@SuppressLint("DiscouragedPrivateApi") @SuppressWarnings("JavaReflectionMemberAccess")
|
|
||||||
Field mLoadedApkField = applicationClass.getDeclaredField("mLoadedApk");
|
|
||||||
mLoadedApkField.setAccessible(true);
|
|
||||||
Object mLoadedApkObject = mLoadedApkField.get(context);
|
|
||||||
|
|
||||||
@SuppressLint("PrivateApi")
|
|
||||||
Class<?> loadedApkClass = Class.forName("android.app.LoadedApk");
|
|
||||||
@SuppressLint("DiscouragedPrivateApi") Field mReceiversField = loadedApkClass.getDeclaredField("mReceivers");
|
|
||||||
mReceiversField.setAccessible(true);
|
|
||||||
ArrayMap<?, ?> receivers = (ArrayMap<?, ?>) mReceiversField.get(mLoadedApkObject);
|
|
||||||
for (Object receiverMap : receivers.values()) {
|
|
||||||
for (Object receiver : ((ArrayMap<?, ?>) receiverMap).keySet()) {
|
|
||||||
Class<?> receiverClass = receiver.getClass();
|
|
||||||
|
|
||||||
if (receiverClass.getName().contains("ProxyChangeListener")) {
|
|
||||||
Method onReceiveMethod = receiverClass.getDeclaredMethod("onReceive", Context.class, Intent.class);
|
|
||||||
Intent intent = new Intent(android.net.Proxy.PROXY_CHANGE_ACTION);
|
|
||||||
onReceiveMethod.invoke(receiver, context, intent);
|
|
||||||
} else {
|
|
||||||
for (Field field : receiverClass.getDeclaredFields()) {
|
|
||||||
if (field.getType().getName().contains("ProxyChangeListener")) {
|
|
||||||
Method onReceiveMethod = receiverClass.getDeclaredMethod("onReceive", Context.class, Intent.class);
|
|
||||||
Intent intent = new Intent(android.net.Proxy.PROXY_CHANGE_ACTION);
|
|
||||||
onReceiveMethod.invoke(receiver, context, intent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d("Proxy", "Setting proxy successful!");
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.d("Proxy", "Setting proxy failed!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setProxy() {
|
|
||||||
switch (getPrefsValue("proxy")) {
|
|
||||||
case "zaborona":
|
|
||||||
System.setProperty("socksProxyHost", "socks.zaboronahelp.pp.ua");
|
|
||||||
System.setProperty("socksProxyPort", "1488");
|
|
||||||
setProxyRefl();
|
|
||||||
break;
|
|
||||||
case "socks":
|
|
||||||
System.setProperty("socksProxyHost", proxyHostSocks());
|
|
||||||
System.setProperty("socksProxyPort", proxyPortSocks());
|
|
||||||
setProxyRefl();
|
|
||||||
break;
|
|
||||||
case "http":
|
|
||||||
System.setProperty("http.proxyHost", proxyHostHTTP());
|
|
||||||
System.setProperty("http.proxyPort", proxyPortHTTP());
|
|
||||||
System.setProperty("http.proxyUser", proxyUserHTTP());
|
|
||||||
System.setProperty("http.proxyPassword", proxyPassHTTP());
|
|
||||||
setProxyRefl();
|
|
||||||
break;
|
|
||||||
case "https":
|
|
||||||
System.setProperty("https.proxyHost", proxyHostHTTPS());
|
|
||||||
System.setProperty("https.proxyPort", proxyPortHTTPS());
|
|
||||||
System.setProperty("https.proxyUser", proxyUserHTTPS());
|
|
||||||
System.setProperty("https.proxyPassword", proxyPassHTTPS());
|
|
||||||
setProxyRefl();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
resetProxy();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void resetProxy() {
|
|
||||||
clearProperty("https.proxyHost");
|
|
||||||
clearProperty("https.proxyPort");
|
|
||||||
clearProperty("https.proxyUser");
|
|
||||||
clearProperty("https.proxyPassword");
|
|
||||||
clearProperty("http.proxyHost");
|
|
||||||
clearProperty("http.proxyPort");
|
|
||||||
clearProperty("http.proxyUser");
|
|
||||||
clearProperty("http.proxyPassword");
|
|
||||||
clearProperty("socksProxyHost");
|
|
||||||
clearProperty("socksPortHost");
|
|
||||||
} // Reset all proxies
|
|
||||||
|
|
||||||
private static String proxyHostHTTP() {
|
|
||||||
var string = getPrefsValue("proxyHostHTTP");
|
|
||||||
return string.isEmpty() ? "192.168.0.1" : string;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String proxyHostHTTPS() {
|
|
||||||
var string = getPrefsValue("proxyHostHTTPS");
|
|
||||||
return string.isEmpty() ? "192.168.0.1" : string;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String proxyHostSocks() {
|
|
||||||
var string = getPrefsValue("proxyHostSocks");
|
|
||||||
return string.isEmpty() ? "192.168.0.1" : string;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String proxyPortHTTP() {
|
|
||||||
var string = getPrefsValue("proxyPortHTTP");
|
|
||||||
return string.isEmpty() ? "8888" : string;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String proxyPortHTTPS() {
|
|
||||||
var string = getPrefsValue("proxyPortHTTPS");
|
|
||||||
return string.isEmpty() ? "8888" : string;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String proxyPortSocks() {
|
|
||||||
var string = getPrefsValue("proxyPortSocks");
|
|
||||||
return string.isEmpty() ? "8888" : string;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String proxyUserHTTP() {
|
|
||||||
var string = getPrefsValue("proxyUserHTTP");
|
|
||||||
return string.isEmpty() ? "" : string;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String proxyUserHTTPS() {
|
|
||||||
var string = getPrefsValue("proxyUserHTTPS");
|
|
||||||
return string.isEmpty() ? "" : string;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String proxyPassHTTP() {
|
|
||||||
var string = getPrefsValue("proxyPassHTTP");
|
|
||||||
return string.isEmpty() ? "" : string;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String proxyPassHTTPS() {
|
|
||||||
String string = getPrefsValue("proxyPassHTTPS");
|
|
||||||
return string.isEmpty() ? "" : string;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean apiproxy() {
|
|
||||||
return getPrefsValue("proxy").equals("apiproxy");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,7 @@ import static ru.vtosters.lite.utils.About.getBuildNumber;
|
|||||||
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
|
import static ru.vtosters.lite.utils.AndroidUtils.getPrefsValue;
|
||||||
import static ru.vtosters.lite.utils.Preferences.dev;
|
import static ru.vtosters.lite.utils.Preferences.dev;
|
||||||
import static ru.vtosters.lite.utils.Preferences.vksans;
|
import static ru.vtosters.lite.utils.Preferences.vksans;
|
||||||
import static ru.vtosters.lite.utils.ProxyUtils.apiproxy;
|
import static ru.vtosters.lite.proxy.ProxyUtils.isApiProxyEnabled;
|
||||||
import static ru.vtosters.lite.utils.ThemesUtils.isDarkTheme;
|
import static ru.vtosters.lite.utils.ThemesUtils.isDarkTheme;
|
||||||
|
|
||||||
public class SSFSUtils {
|
public class SSFSUtils {
|
||||||
@@ -39,7 +39,7 @@ public class SSFSUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String getUserProxy() {
|
public static String getUserProxy() {
|
||||||
return apiproxy() ? "1" : "0";
|
return isApiProxyEnabled() ? "1" : "0";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String isVKSansEnabled() {
|
public static String isVKSansEnabled() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#Fri Apr 22 13:33:27 MSK 2022
|
#Tue Aug 16 21:49:57 MSK 2022
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
@@ -960,6 +960,17 @@
|
|||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
|
<data
|
||||||
|
android:host="vk.ru"
|
||||||
|
android:pathPattern="/.*"
|
||||||
|
android:scheme="http" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
<data
|
<data
|
||||||
android:host="vk.com"
|
android:host="vk.com"
|
||||||
android:pathPattern="/.*"
|
android:pathPattern="/.*"
|
||||||
@@ -971,28 +982,6 @@
|
|||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
<data
|
|
||||||
android:host="vkontakte.ru"
|
|
||||||
android:pathPattern="/.*"
|
|
||||||
android:scheme="http" />
|
|
||||||
</intent-filter>
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.VIEW" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
|
||||||
|
|
||||||
<data
|
|
||||||
android:host="new.vk.com"
|
|
||||||
android:pathPattern="/.*"
|
|
||||||
android:scheme="http" />
|
|
||||||
</intent-filter>
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.VIEW" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
|
||||||
|
|
||||||
<data
|
<data
|
||||||
android:host="vk.com"
|
android:host="vk.com"
|
||||||
android:pathPattern="/.*"
|
android:pathPattern="/.*"
|
||||||
@@ -1007,6 +996,28 @@
|
|||||||
<data
|
<data
|
||||||
android:host="vkontakte.ru"
|
android:host="vkontakte.ru"
|
||||||
android:pathPattern="/.*"
|
android:pathPattern="/.*"
|
||||||
|
android:scheme="http" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
|
<data
|
||||||
|
android:host="new.vk.ru"
|
||||||
|
android:pathPattern="/.*"
|
||||||
|
android:scheme="http" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
|
<data
|
||||||
|
android:host="vk.ru"
|
||||||
|
android:pathPattern="/.*"
|
||||||
android:scheme="https" />
|
android:scheme="https" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@@ -1016,7 +1027,18 @@
|
|||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
<data
|
<data
|
||||||
android:host="new.vk.com"
|
android:host="vkontakte.ru"
|
||||||
|
android:pathPattern="/.*"
|
||||||
|
android:scheme="https" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
|
<data
|
||||||
|
android:host="new.vk.ru"
|
||||||
android:pathPattern="/.*"
|
android:pathPattern="/.*"
|
||||||
android:scheme="https" />
|
android:scheme="https" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
@@ -1107,6 +1129,30 @@
|
|||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
|
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||||
|
<data
|
||||||
|
android:host="m.vk.ru"
|
||||||
|
android:pathPattern="/.*"
|
||||||
|
android:scheme="http" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
|
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||||
|
<data
|
||||||
|
android:host="m.vk.ru"
|
||||||
|
android:pathPattern="/.*"
|
||||||
|
android:scheme="https" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||||
<data
|
<data
|
||||||
android:host="m.vk.com"
|
android:host="m.vk.com"
|
||||||
@@ -1132,7 +1178,7 @@
|
|||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
<data
|
<data
|
||||||
android:host="m.vk.com"
|
android:host="m.vk.ru"
|
||||||
android:pathPattern="/restore"
|
android:pathPattern="/restore"
|
||||||
android:scheme="http" />
|
android:scheme="http" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
@@ -1143,7 +1189,7 @@
|
|||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
<data
|
<data
|
||||||
android:host="m.vk.com"
|
android:host="m.vk.ru"
|
||||||
android:pathPattern="/restore"
|
android:pathPattern="/restore"
|
||||||
android:scheme="https" />
|
android:scheme="https" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
appscent
|
appscent
|
||||||
//t.me/
|
//t.me/
|
||||||
vk.com
|
vk.com
|
||||||
|
vk.ru
|
||||||
apps-cent
|
apps-cent
|
||||||
app-cent
|
app-cent
|
||||||
appcent
|
appcent
|
||||||
|
|||||||
@@ -394,12 +394,12 @@ function showPhotosBox(url, id, num, link){
|
|||||||
<div class="wk_text" style="max-width: 604px">
|
<div class="wk_text" style="max-width: 604px">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div style="float: left;">
|
<div style="float: left;">
|
||||||
<a href="https://vk.com/club{GROUP_ID}">
|
<a href="https://vk.ru/club{GROUP_ID}">
|
||||||
<img src="{GROUP_PHOTO}" width="50" height="50" border="0"/>
|
<img src="{GROUP_PHOTO}" width="50" height="50" border="0"/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="headGroupName">
|
<div class="headGroupName">
|
||||||
<a href="https://vk.com/club{GROUP_ID}">{GROUP_NAME}</a>
|
<a href="https://vk.ru/club{GROUP_ID}">{GROUP_NAME}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="headOrigLink">
|
<div class="headOrigLink">
|
||||||
{L_PREVIEW} <a href="http://{ORIG_URL}">{ORIG_URL}</a>
|
{L_PREVIEW} <a href="http://{ORIG_URL}">{ORIG_URL}</a>
|
||||||
@@ -412,7 +412,7 @@ function showPhotosBox(url, id, num, link){
|
|||||||
<div class="footer">
|
<div class="footer">
|
||||||
{L_SOURCE} <a href="http://{ORIG_URL}">{ORIG_URL}</a><br/>
|
{L_SOURCE} <a href="http://{ORIG_URL}">{ORIG_URL}</a><br/>
|
||||||
{DATE} - {VIEWS}<br/>
|
{DATE} - {VIEWS}<br/>
|
||||||
<a href="https://vk.com/id{PROFILE_ID}">{L_GO_TO_GROUP}</a>
|
<a href="https://vk.ru/id{PROFILE_ID}">{L_GO_TO_GROUP}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 822 B |
|
After Width: | Height: | Size: 800 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 575 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 142 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 205 KiB |
|
After Width: | Height: | Size: 7.1 KiB |