mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2025-09-22 21:40:52 +02:00
Compare commits
593 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a72d37ab69 | ||
![]() |
f92227e5df | ||
![]() |
c50617452f | ||
![]() |
3957eca94d | ||
![]() |
70111cf614 | ||
![]() |
f9e03c9a40 | ||
![]() |
88fbdf1cc4 | ||
![]() |
7b76bd79e8 | ||
![]() |
f4b58e649d | ||
![]() |
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 | ||
![]() |
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 | ||
![]() |
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
|
||||
===============================
|
||||
|
||||
READ THIS GUIDELINES CAREFULLY BEFORE CONTRIBUTING.
|
||||
PLEASE READ THESE GUIDELINES CAREFULLY BEFORE ANY CONTRIBUTION!
|
||||
|
||||
## 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
|
||||
* Check if this issue/feature is already fixed/implemented in the repository
|
||||
* If you are an android/java developer you are always welcome to fix/implement an issue/a feature yourself
|
||||
* Use english
|
||||
* Search the [existing issues](https://github.com/TeamNewPipe/NewPipe/issues) first to make sure your issue/feature hasn't been reported/requested before
|
||||
* 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. PRs welcome!
|
||||
* 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
|
||||
* 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.
|
||||
## Bug Fixing
|
||||
* 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
|
||||
|
||||
* 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
|
||||
|
||||
* Stick to NewPipe style guidelines (just look the other code and than do it the same way :) )
|
||||
* Do not bring nonfree software/binary blobs into the project (keep it google free)
|
||||
* 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)
|
||||
* When submitting changes, you agree that your code will be licensed under GPLv3
|
||||
* Please test (compile and run) your code before you submit changes!!!
|
||||
* Try to figure out you selves why CI fails, or why a merge request collides
|
||||
* Please maintain your code after you contributed it.
|
||||
* Respond yourselves if someone request changes or notifies issues
|
||||
* Stick to NewPipe's style conventions (well, just look the other code and then do it the same way :))
|
||||
* 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)
|
||||
* 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 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! Ideally, provide test feedback in the PR description. Untested code will **not** be merged!
|
||||
* Try to figure out yourself why builds on our CI fail.
|
||||
* 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.
|
||||
* 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
|
||||
|
||||
* 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
|
||||
* Feel free to post suggestions, changes, ideas etc!
|
||||
* 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)!
|
||||
* 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
|
||||
|
@@ -5,16 +5,12 @@ android:
|
||||
components:
|
||||
# The BuildTools version used by NewPipe
|
||||
- tools
|
||||
- build-tools-25.0.2
|
||||
- build-tools-27.0.1
|
||||
|
||||
# The SDK version used to compile NewPipe
|
||||
- android-25
|
||||
|
||||
# Additional components
|
||||
- extra-android-m2repository
|
||||
- android-27
|
||||
|
||||
script: ./gradlew -Dorg.gradle.jvmargs=-Xmx1536m assembleDebug lintDebug testDebugUnitTest
|
||||
|
||||
licenses:
|
||||
- '.+'
|
||||
|
||||
|
87
README.md
87
README.md
@@ -1,34 +1,33 @@
|
||||
<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>
|
||||
<hr />
|
||||
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
|
||||
|
||||
[<img src="screenshots/screenshot_1.png" width=160>](screenshots/screenshot_1.png)
|
||||
[<img src="screenshots/screenshot_2.png" width=160>](screenshots/screenshot_2.png)
|
||||
[<img src="screenshots/screenshot_3.png" width=160>](screenshots/screenshot_3.png)
|
||||
[<img src="screenshots/screenshot_4.png" width=160>](screenshots/screenshot_4.png)
|
||||
[<img src="screenshots/screenshot_5.png" width=160>](screenshots/screenshot_5.png)
|
||||
[<img src="screenshots/screenshot_6.png" width=160>](screenshots/screenshot_6.png)
|
||||
[<img src="screenshots/screenshot_7.png" width=160>](screenshots/screenshot_7.png)
|
||||
[<img src="screenshots/screenshot_8.png" width=160>](screenshots/screenshot_8.png)
|
||||
[<img src="screenshots/screenshot_9.png" width=160>](screenshots/screenshot_9.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="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_2.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_2.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="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_4.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_4.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="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_6.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_6.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="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_8.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_8.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
|
||||
|
||||
@@ -39,7 +38,7 @@ NewPipe does not use any Google framework libraries, or the YouTube API. It only
|
||||
* Search videos
|
||||
* Display general information about a video
|
||||
* Watch YouTube videos
|
||||
* Listen to YouTube videos (experimental)
|
||||
* Listen to YouTube videos
|
||||
* Popup mode (floating player)
|
||||
* Select the streaming player to watch the video with
|
||||
* Download videos
|
||||
@@ -47,21 +46,23 @@ NewPipe does not use any Google framework libraries, or the YouTube API. It only
|
||||
* Open a video in Kodi
|
||||
* Show Next/Related videos
|
||||
* Search YouTube in a specific language
|
||||
* Watch age restricted material
|
||||
* Watch/Block age restricted material
|
||||
* Display general information about channels
|
||||
* Search channels
|
||||
* Watch videos from a channel
|
||||
* Orbot/Tor support (not yet directly)
|
||||
* 1080p/2k/4k support
|
||||
* View history
|
||||
* Subscribe to channels
|
||||
* Search history
|
||||
* Search/Watch Playlists
|
||||
* Watch as queues Playlists
|
||||
* Queuing videos
|
||||
|
||||
### Coming Features
|
||||
|
||||
* Multiservice support (eg. SoundCloud)
|
||||
* Bookmarks
|
||||
* View history
|
||||
* Search history
|
||||
* Subscribe to channels
|
||||
* Search/Watch Playlists
|
||||
* Queeing videos
|
||||
* Subtitles support
|
||||
* livestream support
|
||||
* ... and many more
|
||||
@@ -70,11 +71,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.
|
||||
|
||||
## 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!
|
||||
|
||||
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
|
||||
[](http://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
||||
|
@@ -1,23 +1,38 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 25
|
||||
buildToolsVersion '25.0.2'
|
||||
compileSdkVersion 27
|
||||
buildToolsVersion '27.0.1'
|
||||
|
||||
defaultConfig {
|
||||
applicationId "org.schabi.newpipe"
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 25
|
||||
versionCode 37
|
||||
versionName "0.9.10"
|
||||
targetSdkVersion 27
|
||||
versionCode 42
|
||||
versionName "0.11.1"
|
||||
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
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 {
|
||||
@@ -33,29 +48,42 @@ android {
|
||||
}
|
||||
|
||||
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'
|
||||
}
|
||||
|
||||
implementation 'com.github.TeamNewPipe:NewPipeExtractor:17ce9f537e8df'
|
||||
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'org.mockito:mockito-core:1.10.19'
|
||||
testCompile 'org.json:json:20160810'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
testImplementation 'org.mockito:mockito-core:1.10.19'
|
||||
|
||||
compile 'com.android.support:appcompat-v7:25.3.1'
|
||||
compile 'com.android.support:support-v4:25.3.1'
|
||||
compile 'com.android.support:design:25.3.1'
|
||||
compile 'com.android.support:recyclerview-v7:25.3.1'
|
||||
implementation 'com.android.support:appcompat-v7:27.0.1'
|
||||
implementation 'com.android.support:support-v4:27.0.1'
|
||||
implementation 'com.android.support:design:27.0.1'
|
||||
implementation 'com.android.support:recyclerview-v7:27.0.1'
|
||||
implementation 'com.android.support:preference-v14:27.0.1'
|
||||
|
||||
compile 'com.google.code.gson:gson:2.7'
|
||||
compile 'org.jsoup:jsoup:1.8.3'
|
||||
compile 'org.mozilla:rhino:1.7.7'
|
||||
compile 'ch.acra:acra:4.9.0'
|
||||
compile 'info.guardianproject.netcipher:netcipher:1.2'
|
||||
implementation 'com.google.code.gson:gson:2.8.2'
|
||||
implementation 'ch.acra:acra:4.9.2'
|
||||
|
||||
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
|
||||
compile 'de.hdodenhof:circleimageview:2.0.0'
|
||||
compile 'com.github.nirhart:parallaxscroll:1.0'
|
||||
compile 'com.nononsenseapps:filepicker:3.0.0'
|
||||
compile 'com.google.android.exoplayer:exoplayer:r2.4.2'
|
||||
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
|
||||
implementation 'de.hdodenhof:circleimageview:2.2.0'
|
||||
implementation 'com.github.nirhart:ParallaxScroll:dd53d1f9d1'
|
||||
implementation 'com.nononsenseapps:filepicker:3.0.1'
|
||||
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.6'
|
||||
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 {
|
||||
# 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:label="@string/app_name"
|
||||
android:logo="@mipmap/ic_launcher"
|
||||
android:theme="@style/AppTheme"
|
||||
android:theme="@style/DarkTheme"
|
||||
tools:ignore="AllowBackup">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name">
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
@@ -28,7 +29,7 @@
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".player.PlayVideoActivity"
|
||||
android:name=".player.old.PlayVideoActivity"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:theme="@style/VideoPlayerTheme"
|
||||
tools:ignore="UnusedAttribute"/>
|
||||
@@ -37,6 +38,16 @@
|
||||
android:name=".player.BackgroundPlayer"
|
||||
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
|
||||
android:name=".player.PopupVideoPlayer"
|
||||
android:exported="false"/>
|
||||
@@ -51,6 +62,15 @@
|
||||
<activity
|
||||
android:name=".settings.SettingsActivity"
|
||||
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
|
||||
android:name=".PanicResponderActivity"
|
||||
android:launchMode="singleInstance"
|
||||
@@ -62,6 +82,7 @@
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".ExitActivity"
|
||||
android:label="@string/general_error"
|
||||
@@ -72,16 +93,20 @@
|
||||
<activity
|
||||
android:name=".download.DownloadActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/AppTheme"/>
|
||||
android:launchMode="singleTask"/>
|
||||
|
||||
<service android:name="us.shandian.giga.service.DownloadManagerService"/>
|
||||
|
||||
<activity
|
||||
android:name="com.nononsenseapps.filepicker.FilePickerActivity"
|
||||
android:name=".util.FilePickerActivityHelper"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/FilePickerTheme"/>
|
||||
android:theme="@style/FilePickerThemeDark">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.GET_CONTENT" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".ReCaptchaActivity"
|
||||
android:label="@string/reCaptchaActivity"/>
|
||||
@@ -121,6 +146,8 @@
|
||||
<!-- channel prefix -->
|
||||
<data android:pathPrefix="/channel/"/>
|
||||
<data android:pathPrefix="/user/"/>
|
||||
<!-- playlist prefix -->
|
||||
<data android:pathPrefix="/playlist"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
@@ -154,12 +181,11 @@
|
||||
<data android:mimeType="text/plain"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".RouterPopupActivity"
|
||||
android:label="@string/popup_mode_share_menu_title"
|
||||
android:taskAffinity=""
|
||||
android:theme="@android:style/Theme.NoDisplay"
|
||||
android:label="@string/popup_mode_share_menu_title">
|
||||
android:theme="@style/PopupPermissionsTheme">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
|
||||
@@ -209,11 +235,5 @@
|
||||
<data android:mimeType="text/plain"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".about.AboutActivity"
|
||||
android:label="@string/title_activity_about"
|
||||
android:theme="@style/AppTheme">
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
@@ -15,9 +15,9 @@ Version 2, June 1991
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.<br/>
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA<br/>
|
||||
<br/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
</pre>
|
||||
|
@@ -4,6 +4,7 @@
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Mozilla Public License, version 2.0</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="mozilla-public-license-version-2.0">Mozilla Public License<br>Version 2.0</h1>
|
||||
<h2 id="definitions">1. Definitions</h2>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
package org.schabi.newpipe;
|
||||
|
||||
/**
|
||||
/*
|
||||
* Created by Christian Schabesberger on 24.12.15.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
||||
|
@@ -1,7 +1,11 @@
|
||||
package org.schabi.newpipe;
|
||||
|
||||
import android.app.Application;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
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.UserAction;
|
||||
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 info.guardianproject.netcipher.proxy.OrbotHelper;
|
||||
import java.io.IOException;
|
||||
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>
|
||||
* App.java is part of NewPipe.
|
||||
*
|
||||
@@ -40,73 +52,101 @@ import info.guardianproject.netcipher.proxy.OrbotHelper;
|
||||
*/
|
||||
|
||||
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
|
||||
= new Class[]{AcraReportSenderFactory.class};
|
||||
@Override
|
||||
protected void attachBaseContext(Context base) {
|
||||
super.attachBaseContext(base);
|
||||
|
||||
initACRA();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
// init crashreport
|
||||
try {
|
||||
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));
|
||||
}
|
||||
// Initialize settings first because others inits can use its values
|
||||
SettingsActivity.initSettings(this);
|
||||
|
||||
//init NewPipe
|
||||
NewPipe.init(Downloader.getInstance());
|
||||
NewPipeDatabase.init(this);
|
||||
StateSaver.init(this);
|
||||
initNotificationChannel();
|
||||
|
||||
// Initialize image loader
|
||||
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this).build();
|
||||
ImageLoader.getInstance().init(config);
|
||||
|
||||
/*
|
||||
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());
|
||||
configureRxJavaErrorHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the proxy settings based on whether Tor should be enabled or not.
|
||||
*/
|
||||
public static void configureTor(boolean enabled) {
|
||||
useTor = enabled;
|
||||
if (useTor) {
|
||||
NetCipher.useTor();
|
||||
} else {
|
||||
NetCipher.setProxy(null);
|
||||
private void configureRxJavaErrorHandler() {
|
||||
// https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling
|
||||
RxJavaPlugins.setErrorHandler(new Consumer<Throwable>() {
|
||||
@Override
|
||||
public void accept(@NonNull Throwable throwable) throws Exception {
|
||||
Log.e(TAG, "RxJavaPlugins.ErrorHandler called with -> : throwable = [" + throwable.getClass().getName() + "]");
|
||||
|
||||
if (throwable instanceof UndeliverableException) {
|
||||
// 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) {
|
||||
if (useTor) {
|
||||
OrbotHelper.requestStartTor(context);
|
||||
public void initNotificationChannel() {
|
||||
if (Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isUsingTor() {
|
||||
return useTor;
|
||||
final String id = getString(R.string.notification_channel_id);
|
||||
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;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
|
||||
import org.schabi.newpipe.util.ExtractorHelper;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
@@ -14,7 +17,7 @@ import java.util.Map;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* Created by Christian Schabesberger on 28.01.16.
|
||||
*
|
||||
* 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 {
|
||||
|
||||
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 Downloader instance = null;
|
||||
|
||||
private Downloader() {}
|
||||
private Downloader() {
|
||||
}
|
||||
|
||||
public static Downloader getInstance() {
|
||||
if(instance == null) {
|
||||
if (instance == null) {
|
||||
synchronized (Downloader.class) {
|
||||
if (instance == null) {
|
||||
instance = new Downloader();
|
||||
@@ -62,41 +66,66 @@ public class Downloader implements org.schabi.newpipe.extractor.Downloader {
|
||||
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.
|
||||
* @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
|
||||
* @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 {
|
||||
Map<String, String> requestProperties = new HashMap<>();
|
||||
requestProperties.put("Accept-Language", language);
|
||||
return download(siteUrl, requestProperties);
|
||||
}
|
||||
|
||||
|
||||
/**Download the text file at the supplied URL as in download(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
|
||||
/**
|
||||
* Download the text file at the supplied URL as in download(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 customProperties set request header properties
|
||||
* @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 {
|
||||
URL url = new URL(siteUrl);
|
||||
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
|
||||
Iterator it = customProperties.entrySet().iterator();
|
||||
while(it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
con.setRequestProperty((String)pair.getKey(), (String)pair.getValue());
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry) it.next();
|
||||
con.setRequestProperty((String) pair.getKey(), (String) pair.getValue());
|
||||
}
|
||||
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 {
|
||||
StringBuilder response = new StringBuilder();
|
||||
BufferedReader in = null;
|
||||
|
||||
try {
|
||||
con.setReadTimeout(30 * 1000);// 30s
|
||||
con.setRequestMethod("GET");
|
||||
con.setRequestProperty("User-Agent", USER_AGENT);
|
||||
|
||||
@@ -104,17 +133,19 @@ public class Downloader implements org.schabi.newpipe.extractor.Downloader {
|
||||
con.setRequestProperty("Cookie", getCookies());
|
||||
}
|
||||
|
||||
in = new BufferedReader(
|
||||
new InputStreamReader(con.getInputStream()));
|
||||
String inputLine;
|
||||
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
|
||||
|
||||
while((inputLine = in.readLine()) != null) {
|
||||
String inputLine;
|
||||
while ((inputLine = in.readLine()) != null) {
|
||||
response.append(inputLine);
|
||||
}
|
||||
} catch(UnknownHostException uhe) {//thrown when there's no internet connection
|
||||
throw new IOException("unknown host or no network", uhe);
|
||||
//Toast.makeText(getActivity(), uhe.getMessage(), Toast.LENGTH_LONG).show();
|
||||
} catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
Log.e("Downloader", "dl() ----- Exception thrown → " + e.getClass().getName());
|
||||
|
||||
if (ExtractorHelper.isInterruptedCaused(e)) {
|
||||
throw new InterruptedIOException(e.getMessage());
|
||||
}
|
||||
|
||||
/*
|
||||
* HTTP 429 == Too Many 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) {
|
||||
throw new ReCaptchaException("reCaptcha Challenge requested");
|
||||
}
|
||||
throw new IOException(e);
|
||||
|
||||
throw new IOException(con.getResponseCode() + " " + con.getResponseMessage(), e);
|
||||
} finally {
|
||||
if(in != null) {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
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.Bundle;
|
||||
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) Hans-Christoph Steiner 2016 <hans@eds.org>
|
||||
* 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.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
@@ -34,19 +38,37 @@ import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
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.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.search.SearchFragment;
|
||||
import org.schabi.newpipe.settings.SettingsActivity;
|
||||
import org.schabi.newpipe.fragments.list.search.SearchFragment;
|
||||
import org.schabi.newpipe.history.HistoryListener;
|
||||
import org.schabi.newpipe.util.Constants;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
import org.schabi.newpipe.util.PermissionHelper;
|
||||
import org.schabi.newpipe.util.StateSaver;
|
||||
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";
|
||||
public static final boolean DEBUG = false;
|
||||
private SharedPreferences sharedPreferences;
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Activity's LifeCycle
|
||||
@@ -63,8 +85,21 @@ public class MainActivity extends AppCompatActivity {
|
||||
initFragments();
|
||||
}
|
||||
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
initHistory();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (!isChangingConfigurations()) {
|
||||
StateSaver.clearStateFiles();
|
||||
}
|
||||
|
||||
disposeHistory();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -75,7 +110,20 @@ public class MainActivity extends AppCompatActivity {
|
||||
if (sharedPreferences.getBoolean(Constants.KEY_THEME_CHANGE, false)) {
|
||||
if (DEBUG) Log.d(TAG, "Theme has changed, recreating activity...");
|
||||
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");
|
||||
|
||||
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) {
|
||||
@@ -131,7 +182,6 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayShowTitleEnabled(false);
|
||||
actionBar.setDisplayHomeAsUpEnabled(false);
|
||||
}
|
||||
return true;
|
||||
@@ -143,20 +193,20 @@ public class MainActivity extends AppCompatActivity {
|
||||
int id = item.getItemId();
|
||||
|
||||
switch (id) {
|
||||
case android.R.id.home: {
|
||||
case android.R.id.home:
|
||||
NavigationHelper.gotoMainFragment(getSupportFragmentManager());
|
||||
return true;
|
||||
}
|
||||
case R.id.action_settings: {
|
||||
case R.id.action_settings:
|
||||
NavigationHelper.openSettings(this);
|
||||
return true;
|
||||
}
|
||||
case R.id.action_show_downloads: {
|
||||
case R.id.action_show_downloads:
|
||||
return NavigationHelper.openDownloads(this);
|
||||
}
|
||||
case R.id.action_about:
|
||||
NavigationHelper.openAbout(this);
|
||||
return true;
|
||||
case R.id.action_history:
|
||||
NavigationHelper.openHistory(this);
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
@@ -167,6 +217,8 @@ public class MainActivity extends AppCompatActivity {
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
private void initFragments() {
|
||||
if (DEBUG) Log.d(TAG, "initFragments() called");
|
||||
StateSaver.clearStateFiles();
|
||||
if (getIntent() != null && getIntent().hasExtra(Constants.KEY_LINK_TYPE)) {
|
||||
handleIntent(getIntent());
|
||||
} else NavigationHelper.gotoMainFragment(getSupportFragmentManager());
|
||||
@@ -191,6 +243,9 @@ public class MainActivity extends AppCompatActivity {
|
||||
case CHANNEL:
|
||||
NavigationHelper.openChannelFragment(getSupportFragmentManager(), serviceId, url, title);
|
||||
break;
|
||||
case PLAYLIST:
|
||||
NavigationHelper.openPlaylistFragment(getSupportFragmentManager(), serviceId, url, title);
|
||||
break;
|
||||
}
|
||||
} else if (intent.hasExtra(Constants.KEY_OPEN_SEARCH)) {
|
||||
String searchQuery = intent.getStringExtra(Constants.KEY_QUERY);
|
||||
@@ -201,4 +256,75 @@ public class MainActivity extends AppCompatActivity {
|
||||
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.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.media.AudioManager;
|
||||
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) Hans-Christoph Steiner 2016 <hans@eds.org>
|
||||
* PanicResponderActivity.java is part of NewPipe.
|
||||
*
|
||||
|
@@ -16,7 +16,7 @@ import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
|
||||
/**
|
||||
/*
|
||||
* Created by beneth <bmauduit@beneth.fr> on 06.12.16.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
||||
@@ -49,7 +49,7 @@ public class ReCaptchaActivity extends AppCompatActivity {
|
||||
// Set return to Cancel by default
|
||||
setResult(RESULT_CANCELED);
|
||||
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
@@ -59,7 +59,7 @@ public class ReCaptchaActivity extends AppCompatActivity {
|
||||
actionBar.setDisplayShowTitleEnabled(true);
|
||||
}
|
||||
|
||||
WebView myWebView = (WebView) findViewById(R.id.reCaptchaWebView);
|
||||
WebView myWebView = findViewById(R.id.reCaptchaWebView);
|
||||
|
||||
// Enable Javascript
|
||||
WebSettings webSettings = myWebView.getSettings();
|
||||
|
@@ -1,8 +1,8 @@
|
||||
package org.schabi.newpipe;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
@@ -10,29 +10,29 @@ import org.schabi.newpipe.util.NavigationHelper;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
/*
|
||||
/**
|
||||
* 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (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
|
||||
* 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 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
|
||||
* to the part of the service which can handle the url.
|
||||
*/
|
||||
public class RouterActivity extends Activity {
|
||||
public class RouterActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@@ -40,16 +40,15 @@ public class RouterActivity extends Activity {
|
||||
|
||||
String videoUrl = getUrl(getIntent());
|
||||
handleUrl(videoUrl);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
protected void handleUrl(String url) {
|
||||
try {
|
||||
NavigationHelper.openByLink(this, url);
|
||||
} catch (Exception e) {
|
||||
boolean success = NavigationHelper.openByLink(this, url);
|
||||
if (!success) {
|
||||
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.StreamingService;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.player.PopupVideoPlayer;
|
||||
import org.schabi.newpipe.util.Constants;
|
||||
import org.schabi.newpipe.util.PermissionHelper;
|
||||
@@ -20,10 +21,13 @@ public class RouterPopupActivity extends RouterActivity {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
&& !PermissionHelper.checkSystemAlertWindowPermission(this)) {
|
||||
Toast.makeText(this, R.string.msg_popup_permission, Toast.LENGTH_LONG).show();
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
StreamingService service = NewPipe.getServiceByUrl(url);
|
||||
if (service == null) {
|
||||
StreamingService service;
|
||||
try {
|
||||
service = NewPipe.getServiceByUrl(url);
|
||||
} catch (ExtractionException e) {
|
||||
Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
@@ -40,5 +44,7 @@ public class RouterPopupActivity extends RouterActivity {
|
||||
callIntent.putExtra(Constants.KEY_URL, url);
|
||||
callIntent.putExtra(Constants.KEY_SERVICE_ID, service.getServiceId());
|
||||
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("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("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("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("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);
|
||||
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
// 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());
|
||||
|
||||
// Set up the ViewPager with the sections adapter.
|
||||
mViewPager = (ViewPager) findViewById(R.id.container);
|
||||
mViewPager = findViewById(R.id.container);
|
||||
mViewPager.setAdapter(mSectionsPagerAdapter);
|
||||
|
||||
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
|
||||
TabLayout tabLayout = findViewById(R.id.tabs);
|
||||
tabLayout.setupWithViewPager(mViewPager);
|
||||
}
|
||||
|
||||
@@ -127,14 +129,18 @@ public class AboutActivity extends AppCompatActivity {
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
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);
|
||||
|
||||
View githubLink = rootView.findViewById(R.id.github_link);
|
||||
githubLink.setOnClickListener(new OnGithubLinkClickListener());
|
||||
|
||||
View licenseLink = rootView.findViewById(R.id.app_read_license);
|
||||
licenseLink.setOnClickListener(new OnReadFullLicenseClickListener());
|
||||
View donationLink = rootView.findViewById(R.id.donation_link);
|
||||
donationLink.setOnClickListener(new OnDonationLinkClickListener());
|
||||
|
||||
View websiteLink = rootView.findViewById(R.id.website_link);
|
||||
websiteLink.setOnClickListener(new OnWebsiteLinkClickListener());
|
||||
|
||||
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
|
||||
public void onClick(View v) {
|
||||
LicenseFragment.showLicense(v.getContext(), StandardLicenses.GPL3);
|
||||
public void onClick(final View view) {
|
||||
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