mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2025-10-02 03:20:51 +02:00
Compare commits
634 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4df4f68fe1 | ||
![]() |
7db8d37137 | ||
![]() |
b7503a7d81 | ||
![]() |
9f5d4034e3 | ||
![]() |
3c941f6c4b | ||
![]() |
ec8fff421a | ||
![]() |
a47a0b5432 | ||
![]() |
96ba46f21d | ||
![]() |
90f48d5817 | ||
![]() |
7288dd097a | ||
![]() |
0119d62a35 | ||
![]() |
4d6ab73fa9 | ||
![]() |
f58c95840a | ||
![]() |
ecf24f81ec | ||
![]() |
dd3306a940 | ||
![]() |
bbb2b98f27 | ||
![]() |
bc7332780d | ||
![]() |
6f3bc3ac8f | ||
![]() |
cd04d869b7 | ||
![]() |
909e15cbdd | ||
![]() |
33fa30ab78 | ||
![]() |
44933ac17a | ||
![]() |
bb2af96deb | ||
![]() |
1fe6da14ea | ||
![]() |
b7b9653c21 | ||
![]() |
8adc5918f8 | ||
![]() |
0db593b1bb | ||
![]() |
a0c9dbeb78 | ||
![]() |
61d5546d89 | ||
![]() |
f97b7c943b | ||
![]() |
97549b633b | ||
![]() |
1949e4a9d4 | ||
![]() |
ecb5f7a5ba | ||
![]() |
6021f72cf0 | ||
![]() |
c00ef74f96 | ||
![]() |
962e070150 | ||
![]() |
221cbf5e07 | ||
![]() |
a72d37ab69 | ||
![]() |
f92227e5df | ||
![]() |
c50617452f | ||
![]() |
3957eca94d | ||
![]() |
70111cf614 | ||
![]() |
f9e03c9a40 | ||
![]() |
88fbdf1cc4 | ||
![]() |
7b76bd79e8 | ||
![]() |
f4b58e649d | ||
![]() |
91ff301d53 | ||
![]() |
f5e1c99259 | ||
![]() |
abdcd3cc30 | ||
![]() |
23615a39ac | ||
![]() |
5fa5fc39fc | ||
![]() |
01b3c7e91b | ||
![]() |
e4e364af3f | ||
![]() |
f2358692af | ||
![]() |
26ed6299e3 | ||
![]() |
3a85187111 | ||
![]() |
4261a2eed3 | ||
![]() |
fef17163a9 | ||
![]() |
9dd447a14f | ||
![]() |
ecf4407ba4 | ||
![]() |
039c0d3ee6 | ||
![]() |
5808aead55 | ||
![]() |
e797e2e7f1 | ||
![]() |
23cacbfe65 | ||
![]() |
4f94ee9b72 | ||
![]() |
0d1a26298a | ||
![]() |
8ccd0b23e9 | ||
![]() |
9d8b991354 | ||
![]() |
d273f69852 | ||
![]() |
eee3ccafc3 | ||
![]() |
3686e90e81 | ||
![]() |
1a5d9da2bf | ||
![]() |
21a7a73f6d | ||
![]() |
5090b41eef | ||
![]() |
0e55aa6249 | ||
![]() |
dd2dcf4df2 | ||
![]() |
2e84b28998 | ||
![]() |
e6cbfea5a7 | ||
![]() |
641d662944 | ||
![]() |
09208e183b | ||
![]() |
fba3ece688 | ||
![]() |
f7d849a3cc | ||
![]() |
709c700cc6 | ||
![]() |
2da411c1ec | ||
![]() |
d6e4f3c809 | ||
![]() |
1bb08db8ba | ||
![]() |
2ba116b1e6 | ||
![]() |
7088de0fb9 | ||
![]() |
7084f73d6c | ||
![]() |
69374e25fe | ||
![]() |
5e16969d61 | ||
![]() |
0fe5a44e5a | ||
![]() |
98e617001d | ||
![]() |
979bd09b29 | ||
![]() |
77678b8f31 | ||
![]() |
3575cac9d7 | ||
![]() |
8cdeaf1b27 | ||
![]() |
08a8c6c414 | ||
![]() |
fa5c1b22ae | ||
![]() |
a99e7f3288 | ||
![]() |
a29506ed2f | ||
![]() |
1434b40d03 | ||
![]() |
6d6609187b | ||
![]() |
9682eaae2a | ||
![]() |
1cdb4ccc17 | ||
![]() |
2a878dffbc | ||
![]() |
49f4fb7ed7 | ||
![]() |
caa985660a | ||
![]() |
3842a1e4fb | ||
![]() |
e06d83cb93 | ||
![]() |
67df894448 | ||
![]() |
d1ec6cf21b | ||
![]() |
537c561cee | ||
![]() |
a65ddc5b36 | ||
![]() |
1fb1b3a784 | ||
![]() |
b80879765c | ||
![]() |
10919fe15b | ||
![]() |
9e5fe1edca | ||
![]() |
03ee3f3d2a | ||
![]() |
4113283069 | ||
![]() |
56c5f696df | ||
![]() |
9beb76e641 | ||
![]() |
f71403be58 | ||
![]() |
d0e5d36b1b | ||
![]() |
fdeb7543ca | ||
![]() |
90716f4f5b | ||
![]() |
54d41bc288 | ||
![]() |
d63c7a9042 | ||
![]() |
cd5b60cbed | ||
![]() |
6d60e6698a | ||
![]() |
d53cb01396 | ||
![]() |
8baaecab1b | ||
![]() |
1368f9f89e | ||
![]() |
ce36f3ae3b | ||
![]() |
cf147aa161 | ||
![]() |
7700cff5e5 | ||
![]() |
b883f313ba | ||
![]() |
b1ee22cde6 | ||
![]() |
b32f149a1b | ||
![]() |
1d136c6c35 | ||
![]() |
b8a17580c5 | ||
![]() |
87febf8679 | ||
![]() |
38b2ffd450 | ||
![]() |
01e031e7e7 | ||
![]() |
0b1eda3050 | ||
![]() |
52cdf96dfe | ||
![]() |
1f5eba59c5 | ||
![]() |
372c2f2be0 | ||
![]() |
25e0b46396 | ||
![]() |
d3332583b6 | ||
![]() |
cb5cf9bb09 | ||
![]() |
6cb2c2a84e | ||
![]() |
633137fd79 | ||
![]() |
9627fdf33f | ||
![]() |
b39366c80a | ||
![]() |
ac01c49666 | ||
![]() |
80d16ea407 | ||
![]() |
4f44f26333 | ||
![]() |
a21bdb1487 | ||
![]() |
4d6a2f40d3 | ||
![]() |
e6773aac0e | ||
![]() |
997381d0c3 | ||
![]() |
ac53eeb76d | ||
![]() |
a09c8934fc | ||
![]() |
b4120c39e6 | ||
![]() |
5d6320d925 | ||
![]() |
985bf50f7f | ||
![]() |
84d21af644 | ||
![]() |
267cd99b04 | ||
![]() |
401960079c | ||
![]() |
1fbc8a2850 | ||
![]() |
16fe5a94ac | ||
![]() |
1c20a4d9eb | ||
![]() |
3a9f30d954 | ||
![]() |
856aacf8ce | ||
![]() |
441b510775 | ||
![]() |
88a10b5af1 | ||
![]() |
65205ace95 | ||
![]() |
1a4ef06ee9 | ||
![]() |
64ac631040 | ||
![]() |
4e4cabb929 | ||
![]() |
b242c86869 | ||
![]() |
d37fee346a | ||
![]() |
cc52d3b0af | ||
![]() |
d5b1bae305 | ||
![]() |
04e22faf85 | ||
![]() |
48cb3ed138 | ||
![]() |
ebdeee8b3c | ||
![]() |
6449d7d4ee | ||
![]() |
4b775d15a2 | ||
![]() |
e4d6a453b0 | ||
![]() |
9dcbcd57cb | ||
![]() |
17aa44c88b | ||
![]() |
60dc266e13 | ||
![]() |
60ed308caa | ||
![]() |
c485e7e167 | ||
![]() |
71a8361580 | ||
![]() |
666dce1b6f | ||
![]() |
7bed1c2295 | ||
![]() |
51325089f0 | ||
![]() |
90666a84ac | ||
![]() |
0c37bd3a64 | ||
![]() |
753517fb56 | ||
![]() |
b939daac2a | ||
![]() |
8f2b7b2783 | ||
![]() |
883d4b4065 | ||
![]() |
ff38ae202b | ||
![]() |
7b71302a63 | ||
![]() |
cbf8fc5bb9 | ||
![]() |
00797a7834 | ||
![]() |
de092e5357 | ||
![]() |
bba8739008 | ||
![]() |
3c5564b274 | ||
![]() |
f3ff24cfbf | ||
![]() |
975b519585 | ||
![]() |
7f1f34f812 | ||
![]() |
d5bab1006e | ||
![]() |
b52e48a355 | ||
![]() |
68a807a446 | ||
![]() |
0dc6b66825 | ||
![]() |
a9db7616aa | ||
![]() |
b71e2833d6 | ||
![]() |
56bc919866 | ||
![]() |
ac3d8cddbe | ||
![]() |
aa10b392ae | ||
![]() |
e8ea1c92b1 | ||
![]() |
b5d7b80fe9 | ||
![]() |
2a328e28da | ||
![]() |
3d1cc348c8 | ||
![]() |
3d5c173d61 | ||
![]() |
9a5da5199d | ||
![]() |
764a171a25 | ||
![]() |
25061ab07c | ||
![]() |
6074925102 | ||
![]() |
f8c0c449bf | ||
![]() |
26d18c588e | ||
![]() |
6f18dd26a2 | ||
![]() |
7340bc05b4 | ||
![]() |
b0948cf9fc | ||
![]() |
86c16fa5d8 | ||
![]() |
68695bbf92 | ||
![]() |
b4fdbdeb1b | ||
![]() |
1fb3774e03 | ||
![]() |
f284a799ef | ||
![]() |
c6e759a94c | ||
![]() |
052c9a9869 | ||
![]() |
0806344ffb | ||
![]() |
d0e626c6ee | ||
![]() |
9068247856 | ||
![]() |
4553850412 | ||
![]() |
21d42c92e5 | ||
![]() |
eb9770e3ba | ||
![]() |
d54a6e0b0e | ||
![]() |
a8f5cfa640 | ||
![]() |
0d3e0c201e | ||
![]() |
cc4e4a4f91 | ||
![]() |
b597774bb9 | ||
![]() |
87fca5cffe | ||
![]() |
9685456ee4 | ||
![]() |
6a9e3ef639 | ||
![]() |
b5a9f042cc | ||
![]() |
770dcc1832 | ||
![]() |
94f7baf299 | ||
![]() |
77979eddde | ||
![]() |
f1e52b8b92 | ||
![]() |
2e414cfd63 | ||
![]() |
f5b5982e1c | ||
![]() |
eebd83d6ac | ||
![]() |
a9aee21e58 | ||
![]() |
bd9ee18e56 | ||
![]() |
c75c2d0f21 | ||
![]() |
80f3e3c3b6 | ||
![]() |
86a1fcf009 | ||
![]() |
c235c647a0 | ||
![]() |
09d8ae1316 | ||
![]() |
cb7e94449c | ||
![]() |
e742091a37 | ||
![]() |
8e3be3826f | ||
![]() |
9bc95f030c | ||
![]() |
9576d5bd89 | ||
![]() |
a0ba3ce2e4 | ||
![]() |
6b816a11f7 | ||
![]() |
86c7b8522e | ||
![]() |
f9eb2a1ee5 | ||
![]() |
174d040ca3 | ||
![]() |
6b16b08712 | ||
![]() |
e9cdb28a06 | ||
![]() |
f8abf92a66 | ||
![]() |
9413856463 | ||
![]() |
c24d46cf0f | ||
![]() |
c38e4190f1 | ||
![]() |
53cec61cdf | ||
![]() |
150c3b413a | ||
![]() |
eb15c04254 | ||
![]() |
7d7a6f7ccc | ||
![]() |
b54d18d888 | ||
![]() |
705028c79d | ||
![]() |
a91ef2ce9e | ||
![]() |
73f46d3762 | ||
![]() |
1ceda017c7 | ||
![]() |
725cedab72 | ||
![]() |
40b60e8313 | ||
![]() |
5c01f04a07 | ||
![]() |
183181ee54 | ||
![]() |
74b58cae59 | ||
![]() |
b859823011 | ||
![]() |
701320b100 | ||
![]() |
dcdcf17f5e | ||
![]() |
7c9c3de644 | ||
![]() |
cbcd281784 | ||
![]() |
e70dcdc642 | ||
![]() |
391d3e7fc7 | ||
![]() |
02d986fc89 | ||
![]() |
65a6488e44 | ||
![]() |
cf703d5213 | ||
![]() |
3a8437c6f3 | ||
![]() |
640396da64 | ||
![]() |
7e005549fe | ||
![]() |
59b3362715 | ||
![]() |
9dc8e47113 | ||
![]() |
e958545230 | ||
![]() |
76f3e170d5 | ||
![]() |
a5af49dafd | ||
![]() |
736d9fe450 | ||
![]() |
bd7a520316 | ||
![]() |
7f5b5d6f03 | ||
![]() |
8d5a59e7d5 | ||
![]() |
989acce0a5 | ||
![]() |
641b4a806a | ||
![]() |
025a44b629 | ||
![]() |
dd64bf2af7 | ||
![]() |
d5b3f65076 | ||
![]() |
66de4cbead | ||
![]() |
be3d6adf77 | ||
![]() |
65e83e8fb6 | ||
![]() |
7a2be6f12c | ||
![]() |
0d6662b558 | ||
![]() |
0a2aa54508 | ||
![]() |
f6353cfb47 | ||
![]() |
fb71ba3b7c | ||
![]() |
ac6e086c26 | ||
![]() |
4c4cfb49b4 | ||
![]() |
9a073713bb | ||
![]() |
4db3bd3270 | ||
![]() |
d5d9ed7200 | ||
![]() |
0e409bb993 | ||
![]() |
89a8769399 | ||
![]() |
fdfd94b9d0 | ||
![]() |
ba56aec353 | ||
![]() |
3ac3cedc19 | ||
![]() |
2756db6601 | ||
![]() |
7d296ee650 | ||
![]() |
ccd26b4146 | ||
![]() |
5d4269be4c | ||
![]() |
54cdfc0c16 | ||
![]() |
fd899a2e95 | ||
![]() |
d1f446aae2 | ||
![]() |
c3f04ea67d | ||
![]() |
7b56aaad53 | ||
![]() |
b73677fa5e | ||
![]() |
0040ee5cb6 | ||
![]() |
f391574113 | ||
![]() |
ea863b0c24 | ||
![]() |
4506c90e59 | ||
![]() |
894a63ed82 | ||
![]() |
0155454526 | ||
![]() |
f7aafb87a8 | ||
![]() |
227001ec32 | ||
![]() |
d765364915 | ||
![]() |
3d47e63d6f | ||
![]() |
79c5c3cc57 | ||
![]() |
8babbddcf9 | ||
![]() |
13756508d3 | ||
![]() |
b7fe001b13 | ||
![]() |
35b4110a7a | ||
![]() |
cdca0c6325 | ||
![]() |
d928f5759f | ||
![]() |
23eeb4353d | ||
![]() |
8e8d74b5b7 | ||
![]() |
094851cc7d | ||
![]() |
f55612be40 | ||
![]() |
0951f0f824 | ||
![]() |
b70fd826e7 | ||
![]() |
994559b39b | ||
![]() |
f7534b3a0f | ||
![]() |
7fcc07805a | ||
![]() |
7f9f075147 | ||
![]() |
cbfc359a99 | ||
![]() |
907842c672 | ||
![]() |
c890ab44d6 | ||
![]() |
89b11ff71c | ||
![]() |
3e34eeeed7 | ||
![]() |
69302fcbd0 | ||
![]() |
60879351a9 | ||
![]() |
f4433ac508 | ||
![]() |
7b7d0d6171 | ||
![]() |
a6e0ed09a8 | ||
![]() |
19ed6ebbaf | ||
![]() |
dfeee17d39 | ||
![]() |
4c429c869c | ||
![]() |
6d8a361c9a | ||
![]() |
825de1b6ee | ||
![]() |
124461f587 | ||
![]() |
a570fa6110 | ||
![]() |
0e8df83bbd | ||
![]() |
952c8428d8 | ||
![]() |
5fe2c10aa1 | ||
![]() |
1f4aa2506b | ||
![]() |
9f8844fa5f | ||
![]() |
990aa88e00 | ||
![]() |
9e335c1894 | ||
![]() |
8f2b9a6bb7 | ||
![]() |
448f3e8918 | ||
![]() |
62b2ab7571 | ||
![]() |
46fa9a9366 | ||
![]() |
29fee28d1d | ||
![]() |
78cbfa20d9 | ||
![]() |
ccd42d42ab | ||
![]() |
abe03ef9a3 | ||
![]() |
9813ffb83b | ||
![]() |
b4eefa3eed | ||
![]() |
3490273b49 | ||
![]() |
65c8b6e66a | ||
![]() |
6a166b798a | ||
![]() |
0686aec606 | ||
![]() |
54b3c62803 | ||
![]() |
40d83ba7e7 | ||
![]() |
ea3c379d88 | ||
![]() |
a6ee3e99ea | ||
![]() |
b2cab4aea0 | ||
![]() |
2a2e532acc | ||
![]() |
0954a494e7 | ||
![]() |
bc32c946ff | ||
![]() |
95debf66e5 | ||
![]() |
3b166f82a8 | ||
![]() |
7d19250565 | ||
![]() |
c510a4149d | ||
![]() |
33e473c509 | ||
![]() |
e3dfdb0b06 | ||
![]() |
efa262480a | ||
![]() |
2c8dd9ce2a | ||
![]() |
ead1399e7b | ||
![]() |
5ebde97352 | ||
![]() |
f6c624b59a | ||
![]() |
4a4b1e0e49 | ||
![]() |
cb5e37184a | ||
![]() |
4b78a9366d | ||
![]() |
90b9223aae | ||
![]() |
094a3af8ae | ||
![]() |
0d2296917a | ||
![]() |
d6fffc7e55 | ||
![]() |
283d33aa27 | ||
![]() |
6c445c0833 | ||
![]() |
dd10c1756f | ||
![]() |
74bda719a6 | ||
![]() |
ced75a9b60 | ||
![]() |
5ecad47d6e | ||
![]() |
6e11ca1ac4 | ||
![]() |
edfdabb691 | ||
![]() |
4653e94c57 | ||
![]() |
54df50f84d | ||
![]() |
7588c8de5a | ||
![]() |
d564199e88 | ||
![]() |
e458adb342 | ||
![]() |
b43a7354cf | ||
![]() |
6341ad88e8 | ||
![]() |
314b2fb14f | ||
![]() |
795ba89dc4 | ||
![]() |
5b8ff28556 | ||
![]() |
5e66a66111 | ||
![]() |
3e6bed538a | ||
![]() |
f893edeb82 | ||
![]() |
64e4adef29 | ||
![]() |
c1fe03aab6 | ||
![]() |
4b0a071a35 | ||
![]() |
4ef69969a7 | ||
![]() |
c5885d9ce4 | ||
![]() |
4c2d705311 | ||
![]() |
939017ada9 | ||
![]() |
322c5c05cf | ||
![]() |
cd174b8ce9 | ||
![]() |
f5999f28e9 | ||
![]() |
428a754bfc | ||
![]() |
9ba2a9d907 | ||
![]() |
71a22348c9 | ||
![]() |
4ac0db1869 | ||
![]() |
bca9035302 | ||
![]() |
33b316d72f | ||
![]() |
020322df0b | ||
![]() |
6068043fd4 | ||
![]() |
2bf4032a6f | ||
![]() |
5e659e3f46 | ||
![]() |
23f70d6b8b | ||
![]() |
ddcf2c5206 | ||
![]() |
6b88349c77 | ||
![]() |
4eb2d3805d | ||
![]() |
6cdddc4e9f | ||
![]() |
406d844722 | ||
![]() |
09ee0357c7 | ||
![]() |
f603f63361 | ||
![]() |
720bb5d615 | ||
![]() |
eebd76661d | ||
![]() |
7885ae5d3f | ||
![]() |
08257cc5dd | ||
![]() |
27f8144bb8 | ||
![]() |
146d4a8365 | ||
![]() |
bddd9b3409 | ||
![]() |
0d4d83f3a6 | ||
![]() |
4bb0bb4ff0 | ||
![]() |
2d75968532 | ||
![]() |
aa0e759168 | ||
![]() |
cdae745c00 | ||
![]() |
a8b6af1f03 | ||
![]() |
c7106073b4 | ||
![]() |
d96139798f | ||
![]() |
bd560644fe | ||
![]() |
f6772c4138 | ||
![]() |
dd733640e5 | ||
![]() |
75a0c0a527 | ||
![]() |
a5925875a7 | ||
![]() |
84157f9247 | ||
![]() |
fcf3ed7881 | ||
![]() |
dac3be69d6 | ||
![]() |
5118e5cceb | ||
![]() |
7ca0d20dda | ||
![]() |
378222e484 | ||
![]() |
812bec205c | ||
![]() |
2ee8803e33 | ||
![]() |
007616ca42 | ||
![]() |
f3b235e4a7 | ||
![]() |
074d4be4ba | ||
![]() |
03cd48257b | ||
![]() |
546db83de3 | ||
![]() |
cc11a39f7e | ||
![]() |
a83b365afd | ||
![]() |
6a6cfac603 | ||
![]() |
5270cedc56 | ||
![]() |
2ac833d2a6 | ||
![]() |
f7be210b12 | ||
![]() |
24774d7921 | ||
![]() |
2b2e954b84 | ||
![]() |
85108be686 | ||
![]() |
9fbac943bb | ||
![]() |
d901eaa8d2 | ||
![]() |
5fb0e8d007 | ||
![]() |
cd5c76cb76 | ||
![]() |
b2a64f8bf3 | ||
![]() |
b91acc9de5 | ||
![]() |
07836c7ffa | ||
![]() |
8b30a0d7cc | ||
![]() |
13a3e2feb2 | ||
![]() |
f4dca71497 | ||
![]() |
e4c6e87338 | ||
![]() |
b2862520fd | ||
![]() |
bb29f1ea95 | ||
![]() |
69b92757f4 | ||
![]() |
62ae2652c7 | ||
![]() |
6f6633050b | ||
![]() |
d37bfd6651 | ||
![]() |
55a17a8a83 | ||
![]() |
422b06b72d | ||
![]() |
873a1d1c3b | ||
![]() |
44d06767b5 | ||
![]() |
3f4379afbf | ||
![]() |
c0515de6b7 | ||
![]() |
09159ec245 | ||
![]() |
ab0bf80888 | ||
![]() |
74b8eaed04 | ||
![]() |
d64b5ccae2 | ||
![]() |
3883212ca7 | ||
![]() |
1cec41dba0 | ||
![]() |
d00c0ff60c | ||
![]() |
1d597c5f5b | ||
![]() |
c004ef7d0b | ||
![]() |
1bfb977b28 | ||
![]() |
04138047f6 | ||
![]() |
147e99a915 | ||
![]() |
6f7d162edc | ||
![]() |
910aee4b73 | ||
![]() |
77e376751a | ||
![]() |
7e1264ac44 | ||
![]() |
8f3a4a5a04 | ||
![]() |
2d2689362d | ||
![]() |
913500a6de | ||
![]() |
81d7c54a55 | ||
![]() |
4501d5a8fc | ||
![]() |
becc90409f | ||
![]() |
10c4f7b465 | ||
![]() |
cb5b0ff764 | ||
![]() |
277a817eaf | ||
![]() |
fbac6f6a57 | ||
![]() |
b1b0d6ceb6 | ||
![]() |
07421542df | ||
![]() |
74a8139ac9 | ||
![]() |
77eb76fefb | ||
![]() |
42a450c61f | ||
![]() |
9e2ed10144 | ||
![]() |
27e5ce7f9b | ||
![]() |
f7b322da49 | ||
![]() |
16ad13c962 | ||
![]() |
a8880bbc0a | ||
![]() |
f020b88db3 | ||
![]() |
a4f5c9e2a3 | ||
![]() |
96d3841dba | ||
![]() |
39277d569f | ||
![]() |
75b5bc03f7 | ||
![]() |
01e17d9c2e | ||
![]() |
8047ff96a8 | ||
![]() |
0e737a2f3b | ||
![]() |
854579d814 | ||
![]() |
f3cbd99e45 | ||
![]() |
c13ed3f347 | ||
![]() |
7409b58546 | ||
![]() |
404ebb8810 | ||
![]() |
b4a9a300c5 | ||
![]() |
aa637e6a2b | ||
![]() |
85132e1e6e | ||
![]() |
f0aa5a4646 | ||
![]() |
b0479d0bd9 | ||
![]() |
e475b888aa | ||
![]() |
a8a3bbd9f5 | ||
![]() |
f3cbd17598 | ||
![]() |
3d7e4dc286 | ||
![]() |
2e98729527 | ||
![]() |
3ac838a7ec | ||
![]() |
a1bd5bfc00 | ||
![]() |
b99571a797 | ||
![]() |
43dec8914c | ||
![]() |
5b5cb78595 | ||
![]() |
cb8c919609 | ||
![]() |
be3810dfed | ||
![]() |
b961b59ad4 | ||
![]() |
d2fbb86d8a | ||
![]() |
782c6211d0 |
47
.github/CONTRIBUTING.md
vendored
47
.github/CONTRIBUTING.md
vendored
@@ -1,40 +1,45 @@
|
|||||||
NewPipe contribution guidelines
|
NewPipe contribution guidelines
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
READ THIS GUIDELINES CAREFULLY BEFORE CONTRIBUTING.
|
PLEASE READ THESE GUIDELINES CAREFULLY BEFORE ANY CONTRIBUTION!
|
||||||
|
|
||||||
## Crash reporting
|
## Crash reporting
|
||||||
|
|
||||||
Do not report crashes in the GitHub issue tracker. NewPipe has an automated crash report system that will ask you to send a report if a crash occurs.
|
Do not report crashes in the GitHub issue tracker. NewPipe has an automated crash report system that will ask you to send a report via e-mail when a crash occurs. This contains all the data we need for debugging, and allows you to even add a comment to it. You'll see exactly what is sent, the system is 100% transparent.
|
||||||
|
|
||||||
## Issue reporting/feature request
|
## Issue reporting/feature requests
|
||||||
|
|
||||||
* Search the [existing issues](https://github.com/theScrabi/NewPipe/issues) first to make sure your issue/feature hasn't been reported/requested before
|
* Search the [existing issues](https://github.com/TeamNewPipe/NewPipe/issues) first to make sure your issue/feature hasn't been reported/requested before
|
||||||
* Check if this issue/feature is already fixed/implemented in the repository
|
* Check whether your issue/feature is already fixed/implemented
|
||||||
* If you are an android/java developer you are always welcome to fix/implement an issue/a feature yourself
|
* If you are an Android/Java developer, you are always welcome to fix/implement an issue/a feature yourself. PRs welcome!
|
||||||
* Use english
|
* We use English for development. Issues in other languages will be closed and ignored.
|
||||||
|
* Please only add *one* issue at a time. Do not put multiple issues into one thread.
|
||||||
|
|
||||||
## Bugfixing
|
## Bug Fixing
|
||||||
* If you want to help NewPipe getting bug free, you can send me a mail to tnp@newpipe.schabi.org to let me know that you intent to help, and than register at our [sentry](https://support.schabi.org) setup.
|
* If you want to help NewPipe to become free of bugs (this is our utopic goal for NewPipe), you can send us an email to tnp@newpipe.schabi.org to let me know that you intend to help. We'll send you further instructions. You may, on request, register at our [Sentry](https://sentry.schabi.org) instance (see section "Crash reporting" for more information.
|
||||||
|
|
||||||
## Translation
|
## Translation
|
||||||
|
|
||||||
* NewPipe can be translated on [weblate](https://hosted.weblate.org/projects/newpipe/strings/)
|
* NewPipe can be translated via [Weblate](https://hosted.weblate.org/projects/newpipe/strings/). You can log in there with your GitHub account.
|
||||||
|
|
||||||
## Code contribution
|
## Code contribution
|
||||||
|
|
||||||
* Stick to NewPipe style guidelines (just look the other code and than do it the same way :) )
|
* Stick to NewPipe's style conventions (well, just look the other code and then do it the same way :))
|
||||||
* Do not bring nonfree software/binary blobs into the project (keep it google free)
|
* Do not bring non-free software (e.g., binary blobs) into the project. Also, make sure you do not introduce Google libraries.
|
||||||
* Stick to [f-droid contribution guidelines](https://f-droid.org/wiki/page/Inclusion_Policy)
|
* Stick to [F-Droid contribution guidelines](https://f-droid.org/wiki/page/Inclusion_Policy)
|
||||||
* Make changes on a separate branch, not on the master branch (Feature-branching)
|
* Make changes on a separate branch, not on the master branch. This is commonly known as *feature branch workflow*. You may then send your changes as a pull request on GitHub. Patches to the email address mentioned in this document might not be considered, GitHub is the primary platform.
|
||||||
* When submitting changes, you agree that your code will be licensed under GPLv3
|
* When submitting changes, you confirm that your code is licensed under the terms of the [GNU General Public License v3](https://www.gnu.org/licenses/gpl-3.0.html).
|
||||||
* Please test (compile and run) your code before you submit changes!!!
|
* Please test (compile and run) your code before you submit changes! Ideally, provide test feedback in the PR description. Untested code will **not** be merged!
|
||||||
* Try to figure out you selves why CI fails, or why a merge request collides
|
* Try to figure out yourself why builds on our CI fail.
|
||||||
* Please maintain your code after you contributed it.
|
* Make sure your PR is up-to-date with the rest of the code. Often, a simple click on "Update branch" will do the job, but if not, you are asked to merge the master branch manually and resolve the problems on your own. That will make the maintainers' jobs way easier.
|
||||||
* Respond yourselves if someone request changes or notifies issues
|
* Please show intention to maintain your features and code after you contributed it. Unmaintained code is a hassle for the core developers, and just adds work. If you do not intend to maintain features you contributed, please think again about submission, or clearly state that in the description of your PR.
|
||||||
|
* Respond yourselves if someone requests changes or otherwise raises issues about your PRs.
|
||||||
|
* Check if your contributions align with the [fdroid inclusion guidelines](https://f-droid.org/en/docs/Inclusion_Policy/).
|
||||||
|
* Check if your submission can be build with the current fdroid build server setup.
|
||||||
|
|
||||||
## Communication
|
## Communication
|
||||||
|
|
||||||
* WE DO NOW HAVE A MAILING LIST: [newpipe@list.schabi.org](https://list.schabi.org/cgi-bin/mailman/listinfo/newpipe).
|
* WE DO NOW HAVE A MAILING LIST: [newpipe@list.schabi.org](https://list.schabi.org/cgi-bin/mailman/listinfo/newpipe).
|
||||||
* If you want to get in contact with me or one of our other contributors you can send me an email at tnp(at)schabi.org
|
* There is an IRC channel on Freenode which is regularly visited by the core team and other developers: [#newpipe](irc:irc.freenode.net/newpipe). [Click here for Webchat](https://webchat.freenode.net/?channels=newpipe)!
|
||||||
* Feel free to post suggestions, changes, ideas etc!
|
* If you want to get in touch with the core team or one of our other contributors you can send an email to tnp(at)schabi.org. Please do not send issue reports, they will be ignored and remain unanswered! Use the GitHub issue tracker described above!
|
||||||
|
* Feel free to post suggestions, changes, ideas etc. on GitHub, IRC or the mailing list!
|
||||||
|
1
.github/PULL_REQUEST_TEAMPLATE.md
vendored
1
.github/PULL_REQUEST_TEAMPLATE.md
vendored
@@ -1 +0,0 @@
|
|||||||
[ ] I carefully reed the [contribution guidelines](https://github.com/TeamNewPipe/NewPipe/blob/HEAD/.github/CONTRIBUTING.md) and agree to them.
|
|
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
- [ ] I carefully read the [contribution guidelines](https://github.com/TeamNewPipe/NewPipe/blob/HEAD/.github/CONTRIBUTING.md) and agree to them.
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
|||||||
[submodule "app/src/main/java/org/schabi/newpipe/extractor"]
|
|
||||||
path = app/src/main/java/org/schabi/newpipe/extractor
|
|
||||||
url = https://github.com/TeamNewPipe/NewPipeExtractor.git
|
|
||||||
|
10
.travis.yml
10
.travis.yml
@@ -5,16 +5,14 @@ android:
|
|||||||
components:
|
components:
|
||||||
# The BuildTools version used by NewPipe
|
# The BuildTools version used by NewPipe
|
||||||
- tools
|
- tools
|
||||||
- build-tools-25.0.2
|
- build-tools-27.0.1
|
||||||
|
|
||||||
# The SDK version used to compile NewPipe
|
# The SDK version used to compile NewPipe
|
||||||
- android-25
|
- android-27
|
||||||
|
|
||||||
# Additional components
|
|
||||||
- extra-android-m2repository
|
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- yes | sdkmanager "platforms;android-27"
|
||||||
script: ./gradlew -Dorg.gradle.jvmargs=-Xmx1536m assembleDebug lintDebug testDebugUnitTest
|
script: ./gradlew -Dorg.gradle.jvmargs=-Xmx1536m assembleDebug lintDebug testDebugUnitTest
|
||||||
|
|
||||||
licenses:
|
licenses:
|
||||||
- '.+'
|
- '.+'
|
||||||
|
|
||||||
|
88
README.md
88
README.md
@@ -1,34 +1,34 @@
|
|||||||
|
<p align="center"><a href="https://newpipe.schabi.org"><img src="assets/new_pipe_icon_5.png" width="150"/></a></p>
|
||||||
|
<h2 align="center"><b>NewPipe</b></h2>
|
||||||
|
<h4 align="center">A free lightweight YouTube frontend for Android.</h4>
|
||||||
|
<p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://f-droid.org/wiki/images/0/06/F-Droid-button_get-it-on.png"/></a></p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/TeamNewPipe/NewPipe" alt="GitHub release"><img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe.svg" /></a>
|
||||||
|
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="License: GPL v3"><img src="https://img.shields.io/badge/License-GPL%20v3-blue.svg" /></a>
|
||||||
|
<a href="https://travis-ci.org/TeamNewPipe/NewPipe" alt="Build Status"><img src="https://travis-ci.org/TeamNewPipe/NewPipe.svg" /></a>
|
||||||
|
<a href="https://hosted.weblate.org/engage/NewPipe/" alt="Translation Status"><img src="https://hosted.weblate.org/widgets/NewPipe/-/svg-badge.svg" /></a>
|
||||||
|
<a href="http://webchat.freenode.net/?channels=%23newpipe" alt="IRC channel: #newpipe"><img src="https://img.shields.io/badge/IRC%20chat-%23newpipe-brightgreen.svg" /></a>
|
||||||
|
<a href="https://www.bountysource.com/teams/newpipe" alt="Bountysource bounties"><img src="https://img.shields.io/bountysource/team/newpipe/activity.svg?colorB=cd201f"/></a>
|
||||||
|
</p>
|
||||||
|
<hr />
|
||||||
|
<p align="center"><a href="#screenshots">Screenshots</a> • <a href="#description">Description</a> • <a href="#features">Features</a> • <a href="#contribution">Contribution</a> • <a href="#donate">Donate</a> • <a href="#license">License</a></p>
|
||||||
|
<p align="center"><a href="https://newpipe.schabi.org">Website</a> • <a href="https://newpipe.schabi.org/blog/">Blog</a> • <a href="https://newpipe.schabi.org/press/">Press</a></p>
|
||||||
|
<hr />
|
||||||
WARNING: PUTTING NEWPIPE OR ANY FORK OF IT INTO GOOGLE PLAYSTORE VIOLATES THEIR TERMS OF CONDITIONS.
|
WARNING: PUTTING NEWPIPE OR ANY FORK OF IT INTO GOOGLE PLAYSTORE VIOLATES THEIR TERMS OF CONDITIONS.
|
||||||
|
|
||||||
# NewPipe
|
|
||||||
NewPipe: A free lightweight Youtube frontend for Android.
|
|
||||||
|
|
||||||
[](https://newpipe.schabi.org)
|
|
||||||
[](https://f-droid.org/packages/org.schabi.newpipe/)
|
|
||||||
|
|
||||||
|
|
||||||
Project status:
|
|
||||||
[](https://hosted.weblate.org/engage/NewPipe/)
|
|
||||||
[](https://travis-ci.org/TeamNewPipe/NewPipe)
|
|
||||||
|
|
||||||
## Donate
|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
`16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh`
|
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
[<img src="screenshots/screenshot_1.png" width=160>](screenshots/screenshot_1.png)
|
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_1.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_1.png)
|
||||||
[<img src="screenshots/screenshot_2.png" width=160>](screenshots/screenshot_2.png)
|
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_2.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_2.png)
|
||||||
[<img src="screenshots/screenshot_3.png" width=160>](screenshots/screenshot_3.png)
|
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_3.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_3.png)
|
||||||
[<img src="screenshots/screenshot_4.png" width=160>](screenshots/screenshot_4.png)
|
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_4.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_4.png)
|
||||||
[<img src="screenshots/screenshot_5.png" width=160>](screenshots/screenshot_5.png)
|
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_5.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_5.png)
|
||||||
[<img src="screenshots/screenshot_6.png" width=160>](screenshots/screenshot_6.png)
|
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_6.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_6.png)
|
||||||
[<img src="screenshots/screenshot_7.png" width=160>](screenshots/screenshot_7.png)
|
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_7.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_7.png)
|
||||||
[<img src="screenshots/screenshot_8.png" width=160>](screenshots/screenshot_8.png)
|
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_8.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_8.png)
|
||||||
[<img src="screenshots/screenshot_9.png" width=160>](screenshots/screenshot_9.png)
|
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_9.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_9.png)
|
||||||
|
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_10.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_10.png)
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ NewPipe does not use any Google framework libraries, or the YouTube API. It only
|
|||||||
* Search videos
|
* Search videos
|
||||||
* Display general information about a video
|
* Display general information about a video
|
||||||
* Watch YouTube videos
|
* Watch YouTube videos
|
||||||
* Listen to YouTube videos (experimental)
|
* Listen to YouTube videos
|
||||||
* Popup mode (floating player)
|
* Popup mode (floating player)
|
||||||
* Select the streaming player to watch the video with
|
* Select the streaming player to watch the video with
|
||||||
* Download videos
|
* Download videos
|
||||||
@@ -47,21 +47,23 @@ NewPipe does not use any Google framework libraries, or the YouTube API. It only
|
|||||||
* Open a video in Kodi
|
* Open a video in Kodi
|
||||||
* Show Next/Related videos
|
* Show Next/Related videos
|
||||||
* Search YouTube in a specific language
|
* Search YouTube in a specific language
|
||||||
* Watch age restricted material
|
* Watch/Block age restricted material
|
||||||
* Display general information about channels
|
* Display general information about channels
|
||||||
* Search channels
|
* Search channels
|
||||||
* Watch videos from a channel
|
* Watch videos from a channel
|
||||||
* Orbot/Tor support (not yet directly)
|
* Orbot/Tor support (not yet directly)
|
||||||
* 1080p/2k/4k support
|
* 1080p/2k/4k support
|
||||||
|
* View history
|
||||||
|
* Subscribe to channels
|
||||||
|
* Search history
|
||||||
|
* Search/Watch Playlists
|
||||||
|
* Watch as queues Playlists
|
||||||
|
* Queuing videos
|
||||||
|
|
||||||
### Coming Features
|
### Coming Features
|
||||||
|
|
||||||
|
* Multiservice support (eg. SoundCloud)
|
||||||
* Bookmarks
|
* Bookmarks
|
||||||
* View history
|
|
||||||
* Search history
|
|
||||||
* Subscribe to channels
|
|
||||||
* Search/Watch Playlists
|
|
||||||
* Queeing videos
|
|
||||||
* Subtitles support
|
* Subtitles support
|
||||||
* livestream support
|
* livestream support
|
||||||
* ... and many more
|
* ... and many more
|
||||||
@@ -70,11 +72,27 @@ NewPipe does not use any Google framework libraries, or the YouTube API. It only
|
|||||||
Although NewPipe only supports YouTube at the moment, it's designed to support many more streaming services. The plan is, that NewPipe will get such support by the version 2.0.
|
Although NewPipe only supports YouTube at the moment, it's designed to support many more streaming services. The plan is, that NewPipe will get such support by the version 2.0.
|
||||||
|
|
||||||
## Contribution
|
## Contribution
|
||||||
Whether you have ideas, translation, design changes, code cleaning, or real heavy code changes, help is always welcome.
|
Whether you have ideas, translations, design changes, code cleaning, or real heavy code changes, help is always welcome.
|
||||||
The more is done the better it gets!
|
The more is done the better it gets!
|
||||||
|
|
||||||
If you'd like to get involved, check our [contribution notes](.github/CONTRIBUTING.md).
|
If you'd like to get involved, check our [contribution notes](.github/CONTRIBUTING.md).
|
||||||
|
|
||||||
|
## Donate
|
||||||
|
If you like NewPipe we'd be happy about a donation. You can either donate via Bitcoin or BountySource. For further information about donating to NewPipe, please visit our [website](https://newpipe.schabi.org/donate/).
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><img src="https://bitcoin.org/img/icons/logotop.svg" alt="Bitcoin" /></td>
|
||||||
|
<td><img src="assets/bitcoin_qr_code.png" alt="Bitcoin QR Code" width="100px"/></td>
|
||||||
|
<td><samp>16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh</samp></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="https://www.bountysource.com/teams/newpipe"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/22/Bountysource.png/320px-Bountysource.png" alz="Bountysource" width="190px" /></a></td>
|
||||||
|
<td><a href="https://www.bountysource.com/teams/newpipe"><img src="assets/bountysource_qr_code.png" alt="Visit NewPipe at bountysource.com" width="100px"/></a></td>
|
||||||
|
<td><a href="https://www.bountysource.com/teams/newpipe/issues"><img src="https://img.shields.io/bountysource/team/newpipe/activity.svg?colorB=cd201f" height="30px" alt="Check out how many bounties you can earn." /></a></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
## License
|
## License
|
||||||
[](http://www.gnu.org/licenses/gpl-3.0.en.html)
|
[](http://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||||
|
|
||||||
|
@@ -1,23 +1,38 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 25
|
compileSdkVersion 27
|
||||||
buildToolsVersion '25.0.2'
|
buildToolsVersion '27.0.1'
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "org.schabi.newpipe"
|
applicationId "org.schabi.newpipe"
|
||||||
minSdkVersion 15
|
minSdkVersion 15
|
||||||
targetSdkVersion 25
|
targetSdkVersion 27
|
||||||
versionCode 37
|
versionCode 43
|
||||||
versionName "0.9.10"
|
versionName "0.11.2"
|
||||||
|
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
|
vectorDrawables.useSupportLibrary = true
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
minifyEnabled false
|
minifyEnabled true
|
||||||
|
shrinkResources true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
|
debug {
|
||||||
|
multiDexEnabled true
|
||||||
|
|
||||||
|
debuggable true
|
||||||
|
applicationIdSuffix ".debug"
|
||||||
|
}
|
||||||
|
beta {
|
||||||
|
minifyEnabled true
|
||||||
|
shrinkResources true
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
|
||||||
|
applicationIdSuffix ".beta"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lintOptions {
|
lintOptions {
|
||||||
@@ -32,30 +47,46 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ext {
|
||||||
|
supportLibVersion = '27.0.2'
|
||||||
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2') {
|
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2') {
|
||||||
exclude module: 'support-annotations'
|
exclude module: 'support-annotations'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
implementation 'com.github.TeamNewPipe:NewPipeExtractor:2d191c4ca'
|
||||||
|
|
||||||
testCompile 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
testCompile 'org.mockito:mockito-core:1.10.19'
|
testImplementation 'org.mockito:mockito-core:1.10.19'
|
||||||
testCompile 'org.json:json:20160810'
|
|
||||||
|
|
||||||
compile 'com.android.support:appcompat-v7:25.3.1'
|
implementation "com.android.support:appcompat-v7:$supportLibVersion"
|
||||||
compile 'com.android.support:support-v4:25.3.1'
|
implementation "com.android.support:support-v4:$supportLibVersion"
|
||||||
compile 'com.android.support:design:25.3.1'
|
implementation "com.android.support:design:$supportLibVersion"
|
||||||
compile 'com.android.support:recyclerview-v7:25.3.1'
|
implementation "com.android.support:recyclerview-v7:$supportLibVersion"
|
||||||
|
implementation "com.android.support:preference-v14:$supportLibVersion"
|
||||||
|
|
||||||
compile 'com.google.code.gson:gson:2.7'
|
implementation 'com.google.code.gson:gson:2.8.2'
|
||||||
compile 'org.jsoup:jsoup:1.8.3'
|
implementation 'ch.acra:acra:4.9.2'
|
||||||
compile 'org.mozilla:rhino:1.7.7'
|
|
||||||
compile 'ch.acra:acra:4.9.0'
|
|
||||||
compile 'info.guardianproject.netcipher:netcipher:1.2'
|
|
||||||
|
|
||||||
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
|
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
|
||||||
compile 'de.hdodenhof:circleimageview:2.0.0'
|
implementation 'de.hdodenhof:circleimageview:2.2.0'
|
||||||
compile 'com.github.nirhart:parallaxscroll:1.0'
|
implementation 'com.github.nirhart:ParallaxScroll:dd53d1f9d1'
|
||||||
compile 'com.nononsenseapps:filepicker:3.0.0'
|
implementation 'com.nononsenseapps:filepicker:3.0.1'
|
||||||
compile 'com.google.android.exoplayer:exoplayer:r2.4.2'
|
implementation 'com.google.android.exoplayer:exoplayer:r2.5.4'
|
||||||
|
|
||||||
|
debugImplementation 'com.facebook.stetho:stetho:1.5.0'
|
||||||
|
debugImplementation 'com.facebook.stetho:stetho-urlconnection:1.5.0'
|
||||||
|
debugImplementation 'com.android.support:multidex:1.0.2'
|
||||||
|
|
||||||
|
implementation 'io.reactivex.rxjava2:rxjava:2.1.7'
|
||||||
|
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
|
||||||
|
implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
|
||||||
|
|
||||||
|
implementation 'android.arch.persistence.room:runtime:1.0.0'
|
||||||
|
implementation 'android.arch.persistence.room:rxjava2:1.0.0'
|
||||||
|
annotationProcessor 'android.arch.persistence.room:compiler:1.0.0'
|
||||||
|
|
||||||
|
implementation 'frankiesardo:icepick:3.2.0'
|
||||||
|
annotationProcessor 'frankiesardo:icepick-processor:3.2.0'
|
||||||
}
|
}
|
||||||
|
20
app/proguard-rules.pro
vendored
20
app/proguard-rules.pro
vendored
@@ -15,3 +15,23 @@
|
|||||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
# public *;
|
# public *;
|
||||||
#}
|
#}
|
||||||
|
|
||||||
|
-dontobfuscate
|
||||||
|
-keep class org.mozilla.javascript.** { *; }
|
||||||
|
|
||||||
|
-keep class org.mozilla.classfile.ClassFileWriter
|
||||||
|
-keep class com.google.android.exoplayer2.** { *; }
|
||||||
|
|
||||||
|
-dontwarn org.mozilla.javascript.tools.**
|
||||||
|
-dontwarn android.arch.util.paging.CountedDataSource
|
||||||
|
-dontwarn android.arch.persistence.room.paging.LimitOffsetDataSource
|
||||||
|
|
||||||
|
|
||||||
|
# Rules for icepick. Copy paste from https://github.com/frankiesardo/icepick
|
||||||
|
-dontwarn icepick.**
|
||||||
|
-keep class icepick.** { *; }
|
||||||
|
-keep class **$$Icepick { *; }
|
||||||
|
-keepclasseswithmembernames class * {
|
||||||
|
@icepick.* <fields>;
|
||||||
|
}
|
||||||
|
-keepnames class * { @icepick.State *;}
|
||||||
|
10
app/src/beta/AndroidManifest.xml
Normal file
10
app/src/beta/AndroidManifest.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:label="NewPipe Beta"
|
||||||
|
tools:replace="android:label">
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
BIN
app/src/beta/res/mipmap-hdpi/ic_launcher.png
Normal file
BIN
app/src/beta/res/mipmap-hdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
BIN
app/src/beta/res/mipmap-mdpi/ic_launcher.png
Normal file
BIN
app/src/beta/res/mipmap-mdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
BIN
app/src/beta/res/mipmap-xhdpi/ic_launcher.png
Normal file
BIN
app/src/beta/res/mipmap-xhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
BIN
app/src/beta/res/mipmap-xxhdpi/ic_launcher.png
Normal file
BIN
app/src/beta/res/mipmap-xxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
app/src/beta/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
BIN
app/src/beta/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
17
app/src/debug/AndroidManifest.xml
Normal file
17
app/src/debug/AndroidManifest.xml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
package="org.schabi.newpipe">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:name=".DebugApp"
|
||||||
|
android:label="NewPipe Debug"
|
||||||
|
tools:replace="android:name, android:label">
|
||||||
|
<activity
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:label="NewPipe Debug"
|
||||||
|
tools:replace="android:label"/>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
45
app/src/debug/java/org/schabi/newpipe/DebugApp.java
Normal file
45
app/src/debug/java/org/schabi/newpipe/DebugApp.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.multidex.MultiDex;
|
||||||
|
|
||||||
|
import com.facebook.stetho.Stetho;
|
||||||
|
|
||||||
|
public class DebugApp extends App {
|
||||||
|
private static final String TAG = DebugApp.class.toString();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void attachBaseContext(Context base) {
|
||||||
|
super.attachBaseContext(base);
|
||||||
|
MultiDex.install(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
|
||||||
|
initStetho();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initStetho() {
|
||||||
|
// Create an InitializerBuilder
|
||||||
|
Stetho.InitializerBuilder initializerBuilder =
|
||||||
|
Stetho.newInitializerBuilder(this);
|
||||||
|
|
||||||
|
// Enable Chrome DevTools
|
||||||
|
initializerBuilder.enableWebKitInspector(
|
||||||
|
Stetho.defaultInspectorModulesProvider(this)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Enable command line interface
|
||||||
|
initializerBuilder.enableDumpapp(
|
||||||
|
Stetho.defaultDumperPluginsProvider(getApplicationContext())
|
||||||
|
);
|
||||||
|
|
||||||
|
// Use the InitializerBuilder to generate an Initializer
|
||||||
|
Stetho.Initializer initializer = initializerBuilder.build();
|
||||||
|
|
||||||
|
// Initialize Stetho with the Initializer
|
||||||
|
Stetho.initialize(initializer);
|
||||||
|
}
|
||||||
|
}
|
@@ -16,11 +16,12 @@
|
|||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:logo="@mipmap/ic_launcher"
|
android:logo="@mipmap/ic_launcher"
|
||||||
android:theme="@style/AppTheme"
|
android:theme="@style/DarkTheme"
|
||||||
tools:ignore="AllowBackup">
|
tools:ignore="AllowBackup">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:label="@string/app_name">
|
android:label="@string/app_name"
|
||||||
|
android:launchMode="singleTask">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
@@ -28,7 +29,7 @@
|
|||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".player.PlayVideoActivity"
|
android:name=".player.old.PlayVideoActivity"
|
||||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||||
android:theme="@style/VideoPlayerTheme"
|
android:theme="@style/VideoPlayerTheme"
|
||||||
tools:ignore="UnusedAttribute"/>
|
tools:ignore="UnusedAttribute"/>
|
||||||
@@ -37,6 +38,16 @@
|
|||||||
android:name=".player.BackgroundPlayer"
|
android:name=".player.BackgroundPlayer"
|
||||||
android:exported="false"/>
|
android:exported="false"/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".player.BackgroundPlayerActivity"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:label="@string/title_activity_background_player"/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".player.PopupVideoPlayerActivity"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:label="@string/title_activity_popup_player"/>
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".player.PopupVideoPlayer"
|
android:name=".player.PopupVideoPlayer"
|
||||||
android:exported="false"/>
|
android:exported="false"/>
|
||||||
@@ -51,6 +62,15 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".settings.SettingsActivity"
|
android:name=".settings.SettingsActivity"
|
||||||
android:label="@string/settings"/>
|
android:label="@string/settings"/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".about.AboutActivity"
|
||||||
|
android:label="@string/title_activity_about"/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".history.HistoryActivity"
|
||||||
|
android:label="@string/title_activity_history"/>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".PanicResponderActivity"
|
android:name=".PanicResponderActivity"
|
||||||
android:launchMode="singleInstance"
|
android:launchMode="singleInstance"
|
||||||
@@ -62,6 +82,7 @@
|
|||||||
<category android:name="android.intent.category.DEFAULT"/>
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ExitActivity"
|
android:name=".ExitActivity"
|
||||||
android:label="@string/general_error"
|
android:label="@string/general_error"
|
||||||
@@ -72,16 +93,20 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".download.DownloadActivity"
|
android:name=".download.DownloadActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:launchMode="singleTask"
|
android:launchMode="singleTask"/>
|
||||||
android:theme="@style/AppTheme"/>
|
|
||||||
|
|
||||||
<service android:name="us.shandian.giga.service.DownloadManagerService"/>
|
<service android:name="us.shandian.giga.service.DownloadManagerService"/>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="com.nononsenseapps.filepicker.FilePickerActivity"
|
android:name=".util.FilePickerActivityHelper"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:launchMode="singleTop"
|
android:theme="@style/FilePickerThemeDark">
|
||||||
android:theme="@style/FilePickerTheme"/>
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.GET_CONTENT" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ReCaptchaActivity"
|
android:name=".ReCaptchaActivity"
|
||||||
android:label="@string/reCaptchaActivity"/>
|
android:label="@string/reCaptchaActivity"/>
|
||||||
@@ -121,6 +146,8 @@
|
|||||||
<!-- channel prefix -->
|
<!-- channel prefix -->
|
||||||
<data android:pathPrefix="/channel/"/>
|
<data android:pathPrefix="/channel/"/>
|
||||||
<data android:pathPrefix="/user/"/>
|
<data android:pathPrefix="/user/"/>
|
||||||
|
<!-- playlist prefix -->
|
||||||
|
<data android:pathPrefix="/playlist"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.VIEW"/>
|
<action android:name="android.intent.action.VIEW"/>
|
||||||
@@ -154,12 +181,11 @@
|
|||||||
<data android:mimeType="text/plain"/>
|
<data android:mimeType="text/plain"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".RouterPopupActivity"
|
android:name=".RouterPopupActivity"
|
||||||
|
android:label="@string/popup_mode_share_menu_title"
|
||||||
android:taskAffinity=""
|
android:taskAffinity=""
|
||||||
android:theme="@android:style/Theme.NoDisplay"
|
android:theme="@style/PopupPermissionsTheme">
|
||||||
android:label="@string/popup_mode_share_menu_title">
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.VIEW"/>
|
<action android:name="android.intent.action.VIEW"/>
|
||||||
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
|
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
|
||||||
@@ -209,11 +235,5 @@
|
|||||||
<data android:mimeType="text/plain"/>
|
<data android:mimeType="text/plain"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
|
||||||
android:name=".about.AboutActivity"
|
|
||||||
android:label="@string/title_activity_about"
|
|
||||||
android:theme="@style/AppTheme">
|
|
||||||
</activity>
|
|
||||||
</application>
|
</application>
|
||||||
|
</manifest>
|
||||||
</manifest>
|
|
@@ -15,9 +15,9 @@ Version 2, June 1991
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.<br/>
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA<br/>
|
||||||
|
<br/>
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
</pre>
|
</pre>
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
<title>Mozilla Public License, version 2.0</title>
|
<title>Mozilla Public License, version 2.0</title>
|
||||||
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1 id="mozilla-public-license-version-2.0">Mozilla Public License<br>Version 2.0</h1>
|
<h1 id="mozilla-public-license-version-2.0">Mozilla Public License<br>Version 2.0</h1>
|
||||||
<h2 id="definitions">1. Definitions</h2>
|
<h2 id="definitions">1. Definitions</h2>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
package org.schabi.newpipe;
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Created by Christian Schabesberger on 24.12.15.
|
* Created by Christian Schabesberger on 24.12.15.
|
||||||
*
|
*
|
||||||
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
||||||
|
@@ -1,7 +1,11 @@
|
|||||||
package org.schabi.newpipe;
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
|
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
|
||||||
@@ -16,12 +20,20 @@ import org.schabi.newpipe.report.AcraReportSenderFactory;
|
|||||||
import org.schabi.newpipe.report.ErrorActivity;
|
import org.schabi.newpipe.report.ErrorActivity;
|
||||||
import org.schabi.newpipe.report.UserAction;
|
import org.schabi.newpipe.report.UserAction;
|
||||||
import org.schabi.newpipe.settings.SettingsActivity;
|
import org.schabi.newpipe.settings.SettingsActivity;
|
||||||
import org.schabi.newpipe.util.ThemeHelper;
|
import org.schabi.newpipe.util.ExtractorHelper;
|
||||||
|
import org.schabi.newpipe.util.StateSaver;
|
||||||
|
|
||||||
import info.guardianproject.netcipher.NetCipher;
|
import java.io.IOException;
|
||||||
import info.guardianproject.netcipher.proxy.OrbotHelper;
|
import java.io.InterruptedIOException;
|
||||||
|
import java.net.SocketException;
|
||||||
|
|
||||||
/**
|
import io.reactivex.annotations.NonNull;
|
||||||
|
import io.reactivex.exceptions.CompositeException;
|
||||||
|
import io.reactivex.exceptions.UndeliverableException;
|
||||||
|
import io.reactivex.functions.Consumer;
|
||||||
|
import io.reactivex.plugins.RxJavaPlugins;
|
||||||
|
|
||||||
|
/*
|
||||||
* Copyright (C) Hans-Christoph Steiner 2016 <hans@eds.org>
|
* Copyright (C) Hans-Christoph Steiner 2016 <hans@eds.org>
|
||||||
* App.java is part of NewPipe.
|
* App.java is part of NewPipe.
|
||||||
*
|
*
|
||||||
@@ -40,73 +52,101 @@ import info.guardianproject.netcipher.proxy.OrbotHelper;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public class App extends Application {
|
public class App extends Application {
|
||||||
private static final String TAG = App.class.toString();
|
protected static final String TAG = App.class.toString();
|
||||||
|
|
||||||
private static boolean useTor;
|
@SuppressWarnings("unchecked")
|
||||||
|
private static final Class<? extends ReportSenderFactory>[] reportSenderFactoryClasses = new Class[]{AcraReportSenderFactory.class};
|
||||||
|
|
||||||
final Class<? extends ReportSenderFactory>[] reportSenderFactoryClasses
|
@Override
|
||||||
= new Class[]{AcraReportSenderFactory.class};
|
protected void attachBaseContext(Context base) {
|
||||||
|
super.attachBaseContext(base);
|
||||||
|
|
||||||
|
initACRA();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
// init crashreport
|
// Initialize settings first because others inits can use its values
|
||||||
try {
|
SettingsActivity.initSettings(this);
|
||||||
final ACRAConfiguration acraConfig = new ConfigurationBuilder(this)
|
|
||||||
.setReportSenderFactoryClasses(reportSenderFactoryClasses)
|
|
||||||
.build();
|
|
||||||
ACRA.init(this, acraConfig);
|
|
||||||
} catch(ACRAConfigurationException ace) {
|
|
||||||
ace.printStackTrace();
|
|
||||||
ErrorActivity.reportError(this, ace, null, null,
|
|
||||||
ErrorActivity.ErrorInfo.make(UserAction.SEARCHED,"none",
|
|
||||||
"Could not initialize ACRA crash report", R.string.app_ui_crash));
|
|
||||||
}
|
|
||||||
|
|
||||||
//init NewPipe
|
|
||||||
NewPipe.init(Downloader.getInstance());
|
NewPipe.init(Downloader.getInstance());
|
||||||
|
NewPipeDatabase.init(this);
|
||||||
|
StateSaver.init(this);
|
||||||
|
initNotificationChannel();
|
||||||
|
|
||||||
// Initialize image loader
|
// Initialize image loader
|
||||||
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this).build();
|
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this).build();
|
||||||
ImageLoader.getInstance().init(config);
|
ImageLoader.getInstance().init(config);
|
||||||
|
|
||||||
/*
|
configureRxJavaErrorHandler();
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
||||||
if(prefs.getBoolean(getString(R.string.use_tor_key), false)) {
|
|
||||||
OrbotHelper.requestStartTor(this);
|
|
||||||
configureTor(true);
|
|
||||||
} else {
|
|
||||||
configureTor(false);
|
|
||||||
}*/
|
|
||||||
configureTor(false);
|
|
||||||
|
|
||||||
// DO NOT REMOVE THIS FUNCTION!!!
|
|
||||||
// Otherwise downloadPathPreference has invalid value.
|
|
||||||
SettingsActivity.initSettings(this);
|
|
||||||
|
|
||||||
ThemeHelper.setTheme(getApplicationContext());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void configureRxJavaErrorHandler() {
|
||||||
* Set the proxy settings based on whether Tor should be enabled or not.
|
// https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling
|
||||||
*/
|
RxJavaPlugins.setErrorHandler(new Consumer<Throwable>() {
|
||||||
public static void configureTor(boolean enabled) {
|
@Override
|
||||||
useTor = enabled;
|
public void accept(@NonNull Throwable throwable) throws Exception {
|
||||||
if (useTor) {
|
Log.e(TAG, "RxJavaPlugins.ErrorHandler called with -> : throwable = [" + throwable.getClass().getName() + "]");
|
||||||
NetCipher.useTor();
|
|
||||||
} else {
|
if (throwable instanceof UndeliverableException) {
|
||||||
NetCipher.setProxy(null);
|
// As UndeliverableException is a wrapper, get the cause of it to get the "real" exception
|
||||||
|
throwable = throwable.getCause();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (throwable instanceof CompositeException) {
|
||||||
|
for (Throwable element : ((CompositeException) throwable).getExceptions()) {
|
||||||
|
if (checkThrowable(element)) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkThrowable(throwable)) return;
|
||||||
|
|
||||||
|
// Throw uncaught exception that will trigger the report system
|
||||||
|
Thread.currentThread().getUncaughtExceptionHandler()
|
||||||
|
.uncaughtException(Thread.currentThread(), throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkThrowable(@NonNull Throwable throwable) {
|
||||||
|
// Don't crash the application over a simple network problem
|
||||||
|
return ExtractorHelper.hasAssignableCauseThrowable(throwable,
|
||||||
|
IOException.class, SocketException.class, InterruptedException.class, InterruptedIOException.class);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void initACRA() {
|
||||||
|
try {
|
||||||
|
final ACRAConfiguration acraConfig = new ConfigurationBuilder(this)
|
||||||
|
.setReportSenderFactoryClasses(reportSenderFactoryClasses)
|
||||||
|
.setBuildConfigClass(BuildConfig.class)
|
||||||
|
.build();
|
||||||
|
ACRA.init(this, acraConfig);
|
||||||
|
} catch (ACRAConfigurationException ace) {
|
||||||
|
ace.printStackTrace();
|
||||||
|
ErrorActivity.reportError(this, ace, null, null, ErrorActivity.ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
|
||||||
|
"Could not initialize ACRA crash report", R.string.app_ui_crash));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void checkStartTor(Context context) {
|
public void initNotificationChannel() {
|
||||||
if (useTor) {
|
if (Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
|
||||||
OrbotHelper.requestStartTor(context);
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isUsingTor() {
|
final String id = getString(R.string.notification_channel_id);
|
||||||
return useTor;
|
final CharSequence name = getString(R.string.notification_channel_name);
|
||||||
|
final String description = getString(R.string.notification_channel_description);
|
||||||
|
|
||||||
|
// Keep this below DEFAULT to avoid making noise on every notification update
|
||||||
|
final int importance = NotificationManager.IMPORTANCE_LOW;
|
||||||
|
|
||||||
|
NotificationChannel mChannel = new NotificationChannel(id, name, importance);
|
||||||
|
mChannel.setDescription(description);
|
||||||
|
|
||||||
|
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
mNotificationManager.createNotificationChannel(mChannel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
121
app/src/main/java/org/schabi/newpipe/BaseFragment.java
Normal file
121
app/src/main/java/org/schabi/newpipe/BaseFragment.java
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.AttrRes;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
|
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
|
||||||
|
|
||||||
|
import icepick.Icepick;
|
||||||
|
|
||||||
|
public abstract class BaseFragment extends Fragment {
|
||||||
|
protected final String TAG = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
|
||||||
|
protected boolean DEBUG = MainActivity.DEBUG;
|
||||||
|
|
||||||
|
protected AppCompatActivity activity;
|
||||||
|
public static final ImageLoader imageLoader = ImageLoader.getInstance();
|
||||||
|
|
||||||
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
|
// Fragment's Lifecycle
|
||||||
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
activity = (AppCompatActivity) context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetach() {
|
||||||
|
super.onDetach();
|
||||||
|
activity = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
if (DEBUG) Log.d(TAG, "onCreate() called with: savedInstanceState = [" + savedInstanceState + "]");
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
Icepick.restoreInstanceState(this, savedInstanceState);
|
||||||
|
if (savedInstanceState != null) onRestoreInstanceState(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(View rootView, Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(rootView, savedInstanceState);
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "onViewCreated() called with: rootView = [" + rootView + "], savedInstanceState = [" + savedInstanceState + "]");
|
||||||
|
}
|
||||||
|
initViews(rootView, savedInstanceState);
|
||||||
|
initListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
Icepick.saveInstanceState(this, outState);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
|
// Init
|
||||||
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
protected void initViews(View rootView, Bundle savedInstanceState) {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initListeners() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
|
// Utils
|
||||||
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
protected final int resolveResourceIdFromAttr(@AttrRes int attr) {
|
||||||
|
TypedArray a = activity.getTheme().obtainStyledAttributes(new int[]{attr});
|
||||||
|
int attributeResourceId = a.getResourceId(0, 0);
|
||||||
|
a.recycle();
|
||||||
|
return attributeResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
|
// DisplayImageOptions default configurations
|
||||||
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
public static final DisplayImageOptions BASE_OPTIONS =
|
||||||
|
new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
||||||
|
|
||||||
|
public static final DisplayImageOptions DISPLAY_AVATAR_OPTIONS =
|
||||||
|
new DisplayImageOptions.Builder()
|
||||||
|
.cloneFrom(BASE_OPTIONS)
|
||||||
|
.showImageOnLoading(R.drawable.buddy)
|
||||||
|
.showImageForEmptyUri(R.drawable.buddy)
|
||||||
|
.showImageOnFail(R.drawable.buddy)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
public static final DisplayImageOptions DISPLAY_THUMBNAIL_OPTIONS =
|
||||||
|
new DisplayImageOptions.Builder()
|
||||||
|
.cloneFrom(BASE_OPTIONS)
|
||||||
|
.displayer(new FadeInBitmapDisplayer(250))
|
||||||
|
.showImageForEmptyUri(R.drawable.dummy_thumbnail)
|
||||||
|
.showImageOnFail(R.drawable.dummy_thumbnail)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
public static final DisplayImageOptions DISPLAY_BANNER_OPTIONS =
|
||||||
|
new DisplayImageOptions.Builder()
|
||||||
|
.cloneFrom(BASE_OPTIONS)
|
||||||
|
.showImageOnLoading(R.drawable.channel_banner)
|
||||||
|
.showImageForEmptyUri(R.drawable.channel_banner)
|
||||||
|
.showImageOnFail(R.drawable.channel_banner)
|
||||||
|
.build();
|
||||||
|
}
|
@@ -1,12 +1,15 @@
|
|||||||
package org.schabi.newpipe;
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
|
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
|
||||||
|
import org.schabi.newpipe.util.ExtractorHelper;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.InterruptedIOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -14,7 +17,7 @@ import java.util.Map;
|
|||||||
import javax.net.ssl.HttpsURLConnection;
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Created by Christian Schabesberger on 28.01.16.
|
* Created by Christian Schabesberger on 28.01.16.
|
||||||
*
|
*
|
||||||
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
||||||
@@ -35,16 +38,17 @@ import javax.net.ssl.HttpsURLConnection;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public class Downloader implements org.schabi.newpipe.extractor.Downloader {
|
public class Downloader implements org.schabi.newpipe.extractor.Downloader {
|
||||||
|
|
||||||
private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0";
|
public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0";
|
||||||
private static String mCookies = "";
|
private static String mCookies = "";
|
||||||
|
|
||||||
private static Downloader instance = null;
|
private static Downloader instance = null;
|
||||||
|
|
||||||
private Downloader() {}
|
private Downloader() {
|
||||||
|
}
|
||||||
|
|
||||||
public static Downloader getInstance() {
|
public static Downloader getInstance() {
|
||||||
if(instance == null) {
|
if (instance == null) {
|
||||||
synchronized (Downloader.class) {
|
synchronized (Downloader.class) {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new Downloader();
|
instance = new Downloader();
|
||||||
@@ -62,41 +66,66 @@ public class Downloader implements org.schabi.newpipe.extractor.Downloader {
|
|||||||
return Downloader.mCookies;
|
return Downloader.mCookies;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Download the text file at the supplied URL as in download(String),
|
/**
|
||||||
|
* Download the text file at the supplied URL as in download(String),
|
||||||
* but set the HTTP header field "Accept-Language" to the supplied string.
|
* but set the HTTP header field "Accept-Language" to the supplied string.
|
||||||
* @param siteUrl the URL of the text file to return the contents of
|
*
|
||||||
|
* @param siteUrl the URL of the text file to return the contents of
|
||||||
* @param language the language (usually a 2-character code) to set as the preferred language
|
* @param language the language (usually a 2-character code) to set as the preferred language
|
||||||
* @return the contents of the specified text file*/
|
* @return the contents of the specified text file
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
public String download(String siteUrl, String language) throws IOException, ReCaptchaException {
|
public String download(String siteUrl, String language) throws IOException, ReCaptchaException {
|
||||||
Map<String, String> requestProperties = new HashMap<>();
|
Map<String, String> requestProperties = new HashMap<>();
|
||||||
requestProperties.put("Accept-Language", language);
|
requestProperties.put("Accept-Language", language);
|
||||||
return download(siteUrl, requestProperties);
|
return download(siteUrl, requestProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/**Download the text file at the supplied URL as in download(String),
|
* Download the text file at the supplied URL as in download(String),
|
||||||
* but set the HTTP header field "Accept-Language" to the supplied string.
|
* but set the HTTP headers included in the customProperties map.
|
||||||
* @param siteUrl the URL of the text file to return the contents of
|
*
|
||||||
|
* @param siteUrl the URL of the text file to return the contents of
|
||||||
* @param customProperties set request header properties
|
* @param customProperties set request header properties
|
||||||
* @return the contents of the specified text file
|
* @return the contents of the specified text file
|
||||||
* @throws IOException*/
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
public String download(String siteUrl, Map<String, String> customProperties) throws IOException, ReCaptchaException {
|
public String download(String siteUrl, Map<String, String> customProperties) throws IOException, ReCaptchaException {
|
||||||
URL url = new URL(siteUrl);
|
URL url = new URL(siteUrl);
|
||||||
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
|
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
|
||||||
Iterator it = customProperties.entrySet().iterator();
|
Iterator it = customProperties.entrySet().iterator();
|
||||||
while(it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
Map.Entry pair = (Map.Entry)it.next();
|
Map.Entry pair = (Map.Entry) it.next();
|
||||||
con.setRequestProperty((String)pair.getKey(), (String)pair.getValue());
|
con.setRequestProperty((String) pair.getKey(), (String) pair.getValue());
|
||||||
}
|
}
|
||||||
return dl(con);
|
return dl(con);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Common functionality between download(String url) and download(String url, String language)*/
|
/**
|
||||||
|
* Download (via HTTP) the text file located at the supplied URL, and return its contents.
|
||||||
|
* Primarily intended for downloading web pages.
|
||||||
|
*
|
||||||
|
* @param siteUrl the URL of the text file to download
|
||||||
|
* @return the contents of the specified text file
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String download(String siteUrl) throws IOException, ReCaptchaException {
|
||||||
|
URL url = new URL(siteUrl);
|
||||||
|
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
|
||||||
|
//HttpsURLConnection con = NetCipher.getHttpsURLConnection(url);
|
||||||
|
return dl(con);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common functionality between download(String url) and download(String url, String language)
|
||||||
|
*/
|
||||||
private static String dl(HttpsURLConnection con) throws IOException, ReCaptchaException {
|
private static String dl(HttpsURLConnection con) throws IOException, ReCaptchaException {
|
||||||
StringBuilder response = new StringBuilder();
|
StringBuilder response = new StringBuilder();
|
||||||
BufferedReader in = null;
|
BufferedReader in = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
con.setReadTimeout(30 * 1000);// 30s
|
||||||
con.setRequestMethod("GET");
|
con.setRequestMethod("GET");
|
||||||
con.setRequestProperty("User-Agent", USER_AGENT);
|
con.setRequestProperty("User-Agent", USER_AGENT);
|
||||||
|
|
||||||
@@ -104,17 +133,19 @@ public class Downloader implements org.schabi.newpipe.extractor.Downloader {
|
|||||||
con.setRequestProperty("Cookie", getCookies());
|
con.setRequestProperty("Cookie", getCookies());
|
||||||
}
|
}
|
||||||
|
|
||||||
in = new BufferedReader(
|
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
|
||||||
new InputStreamReader(con.getInputStream()));
|
|
||||||
String inputLine;
|
|
||||||
|
|
||||||
while((inputLine = in.readLine()) != null) {
|
String inputLine;
|
||||||
|
while ((inputLine = in.readLine()) != null) {
|
||||||
response.append(inputLine);
|
response.append(inputLine);
|
||||||
}
|
}
|
||||||
} catch(UnknownHostException uhe) {//thrown when there's no internet connection
|
} catch (Exception e) {
|
||||||
throw new IOException("unknown host or no network", uhe);
|
Log.e("Downloader", "dl() ----- Exception thrown → " + e.getClass().getName());
|
||||||
//Toast.makeText(getActivity(), uhe.getMessage(), Toast.LENGTH_LONG).show();
|
|
||||||
} catch(Exception e) {
|
if (ExtractorHelper.isInterruptedCaused(e)) {
|
||||||
|
throw new InterruptedIOException(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HTTP 429 == Too Many Request
|
* HTTP 429 == Too Many Request
|
||||||
* Receive from Youtube.com = ReCaptcha challenge request
|
* Receive from Youtube.com = ReCaptcha challenge request
|
||||||
@@ -123,24 +154,14 @@ public class Downloader implements org.schabi.newpipe.extractor.Downloader {
|
|||||||
if (con.getResponseCode() == 429) {
|
if (con.getResponseCode() == 429) {
|
||||||
throw new ReCaptchaException("reCaptcha Challenge requested");
|
throw new ReCaptchaException("reCaptcha Challenge requested");
|
||||||
}
|
}
|
||||||
throw new IOException(e);
|
|
||||||
|
throw new IOException(con.getResponseCode() + " " + con.getResponseMessage(), e);
|
||||||
} finally {
|
} finally {
|
||||||
if(in != null) {
|
if (in != null) {
|
||||||
in.close();
|
in.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.toString();
|
return response.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Download (via HTTP) the text file located at the supplied URL, and return its contents.
|
|
||||||
* Primarily intended for downloading web pages.
|
|
||||||
* @param siteUrl the URL of the text file to download
|
|
||||||
* @return the contents of the specified text file*/
|
|
||||||
public String download(String siteUrl) throws IOException, ReCaptchaException {
|
|
||||||
URL url = new URL(siteUrl);
|
|
||||||
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
|
|
||||||
//HttpsURLConnection con = NetCipher.getHttpsURLConnection(url);
|
|
||||||
return dl(con);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,7 @@ import android.content.Intent;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Copyright (C) Hans-Christoph Steiner 2016 <hans@eds.org>
|
* Copyright (C) Hans-Christoph Steiner 2016 <hans@eds.org>
|
||||||
* ExitActivity.java is part of NewPipe.
|
* ExitActivity.java is part of NewPipe.
|
||||||
*
|
*
|
||||||
|
@@ -1,65 +0,0 @@
|
|||||||
package org.schabi.newpipe;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
|
||||||
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
|
||||||
import org.schabi.newpipe.report.UserAction;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Christian Schabesberger on 01.08.16.
|
|
||||||
*
|
|
||||||
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
|
||||||
* StreamInfoItemViewCreator.java is part of NewPipe.
|
|
||||||
*
|
|
||||||
* NewPipe is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* NewPipe is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class ImageErrorLoadingListener implements ImageLoadingListener {
|
|
||||||
|
|
||||||
private int serviceId = -1;
|
|
||||||
private Context context = null;
|
|
||||||
private View rootView = null;
|
|
||||||
|
|
||||||
public ImageErrorLoadingListener(Context context, View rootView, int serviceId) {
|
|
||||||
this.context = context;
|
|
||||||
this.serviceId= serviceId;
|
|
||||||
this.rootView = rootView;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadingStarted(String imageUri, View view) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
|
||||||
ErrorActivity.reportError(context,
|
|
||||||
failReason.getCause(), null, rootView,
|
|
||||||
ErrorActivity.ErrorInfo.make(UserAction.LOAD_IMAGE,
|
|
||||||
NewPipe.getNameOfService(serviceId), imageUri,
|
|
||||||
R.string.could_not_load_image));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadingCancelled(String imageUri, View view) {}
|
|
||||||
}
|
|
@@ -23,7 +23,11 @@ package org.schabi.newpipe;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v7.app.ActionBar;
|
import android.support.v7.app.ActionBar;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
@@ -34,19 +38,37 @@ import android.view.MenuInflater;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import org.schabi.newpipe.download.DownloadActivity;
|
import org.schabi.newpipe.database.AppDatabase;
|
||||||
|
import org.schabi.newpipe.database.history.dao.HistoryDAO;
|
||||||
|
import org.schabi.newpipe.database.history.dao.SearchHistoryDAO;
|
||||||
|
import org.schabi.newpipe.database.history.dao.WatchHistoryDAO;
|
||||||
|
import org.schabi.newpipe.database.history.model.HistoryEntry;
|
||||||
|
import org.schabi.newpipe.database.history.model.SearchHistoryEntry;
|
||||||
|
import org.schabi.newpipe.database.history.model.WatchHistoryEntry;
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
|
import org.schabi.newpipe.extractor.stream.AudioStream;
|
||||||
|
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||||
|
import org.schabi.newpipe.extractor.stream.VideoStream;
|
||||||
|
import org.schabi.newpipe.fragments.BackPressable;
|
||||||
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
|
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
|
||||||
import org.schabi.newpipe.fragments.search.SearchFragment;
|
import org.schabi.newpipe.fragments.list.search.SearchFragment;
|
||||||
import org.schabi.newpipe.settings.SettingsActivity;
|
import org.schabi.newpipe.history.HistoryListener;
|
||||||
import org.schabi.newpipe.util.Constants;
|
import org.schabi.newpipe.util.Constants;
|
||||||
import org.schabi.newpipe.util.NavigationHelper;
|
import org.schabi.newpipe.util.NavigationHelper;
|
||||||
import org.schabi.newpipe.util.PermissionHelper;
|
import org.schabi.newpipe.util.StateSaver;
|
||||||
import org.schabi.newpipe.util.ThemeHelper;
|
import org.schabi.newpipe.util.ThemeHelper;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
import java.util.Date;
|
||||||
|
|
||||||
|
import io.reactivex.disposables.Disposable;
|
||||||
|
import io.reactivex.functions.Consumer;
|
||||||
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
import io.reactivex.subjects.PublishSubject;
|
||||||
|
|
||||||
|
public class MainActivity extends AppCompatActivity implements HistoryListener {
|
||||||
private static final String TAG = "MainActivity";
|
private static final String TAG = "MainActivity";
|
||||||
public static final boolean DEBUG = false;
|
public static final boolean DEBUG = false;
|
||||||
|
private SharedPreferences sharedPreferences;
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
// Activity's LifeCycle
|
// Activity's LifeCycle
|
||||||
@@ -63,8 +85,21 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
initFragments();
|
initFragments();
|
||||||
}
|
}
|
||||||
|
|
||||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
|
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
|
||||||
|
initHistory();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
if (!isChangingConfigurations()) {
|
||||||
|
StateSaver.clearStateFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
disposeHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -75,7 +110,20 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
if (sharedPreferences.getBoolean(Constants.KEY_THEME_CHANGE, false)) {
|
if (sharedPreferences.getBoolean(Constants.KEY_THEME_CHANGE, false)) {
|
||||||
if (DEBUG) Log.d(TAG, "Theme has changed, recreating activity...");
|
if (DEBUG) Log.d(TAG, "Theme has changed, recreating activity...");
|
||||||
sharedPreferences.edit().putBoolean(Constants.KEY_THEME_CHANGE, false).apply();
|
sharedPreferences.edit().putBoolean(Constants.KEY_THEME_CHANGE, false).apply();
|
||||||
this.recreate();
|
// https://stackoverflow.com/questions/10844112/runtimeexception-performing-pause-of-activity-that-is-not-resumed
|
||||||
|
// Briefly, let the activity resume properly posting the recreate call to end of the message queue
|
||||||
|
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
MainActivity.this.recreate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sharedPreferences.getBoolean(Constants.KEY_MAIN_PAGE_CHANGE, false)) {
|
||||||
|
if (DEBUG) Log.d(TAG, "main page has changed, recreating main fragment...");
|
||||||
|
sharedPreferences.edit().putBoolean(Constants.KEY_MAIN_PAGE_CHANGE, false).apply();
|
||||||
|
NavigationHelper.openMainActivity(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -100,7 +148,10 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
if (DEBUG) Log.d(TAG, "onBackPressed() called");
|
if (DEBUG) Log.d(TAG, "onBackPressed() called");
|
||||||
|
|
||||||
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_holder);
|
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_holder);
|
||||||
if (fragment instanceof VideoDetailFragment) if (((VideoDetailFragment) fragment).onActivityBackPressed()) return;
|
// If current fragment implements BackPressable (i.e. can/wanna handle back press) delegate the back press to it
|
||||||
|
if (fragment instanceof BackPressable) {
|
||||||
|
if (((BackPressable) fragment).onBackPressed()) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
|
if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
|
||||||
@@ -131,7 +182,6 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
ActionBar actionBar = getSupportActionBar();
|
ActionBar actionBar = getSupportActionBar();
|
||||||
if (actionBar != null) {
|
if (actionBar != null) {
|
||||||
actionBar.setDisplayShowTitleEnabled(false);
|
|
||||||
actionBar.setDisplayHomeAsUpEnabled(false);
|
actionBar.setDisplayHomeAsUpEnabled(false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -143,20 +193,20 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case android.R.id.home: {
|
case android.R.id.home:
|
||||||
NavigationHelper.gotoMainFragment(getSupportFragmentManager());
|
NavigationHelper.gotoMainFragment(getSupportFragmentManager());
|
||||||
return true;
|
return true;
|
||||||
}
|
case R.id.action_settings:
|
||||||
case R.id.action_settings: {
|
|
||||||
NavigationHelper.openSettings(this);
|
NavigationHelper.openSettings(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
case R.id.action_show_downloads:
|
||||||
case R.id.action_show_downloads: {
|
|
||||||
return NavigationHelper.openDownloads(this);
|
return NavigationHelper.openDownloads(this);
|
||||||
}
|
|
||||||
case R.id.action_about:
|
case R.id.action_about:
|
||||||
NavigationHelper.openAbout(this);
|
NavigationHelper.openAbout(this);
|
||||||
return true;
|
return true;
|
||||||
|
case R.id.action_history:
|
||||||
|
NavigationHelper.openHistory(this);
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
@@ -167,6 +217,8 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
private void initFragments() {
|
private void initFragments() {
|
||||||
|
if (DEBUG) Log.d(TAG, "initFragments() called");
|
||||||
|
StateSaver.clearStateFiles();
|
||||||
if (getIntent() != null && getIntent().hasExtra(Constants.KEY_LINK_TYPE)) {
|
if (getIntent() != null && getIntent().hasExtra(Constants.KEY_LINK_TYPE)) {
|
||||||
handleIntent(getIntent());
|
handleIntent(getIntent());
|
||||||
} else NavigationHelper.gotoMainFragment(getSupportFragmentManager());
|
} else NavigationHelper.gotoMainFragment(getSupportFragmentManager());
|
||||||
@@ -191,6 +243,9 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
case CHANNEL:
|
case CHANNEL:
|
||||||
NavigationHelper.openChannelFragment(getSupportFragmentManager(), serviceId, url, title);
|
NavigationHelper.openChannelFragment(getSupportFragmentManager(), serviceId, url, title);
|
||||||
break;
|
break;
|
||||||
|
case PLAYLIST:
|
||||||
|
NavigationHelper.openPlaylistFragment(getSupportFragmentManager(), serviceId, url, title);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if (intent.hasExtra(Constants.KEY_OPEN_SEARCH)) {
|
} else if (intent.hasExtra(Constants.KEY_OPEN_SEARCH)) {
|
||||||
String searchQuery = intent.getStringExtra(Constants.KEY_QUERY);
|
String searchQuery = intent.getStringExtra(Constants.KEY_QUERY);
|
||||||
@@ -201,4 +256,75 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
NavigationHelper.gotoMainFragment(getSupportFragmentManager());
|
NavigationHelper.gotoMainFragment(getSupportFragmentManager());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
|
// History
|
||||||
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
private WatchHistoryDAO watchHistoryDAO;
|
||||||
|
private SearchHistoryDAO searchHistoryDAO;
|
||||||
|
private PublishSubject<HistoryEntry> historyEntrySubject;
|
||||||
|
private Disposable disposable;
|
||||||
|
|
||||||
|
private void initHistory() {
|
||||||
|
final AppDatabase database = NewPipeDatabase.getInstance();
|
||||||
|
watchHistoryDAO = database.watchHistoryDAO();
|
||||||
|
searchHistoryDAO = database.searchHistoryDAO();
|
||||||
|
historyEntrySubject = PublishSubject.create();
|
||||||
|
disposable = historyEntrySubject
|
||||||
|
.observeOn(Schedulers.io())
|
||||||
|
.subscribe(getHistoryEntryConsumer());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void disposeHistory() {
|
||||||
|
if (disposable != null) disposable.dispose();
|
||||||
|
watchHistoryDAO = null;
|
||||||
|
searchHistoryDAO = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private Consumer<HistoryEntry> getHistoryEntryConsumer() {
|
||||||
|
return new Consumer<HistoryEntry>() {
|
||||||
|
@Override
|
||||||
|
public void accept(HistoryEntry historyEntry) throws Exception {
|
||||||
|
//noinspection unchecked
|
||||||
|
HistoryDAO<HistoryEntry> historyDAO = (HistoryDAO<HistoryEntry>)
|
||||||
|
(historyEntry instanceof SearchHistoryEntry ? searchHistoryDAO : watchHistoryDAO);
|
||||||
|
|
||||||
|
HistoryEntry latestEntry = historyDAO.getLatestEntry();
|
||||||
|
if (historyEntry.hasEqualValues(latestEntry)) {
|
||||||
|
latestEntry.setCreationDate(historyEntry.getCreationDate());
|
||||||
|
historyDAO.update(latestEntry);
|
||||||
|
} else {
|
||||||
|
historyDAO.insert(historyEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addWatchHistoryEntry(StreamInfo streamInfo) {
|
||||||
|
if (sharedPreferences.getBoolean(getString(R.string.enable_watch_history_key), true)) {
|
||||||
|
WatchHistoryEntry entry = new WatchHistoryEntry(streamInfo);
|
||||||
|
historyEntrySubject.onNext(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVideoPlayed(StreamInfo streamInfo, @Nullable VideoStream videoStream) {
|
||||||
|
addWatchHistoryEntry(streamInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAudioPlayed(StreamInfo streamInfo, AudioStream audioStream) {
|
||||||
|
addWatchHistoryEntry(streamInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSearch(int serviceId, String query) {
|
||||||
|
// Add search history entry
|
||||||
|
if (sharedPreferences.getBoolean(getString(R.string.enable_search_history_key), true)) {
|
||||||
|
SearchHistoryEntry searchHistoryEntry = new SearchHistoryEntry(new Date(), serviceId, query);
|
||||||
|
historyEntrySubject.onNext(searchHistoryEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
31
app/src/main/java/org/schabi/newpipe/NewPipeDatabase.java
Normal file
31
app/src/main/java/org/schabi/newpipe/NewPipeDatabase.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
import android.arch.persistence.room.Room;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.database.AppDatabase;
|
||||||
|
|
||||||
|
import static org.schabi.newpipe.database.AppDatabase.DATABASE_NAME;
|
||||||
|
|
||||||
|
public final class NewPipeDatabase {
|
||||||
|
|
||||||
|
private static AppDatabase databaseInstance;
|
||||||
|
|
||||||
|
private NewPipeDatabase() {
|
||||||
|
//no instance
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void init(Context context) {
|
||||||
|
databaseInstance = Room.databaseBuilder(context.getApplicationContext(),
|
||||||
|
AppDatabase.class, DATABASE_NAME
|
||||||
|
).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static AppDatabase getInstance() {
|
||||||
|
if (databaseInstance == null) throw new RuntimeException("Database not initialized");
|
||||||
|
|
||||||
|
return databaseInstance;
|
||||||
|
}
|
||||||
|
}
|
@@ -6,9 +6,8 @@ import android.app.Activity;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.media.AudioManager;
|
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Copyright (C) Hans-Christoph Steiner 2016 <hans@eds.org>
|
* Copyright (C) Hans-Christoph Steiner 2016 <hans@eds.org>
|
||||||
* PanicResponderActivity.java is part of NewPipe.
|
* PanicResponderActivity.java is part of NewPipe.
|
||||||
*
|
*
|
||||||
|
@@ -16,7 +16,7 @@ import android.webkit.WebSettings;
|
|||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
import android.webkit.WebViewClient;
|
import android.webkit.WebViewClient;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Created by beneth <bmauduit@beneth.fr> on 06.12.16.
|
* Created by beneth <bmauduit@beneth.fr> on 06.12.16.
|
||||||
*
|
*
|
||||||
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
||||||
@@ -49,7 +49,7 @@ public class ReCaptchaActivity extends AppCompatActivity {
|
|||||||
// Set return to Cancel by default
|
// Set return to Cancel by default
|
||||||
setResult(RESULT_CANCELED);
|
setResult(RESULT_CANCELED);
|
||||||
|
|
||||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
ActionBar actionBar = getSupportActionBar();
|
ActionBar actionBar = getSupportActionBar();
|
||||||
@@ -59,7 +59,7 @@ public class ReCaptchaActivity extends AppCompatActivity {
|
|||||||
actionBar.setDisplayShowTitleEnabled(true);
|
actionBar.setDisplayShowTitleEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebView myWebView = (WebView) findViewById(R.id.reCaptchaWebView);
|
WebView myWebView = findViewById(R.id.reCaptchaWebView);
|
||||||
|
|
||||||
// Enable Javascript
|
// Enable Javascript
|
||||||
WebSettings webSettings = myWebView.getSettings();
|
WebSettings webSettings = myWebView.getSettings();
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
package org.schabi.newpipe;
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.schabi.newpipe.util.NavigationHelper;
|
import org.schabi.newpipe.util.NavigationHelper;
|
||||||
@@ -10,29 +10,29 @@ import org.schabi.newpipe.util.NavigationHelper;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
||||||
* RouterActivity .java is part of NewPipe.
|
* RouterActivity.java is part of NewPipe.
|
||||||
*
|
*
|
||||||
* OpenHitboxStreams is free software: you can redistribute it and/or modify
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* OpenHitboxStreams is distributed in the hope that it will be useful,
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with OpenHitboxStreams. If not, see <http://www.gnu.org/licenses/>.
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This Acitivty is designed to route share/open intents to the specified service, and
|
* This Acitivty is designed to route share/open intents to the specified service, and
|
||||||
* to the part of the service which can handle the url.
|
* to the part of the service which can handle the url.
|
||||||
*/
|
*/
|
||||||
public class RouterActivity extends Activity {
|
public class RouterActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -40,16 +40,15 @@ public class RouterActivity extends Activity {
|
|||||||
|
|
||||||
String videoUrl = getUrl(getIntent());
|
String videoUrl = getUrl(getIntent());
|
||||||
handleUrl(videoUrl);
|
handleUrl(videoUrl);
|
||||||
|
|
||||||
finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handleUrl(String url) {
|
protected void handleUrl(String url) {
|
||||||
try {
|
boolean success = NavigationHelper.openByLink(this, url);
|
||||||
NavigationHelper.openByLink(this, url);
|
if (!success) {
|
||||||
} catch (Exception e) {
|
|
||||||
Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show();
|
Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
|
@@ -6,6 +6,7 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
import org.schabi.newpipe.player.PopupVideoPlayer;
|
import org.schabi.newpipe.player.PopupVideoPlayer;
|
||||||
import org.schabi.newpipe.util.Constants;
|
import org.schabi.newpipe.util.Constants;
|
||||||
import org.schabi.newpipe.util.PermissionHelper;
|
import org.schabi.newpipe.util.PermissionHelper;
|
||||||
@@ -20,10 +21,13 @@ public class RouterPopupActivity extends RouterActivity {
|
|||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||||
&& !PermissionHelper.checkSystemAlertWindowPermission(this)) {
|
&& !PermissionHelper.checkSystemAlertWindowPermission(this)) {
|
||||||
Toast.makeText(this, R.string.msg_popup_permission, Toast.LENGTH_LONG).show();
|
Toast.makeText(this, R.string.msg_popup_permission, Toast.LENGTH_LONG).show();
|
||||||
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StreamingService service = NewPipe.getServiceByUrl(url);
|
StreamingService service;
|
||||||
if (service == null) {
|
try {
|
||||||
|
service = NewPipe.getServiceByUrl(url);
|
||||||
|
} catch (ExtractionException e) {
|
||||||
Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show();
|
Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -40,5 +44,7 @@ public class RouterPopupActivity extends RouterActivity {
|
|||||||
callIntent.putExtra(Constants.KEY_URL, url);
|
callIntent.putExtra(Constants.KEY_URL, url);
|
||||||
callIntent.putExtra(Constants.KEY_SERVICE_ID, service.getServiceId());
|
callIntent.putExtra(Constants.KEY_SERVICE_ID, service.getServiceId());
|
||||||
startService(callIntent);
|
startService(callIntent);
|
||||||
|
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -36,11 +36,13 @@ public class AboutActivity extends AppCompatActivity {
|
|||||||
new SoftwareComponent("Rhino", "2015", "Mozilla", "https://www.mozilla.org/rhino/", StandardLicenses.MPL2),
|
new SoftwareComponent("Rhino", "2015", "Mozilla", "https://www.mozilla.org/rhino/", StandardLicenses.MPL2),
|
||||||
new SoftwareComponent("ACRA", "2013", "Kevin Gaudin", "http://www.acra.ch", StandardLicenses.APACHE2),
|
new SoftwareComponent("ACRA", "2013", "Kevin Gaudin", "http://www.acra.ch", StandardLicenses.APACHE2),
|
||||||
new SoftwareComponent("Universal Image Loader", "2011 - 2015", "Sergey Tarasevich", "https://github.com/nostra13/Android-Universal-Image-Loader", StandardLicenses.APACHE2),
|
new SoftwareComponent("Universal Image Loader", "2011 - 2015", "Sergey Tarasevich", "https://github.com/nostra13/Android-Universal-Image-Loader", StandardLicenses.APACHE2),
|
||||||
new SoftwareComponent("Netcipher", "2015", "The Guardian Project", "https://guardianproject.info/code/netcipher/", StandardLicenses.APACHE2),
|
|
||||||
new SoftwareComponent("CircleImageView", "2014 - 2017", "Henning Dodenhof", "https://github.com/hdodenhof/CircleImageView", StandardLicenses.APACHE2),
|
new SoftwareComponent("CircleImageView", "2014 - 2017", "Henning Dodenhof", "https://github.com/hdodenhof/CircleImageView", StandardLicenses.APACHE2),
|
||||||
new SoftwareComponent("ParalaxScrollView", "2014", "Nir Hartmann", "https://github.com/nirhart/ParallaxScroll", StandardLicenses.MIT),
|
new SoftwareComponent("ParalaxScrollView", "2014", "Nir Hartmann", "https://github.com/nirhart/ParallaxScroll", StandardLicenses.MIT),
|
||||||
new SoftwareComponent("NoNonsense-FilePicker", "2016", "Jonas Kalderstam", "https://github.com/spacecowboy/NoNonsense-FilePicker", StandardLicenses.MPL2),
|
new SoftwareComponent("NoNonsense-FilePicker", "2016", "Jonas Kalderstam", "https://github.com/spacecowboy/NoNonsense-FilePicker", StandardLicenses.MPL2),
|
||||||
new SoftwareComponent("ExoPlayer", "2014-2017", "Google Inc", "https://github.com/google/ExoPlayer", StandardLicenses.APACHE2)
|
new SoftwareComponent("ExoPlayer", "2014-2017", "Google Inc", "https://github.com/google/ExoPlayer", StandardLicenses.APACHE2),
|
||||||
|
new SoftwareComponent("RxAndroid", "2015", "The RxAndroid authors", "https://github.com/ReactiveX/RxAndroid", StandardLicenses.APACHE2),
|
||||||
|
new SoftwareComponent("RxJava", "2016-present", "RxJava Contributors", "https://github.com/ReactiveX/RxJava", StandardLicenses.APACHE2),
|
||||||
|
new SoftwareComponent("RxBinding", "2015", "Jake Wharton", "https://github.com/JakeWharton/RxBinding", StandardLicenses.APACHE2)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,7 +67,7 @@ public class AboutActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
setContentView(R.layout.activity_about);
|
setContentView(R.layout.activity_about);
|
||||||
|
|
||||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
// Create the adapter that will return a fragment for each of the three
|
// Create the adapter that will return a fragment for each of the three
|
||||||
@@ -73,10 +75,10 @@ public class AboutActivity extends AppCompatActivity {
|
|||||||
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
|
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
|
||||||
|
|
||||||
// Set up the ViewPager with the sections adapter.
|
// Set up the ViewPager with the sections adapter.
|
||||||
mViewPager = (ViewPager) findViewById(R.id.container);
|
mViewPager = findViewById(R.id.container);
|
||||||
mViewPager.setAdapter(mSectionsPagerAdapter);
|
mViewPager.setAdapter(mSectionsPagerAdapter);
|
||||||
|
|
||||||
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
|
TabLayout tabLayout = findViewById(R.id.tabs);
|
||||||
tabLayout.setupWithViewPager(mViewPager);
|
tabLayout.setupWithViewPager(mViewPager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,14 +129,18 @@ public class AboutActivity extends AppCompatActivity {
|
|||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View rootView = inflater.inflate(R.layout.fragment_about, container, false);
|
View rootView = inflater.inflate(R.layout.fragment_about, container, false);
|
||||||
TextView version = (TextView) rootView.findViewById(R.id.app_version);
|
TextView version = rootView.findViewById(R.id.app_version);
|
||||||
version.setText(BuildConfig.VERSION_NAME);
|
version.setText(BuildConfig.VERSION_NAME);
|
||||||
|
|
||||||
View githubLink = rootView.findViewById(R.id.github_link);
|
View githubLink = rootView.findViewById(R.id.github_link);
|
||||||
githubLink.setOnClickListener(new OnGithubLinkClickListener());
|
githubLink.setOnClickListener(new OnGithubLinkClickListener());
|
||||||
|
|
||||||
View licenseLink = rootView.findViewById(R.id.app_read_license);
|
View donationLink = rootView.findViewById(R.id.donation_link);
|
||||||
licenseLink.setOnClickListener(new OnReadFullLicenseClickListener());
|
donationLink.setOnClickListener(new OnDonationLinkClickListener());
|
||||||
|
|
||||||
|
View websiteLink = rootView.findViewById(R.id.website_link);
|
||||||
|
websiteLink.setOnClickListener(new OnWebsiteLinkClickListener());
|
||||||
|
|
||||||
return rootView;
|
return rootView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,10 +153,21 @@ public class AboutActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class OnReadFullLicenseClickListener implements View.OnClickListener {
|
private static class OnDonationLinkClickListener implements View.OnClickListener {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(final View view) {
|
||||||
LicenseFragment.showLicense(v.getContext(), StandardLicenses.GPL3);
|
final Context context = view.getContext();
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(context.getString(R.string.donation_url)));
|
||||||
|
context.startActivity(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class OnWebsiteLinkClickListener implements View.OnClickListener {
|
||||||
|
@Override
|
||||||
|
public void onClick(final View view) {
|
||||||
|
final Context context = view.getContext();
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(context.getString(R.string.website_url)));
|
||||||
|
context.startActivity(intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user