1
mirror of https://github.com/TeamNewPipe/NewPipe synced 2025-10-06 12:22:14 +02:00

Compare commits

..

186 Commits

Author SHA1 Message Date
TobiGr
049c8f70cd Release version 0.19.5 (950) 2020-05-30 10:43:10 +02:00
TobiGr
353bf69550 Add changelog for 0.19.5 (950) 2020-05-30 10:42:39 +02:00
Tobias Groza
cdb989ede3 Merge pull request #3679 from wb9688/fix-android-10
Enable requestLegacyExternalStorage
2020-05-30 10:32:46 +02:00
Tobias Groza
74079e4238 Merge pull request #3680 from wb9688/fix-kiosks
Open the correct kiosk
2020-05-30 10:28:24 +02:00
wb9688
c89746214c Open the correct kiosk 2020-05-30 08:14:54 +02:00
wb9688
1d97db3ef9 Enable requestLegacyExternalStorage 2020-05-30 08:05:40 +02:00
Tobias Groza
b2a5ff5f9d Merge pull request #3669 from TeamNewPipe/release_0.19.4
Release 0.19.4
2020-05-29 19:13:09 +02:00
Stypox
f47ef2b5ea Add 0.19.4 (940) fastlane changelog 2020-05-29 18:55:01 +02:00
Stypox
bd7ec3b692 Bump to 0.19.4 (940) 2020-05-29 18:55:01 +02:00
TobiGr
52895e7b6b Increase JVM memory to fix release build 2020-05-29 18:55:01 +02:00
Stypox
a6a82c6477 Regression: fix icon size in main player 2020-05-29 15:32:44 +02:00
Tobias Groza
af66ed94b2 Merge pull request #3662 from B0pol/localisation-fixes
Localisation fixes (Fix crashes, lint)
2020-05-29 08:02:19 +02:00
bopol
583f1476d6 oops 2020-05-28 23:32:44 +02:00
bopol
b42bef32fd remove totally untranslated languages 2020-05-28 23:21:28 +02:00
bopol
8bb85ccf19 other translation linting stuff 2020-05-28 23:14:57 +02:00
bopol
3d88c2a5fa fix crash in hindi and pa languages 2020-05-28 22:59:14 +02:00
bopol
e350acaf08 remove unused plural string «comments»
on top of being unused, there were MANY problems for some languages: %s missing, only «one» quantity is translated…
2020-05-28 22:49:41 +02:00
bopol
172f70bef9 fix crash in polish, lint: remove translated translatable=false string 2020-05-28 22:22:29 +02:00
Tobias Groza
9d25c0bf8a Merge pull request #3509 from wb9688/upgrade-dependencies
Upgrade some dependencies
2020-05-28 22:07:04 +02:00
TobiGr
75b377aab3 Updatethe extractor version 2020-05-28 21:56:54 +02:00
TobiGr
3706f30b44 Merge remote-tracking branch 'Weblate/dev' into dev 2020-05-28 21:46:45 +02:00
wb9688
a9697a61ad Fix viewing licenses 2020-05-28 11:39:17 +02:00
wb9688
e16a2d7cb6 Upgrade jsoup 2020-05-28 11:39:17 +02:00
Arnis Jaundzeikars
f106e2945b Added translation using Weblate (Latvian) 2020-05-27 18:06:40 +02:00
pjammo
1ad7deddb1 Translated using Weblate (Italian)
Currently translated at 99.6% (575 of 577 strings)
2020-05-26 09:52:46 +02:00
wb9688
7b81e98581 Upgrade ACRA 2020-05-25 11:03:07 +02:00
wb9688
0cae58ce8e Upgrade LeakCanary 2020-05-25 11:03:07 +02:00
wb9688
7231150115 Upgrade some dependencies 2020-05-22 15:40:28 +02:00
Hosted Weblate
071986a4c9 Merge branch 'origin/dev' into Weblate. 2020-05-22 11:41:39 +02:00
Rahul Bali
39e7d43f10 Translated using Weblate (Hindi)
Currently translated at 82.4% (476 of 577 strings)
2020-05-22 11:41:37 +02:00
Yaron Shahrabani
aa1b17ae66 Translated using Weblate (Hebrew)
Currently translated at 100.0% (577 of 577 strings)
2020-05-22 11:41:37 +02:00
Anonymous
92bae88355 Translated using Weblate (Bengali (Bangladesh))
Currently translated at 29.8% (172 of 577 strings)
2020-05-22 11:41:36 +02:00
Jeff Huang
067eaf363e Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (577 of 577 strings)
2020-05-22 11:41:36 +02:00
Samuel Carvalho de Araújo
00efc266d9 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (577 of 577 strings)
2020-05-22 11:41:36 +02:00
Oğuz Ersen
0b014185e3 Translated using Weblate (Turkish)
Currently translated at 100.0% (577 of 577 strings)
2020-05-22 11:41:36 +02:00
zmni
3eee7378de Translated using Weblate (Indonesian)
Currently translated at 100.0% (577 of 577 strings)
2020-05-22 11:41:36 +02:00
zeritti
c31428f6bc Translated using Weblate (Czech)
Currently translated at 100.0% (577 of 577 strings)
2020-05-22 11:41:35 +02:00
B0pol
163e561cf9 Translated using Weblate (French)
Currently translated at 100.0% (577 of 577 strings)
2020-05-22 11:41:35 +02:00
JoC
a32ded2829 Translated using Weblate (Spanish)
Currently translated at 100.0% (577 of 577 strings)
2020-05-22 11:41:35 +02:00
nautilusx
a5b7517fbd Translated using Weblate (German)
Currently translated at 99.8% (576 of 577 strings)
2020-05-22 11:41:34 +02:00
Tobias Groza
176d57b35a Merge pull request #3271 from Stypox/icons
Use vector drawables instead of PNGs for material icons
2020-05-21 19:32:43 +02:00
Stypox
927a1d58e2 Use drop down/up instead of expand icons in drawer
As per the material guidelines
2020-05-21 15:39:36 +02:00
Stypox
bbd0df08d3 Add shadow behind play icon in video detail fragment 2020-05-21 15:39:36 +02:00
Stypox
9e57195e14 Fix checkstyle issues
Also replace all tabs with 4 spaces
2020-05-21 15:39:36 +02:00
Stypox
05ab54c30d Fix invisible fullscreen button in popup player on API 19 2020-05-21 15:39:36 +02:00
Stypox
e3e2028153 Use AppCompatResources instead of ContextCompat 2020-05-21 15:39:36 +02:00
Stypox
883bcc735d Fix pause used instead of play in paused popup player when seeking
Also use `setBackgroundResource` to automatically obtain PNG drawables (from exoplayer)
2020-05-21 15:39:36 +02:00
Stypox
158727e2f2 Replace hardcoded white drawable with themed one 2020-05-21 15:39:36 +02:00
Stypox
899f69d120 Fix additional empty title on tab selection fragments in API 19 2020-05-21 15:39:36 +02:00
Stypox
b575046c05 Fix choice dialogs on API 19 by manually getting drawable 2020-05-21 15:39:36 +02:00
Stypox
b5c60d2be2 Update AndroidX to fix icon crashes in preferences on API 19
Also remove legacy libraries
Use `androidx.preference:preference` instead of `androidx.legacy:legacy-preference-v14` and remove `androidx.legacy:legacy-support-v4
2020-05-21 15:39:36 +02:00
Stypox
631dfee763 Readd ic_close and ic_replay PNGs: needed in notifications
The other icons used in notifications are taken from exoplayer's ones: `@drawable/exo_controls_*`
2020-05-21 15:39:36 +02:00
Stypox
d7f610113e Fix background player queue crashing on opening 2020-05-21 15:39:36 +02:00
Stypox
e0e4f6db2b Fix MainFragment tab icons did not follow theme color 2020-05-21 15:39:36 +02:00
Stypox
c27a26c0aa Rename ic_hot in ic_kiosk_hot and improve getKioskIcon() 2020-05-21 15:39:36 +02:00
Stypox
3dcd2468a2 Use app:srcCompat and derivatives intead of android: ones
To fix crashes on API 19
2020-05-21 15:39:36 +02:00
Stypox
ea43b28f74 Use vector drawables instead of PNGs for material icons
For all manually-created images PNG have been kept.
- rename all icon attrs to have a `ic_` prefix
- always use `_24dp` icons, because there is no real difference, since they are vector drawables
- always use the original name found on material.io for icon drawables, as to not create confusion and possibly duplicates. Icon names can still be different from real drawable names, though I have made some of them compliant to this or maybe more meaningul.
- remove duplicate `getIconByAttr()` in ThemeHelper (use `resolveResourceIdFromAttr()`
- use standard icons for `expand_more` and `expand_less` instead of triangles
- use `play_button_outline` instead of custom PNG as play button in VideoDetailFragment (questionable, as there is no shadow anymore)
2020-05-21 15:39:35 +02:00
bopol
a3e2a085b6 Merge pull request #3501 from B0pol/openInBrowser
Open in browser button now really opens in browser
2020-05-21 09:24:57 +02:00
Anonymous
635d51b60d Translated using Weblate (Hindi)
Currently translated at 82.4% (476 of 577 strings)
2020-05-20 12:31:02 +02:00
Rahul Bali
95eb1c0d95 Translated using Weblate (Hindi)
Currently translated at 82.4% (476 of 577 strings)
2020-05-20 12:31:01 +02:00
Rahul Bali
8aca43a7e6 Translated using Weblate (Hindi)
Currently translated at 81.9% (473 of 577 strings)
2020-05-20 12:25:58 +02:00
Anonymous
f6afe59788 Translated using Weblate (Hindi)
Currently translated at 81.9% (473 of 577 strings)
2020-05-20 12:25:57 +02:00
bopol
8e13161f64 fix checkstyle 2020-05-19 21:57:46 +02:00
bopol
97437b8af3 apply @stypox suggestions 2020-05-19 21:52:30 +02:00
bopol
9a938093e2 Open in browser button now really opens in browser 2020-05-19 21:51:47 +02:00
Hosted Weblate
3edcc9f9fd Merge branch 'origin/dev' into Weblate. 2020-05-19 17:02:04 +02:00
Oymate
55db408720 Translated using Weblate (Bengali (Bangladesh))
Currently translated at 29.6% (171 of 577 strings)
2020-05-19 17:02:04 +02:00
Samuel Carvalho de Araújo
caef874814 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (577 of 577 strings)
2020-05-19 17:02:04 +02:00
Anonymous
1622639eca Translated using Weblate (Bengali (Bangladesh))
Currently translated at 29.6% (171 of 577 strings)
2020-05-19 17:02:00 +02:00
Oymate
4df89f4217 Translated using Weblate (Bengali (Bangladesh))
Currently translated at 29.6% (171 of 577 strings)
2020-05-19 17:02:00 +02:00
Tobias Groza
079b98ed3f Merge pull request #3618 from Stypox/long-press-strings
Improve long-press menu strings
2020-05-19 08:38:00 +02:00
Stypox
a0526d2c9c Improve long-press menu strings 2020-05-19 08:24:04 +02:00
Stypox
169b1cbd32 Merge pull request #3613 from wb9688/fix-download-dialog-freeze
Fix download dialog freeze
2020-05-18 14:11:17 +02:00
wb9688
8968081e77 Remove not needed Checkstyle stuff 2020-05-18 13:40:01 +02:00
wb9688
93ba7510e1 Fix ListHelper ANR 2020-05-18 13:40:01 +02:00
Hosted Weblate
579bb743bb Merge branch 'origin/dev' into Weblate. 2020-05-18 13:17:56 +02:00
Rai Tsa
9e5e9ea612 Translated using Weblate (Finnish)
Currently translated at 58.0% (335 of 577 strings)
2020-05-18 13:17:54 +02:00
Thien Bui
2241a13cba Translated using Weblate (Vietnamese)
Currently translated at 99.8% (576 of 577 strings)
2020-05-18 13:17:54 +02:00
Isak Holmström
9c1fb0cb92 Translated using Weblate (Swedish)
Currently translated at 89.4% (516 of 577 strings)
2020-05-18 13:17:52 +02:00
Anonymous
4904514257 Translated using Weblate (Swedish)
Currently translated at 89.4% (516 of 577 strings)
2020-05-18 13:17:52 +02:00
Samuel Carvalho de Araújo
6d829c26a1 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (577 of 577 strings)
2020-05-18 13:17:52 +02:00
Stypox
c05467fb92 Merge pull request #3513 from Stypox/exoplayer
Update to ExoPlayer 2.11.4
2020-05-17 22:02:19 +02:00
Anonymous
d47f7f3348 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (577 of 577 strings)
2020-05-17 00:52:28 +02:00
Samuel Carvalho de Araújo
5931a84651 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (577 of 577 strings)
2020-05-16 04:41:32 +02:00
zeritti
5771783d11 Translated using Weblate (Czech)
Currently translated at 100.0% (577 of 577 strings)
2020-05-16 04:41:32 +02:00
Hosted Weblate
aae07a60bd Merge branch 'origin/dev' into Weblate. 2020-05-14 11:38:10 +02:00
MohammedSR Vevo
462d418ee0 Translated using Weblate (Kurdish)
Currently translated at 100.0% (577 of 577 strings)
2020-05-14 11:38:08 +02:00
Isak Holmström
ce63c2e1db Translated using Weblate (Swedish)
Currently translated at 89.4% (516 of 577 strings)
2020-05-14 11:38:07 +02:00
Isak Holmström
52baf8cbe5 Translated using Weblate (Swedish)
Currently translated at 89.4% (516 of 577 strings)
2020-05-14 11:38:07 +02:00
ssantos
1779b9ee1a Translated using Weblate (Portuguese)
Currently translated at 100.0% (577 of 577 strings)
2020-05-14 11:38:06 +02:00
B0pol
eae169236c Merge pull request #3581 from B0pol/gitignore
Add vscode / eclipse files to gitignore
2020-05-13 18:11:51 +00:00
bopol
ce0efba0d2 gitignore update 2020-05-13 19:54:02 +02:00
Tobias Groza
87c7ac3970 Merge pull request #3580 from wb9688/fix-email
Fix sending e-mail from crash reporter
2020-05-13 17:10:22 +02:00
bopol
0f8d196a52 Add vscode / eclipse files to gitignore 2020-05-13 11:07:02 +02:00
Stypox
6dc7dab154 Merge pull request #3565 from B0pol/retry-button-color
Change retry & subscribe buttons background color based on service color
2020-05-13 11:01:40 +02:00
wb9688
dd4cb23005 Fix sending e-mail from crash reporter 2020-05-13 09:42:08 +02:00
ButterflyOfFire
0589017f8c Translated using Weblate (Arabic)
Currently translated at 100.0% (577 of 577 strings)
2020-05-12 15:41:32 +02:00
bopol
375e18bec8 subscribe button now match service's main color 2020-05-11 19:29:34 +02:00
WaldiS
b9de74f183 Translated using Weblate (Polish)
Currently translated at 100.0% (577 of 577 strings)
2020-05-11 08:54:43 +02:00
Oğuz Ersen
08ca69507f Translated using Weblate (Turkish)
Currently translated at 100.0% (577 of 577 strings)
2020-05-11 08:54:42 +02:00
JoC
65ca982342 Translated using Weblate (Spanish)
Currently translated at 100.0% (577 of 577 strings)
2020-05-11 08:54:42 +02:00
Igor Nedoboy
658281a92c Translated using Weblate (Russian)
Currently translated at 100.0% (577 of 577 strings)
2020-05-10 22:59:48 +02:00
Igor Nedoboy
a959f61367 Translated using Weblate (Russian)
Currently translated at 100.0% (577 of 577 strings)
2020-05-10 22:50:30 +02:00
Yaron Shahrabani
8e61f744ec Translated using Weblate (Hebrew)
Currently translated at 100.0% (577 of 577 strings)
2020-05-10 14:34:56 +02:00
Jeff Huang
73d3e52e29 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (577 of 577 strings)
2020-05-10 14:34:55 +02:00
Xiang Xu
49a134845c Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (577 of 577 strings)
2020-05-10 14:34:55 +02:00
Samuel Carvalho de Araújo
29807f3d39 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (577 of 577 strings)
2020-05-10 14:34:55 +02:00
WaldiS
29b79b7725 Translated using Weblate (Polish)
Currently translated at 99.8% (576 of 577 strings)
2020-05-10 14:34:54 +02:00
zmni
1cdb10a040 Translated using Weblate (Indonesian)
Currently translated at 100.0% (577 of 577 strings)
2020-05-10 14:34:54 +02:00
AioiLight
5f7851df72 Translated using Weblate (Japanese)
Currently translated at 100.0% (577 of 577 strings)
2020-05-10 14:34:54 +02:00
winqooq
3d9bc05d7a Translated using Weblate (Russian)
Currently translated at 99.4% (574 of 577 strings)
2020-05-10 14:34:53 +02:00
B0pol
c127428c59 Translated using Weblate (French)
Currently translated at 100.0% (577 of 577 strings)
2020-05-10 14:34:53 +02:00
nautilusx
7966d8403a Translated using Weblate (German)
Currently translated at 100.0% (577 of 577 strings)
2020-05-10 14:34:53 +02:00
bopol
80cc8a8e02 color retry button based on service color 2020-05-10 10:54:12 +02:00
Igor Nedoboy
ee4e205fef Translated using Weblate (Russian)
Currently translated at 99.4% (574 of 577 strings)
2020-05-10 02:07:05 +02:00
Hosted Weblate
ea443dc80c Merge branch 'origin/dev' into Weblate. 2020-05-09 16:13:01 +02:00
Senthil Kumar G
283645513d Translated using Weblate (Tamil)
Currently translated at 35.8% (206 of 574 strings)
2020-05-09 16:12:57 +02:00
Anonymous
81b99382b8 Translated using Weblate (Italian)
Currently translated at 100.0% (574 of 574 strings)
2020-05-09 16:12:57 +02:00
random r
ab74465e6c Translated using Weblate (Italian)
Currently translated at 100.0% (574 of 574 strings)
2020-05-09 16:12:57 +02:00
Tobias Groza
b3eadb557b Merge pull request #3337 from AioiLight/blocking-gesture-when-touch-from-navbar
Block the gesture when touch it from NavigationBar or StatusBar.
2020-05-09 10:43:15 +02:00
AioiLight
0abd2bcba6 Clean up code
Follow Checkstyle

Move to PlayerGestureListener from VideoPlayerImpl

Update app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java

Co-authored-by: wb9688 <46277131+wb9688@users.noreply.github.com>
2020-05-09 10:11:46 +02:00
Tobias Groza
9cf76a918e Merge pull request #3430 from Royosef/DisplayParentChannelDetails
Display parent channel details
2020-05-08 23:29:28 +02:00
wb9688
ae437b1510 Bump NewPipeExtractor 2020-05-08 18:07:52 +02:00
wb9688
1096ec1c09 Adjust sub-channel thumbnail size 2020-05-08 15:51:21 +02:00
wb9688
235394d96c Don't show sub-channel thumbnail by default 2020-05-08 15:51:21 +02:00
Anonymous
d25e1d801c Translated using Weblate (Italian)
Currently translated at 99.6% (572 of 574 strings)
2020-05-08 12:35:52 +02:00
random r
2dca5ab966 Translated using Weblate (Italian)
Currently translated at 99.6% (572 of 574 strings)
2020-05-08 12:35:52 +02:00
caltaojihun
89ab57b1c1 Translated using Weblate (Vietnamese)
Currently translated at 94.4% (542 of 574 strings)
2020-05-08 09:56:46 +02:00
caltaojihun
dc66e6a4bf Translated using Weblate (Vietnamese)
Currently translated at 79.7% (458 of 574 strings)
2020-05-08 06:49:55 +02:00
Hosted Weblate
5c2f2fd882 Merge branch 'origin/dev' into Weblate. 2020-05-07 23:24:06 +02:00
MohammedSR Vevo
5c3ddefbf9 Translated using Weblate (Kurdish)
Currently translated at 100.0% (574 of 574 strings)
2020-05-07 23:24:04 +02:00
thami simo
a8d3f45ea1 Translated using Weblate (Arabic)
Currently translated at 100.0% (574 of 574 strings)
2020-05-07 23:24:03 +02:00
ssantos
cc2c41ddc8 Translated using Weblate (Portuguese)
Currently translated at 100.0% (574 of 574 strings)
2020-05-07 23:24:03 +02:00
wb9688
b990f30a09 Merge pull request #3545 from Stypox/kore
Fix Kodi button showing up with unsupported services
2020-05-07 21:44:09 +02:00
Stypox
5c711322d4 In player hide kodi button if service unsupported 2020-05-07 21:11:34 +02:00
Roy Yosef
b7d4a4f604 Navigate to parent(uploader) channel from the uploader section on long click 2020-05-07 20:40:17 +02:00
Roy Yosef
cc8874b687 Fix PR review
Make all of the uploader section on stream page navigate to the channel page
Extract hard coded strings
Remove redundant spaces
Fix open streams from a channel
Rename "ParentChannel" to "SubChannel"
Config royosef:NewPipeExtractor in app/build.gradle
2020-05-07 20:40:17 +02:00
Roy Yosef
2d0bc05488 Add sub-channel details to channel fragment 2020-05-07 20:39:32 +02:00
Roy Yosef
1429774487 Add sub-channel details to video detail fragment 2020-05-07 20:39:32 +02:00
wb9688
2060312dc1 Merge pull request #3466 from B0pol/soundCloudComments
adapt CommentsInfoItemExtractorRefactoring
2020-05-07 16:06:15 +02:00
bopol
8b6728480f bump extractor version 2020-05-07 15:46:41 +02:00
Anxhelo Lushka
cecafdee29 Translated using Weblate (Albanian)
Currently translated at 100.0% (574 of 574 strings)
2020-05-07 13:58:28 +02:00
Senthil Kumar G
05f2af25af Translated using Weblate (Tamil)
Currently translated at 35.7% (205 of 574 strings)
2020-05-07 13:58:27 +02:00
Yaron Shahrabani
e3d826f6c4 Translated using Weblate (Hebrew)
Currently translated at 100.0% (574 of 574 strings)
2020-05-07 13:58:27 +02:00
Jeff Huang
02430bed90 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (574 of 574 strings)
2020-05-07 13:58:27 +02:00
Samuel Carvalho de Araújo
3f7005ed9a Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (574 of 574 strings)
2020-05-07 13:58:26 +02:00
WaldiS
586ee75833 Translated using Weblate (Polish)
Currently translated at 99.8% (573 of 574 strings)
2020-05-07 13:58:26 +02:00
Emin Tufan Çetin
1d903f11a8 Translated using Weblate (Turkish)
Currently translated at 100.0% (574 of 574 strings)
2020-05-07 13:58:25 +02:00
Muhammad Mauli Mubassari
578159b95c Translated using Weblate (Indonesian)
Currently translated at 100.0% (574 of 574 strings)
2020-05-07 13:58:25 +02:00
zeritti
5c95587284 Translated using Weblate (Czech)
Currently translated at 100.0% (574 of 574 strings)
2020-05-07 13:58:25 +02:00
Marian Hanzel
f7e9227ad2 Translated using Weblate (Slovak)
Currently translated at 94.0% (540 of 574 strings)
2020-05-07 13:58:24 +02:00
AioiLight
c11a4d6867 Translated using Weblate (Japanese)
Currently translated at 100.0% (574 of 574 strings)
2020-05-07 13:58:23 +02:00
Anonymous
6c2b0448a4 Translated using Weblate (Dutch)
Currently translated at 100.0% (574 of 574 strings)
2020-05-07 13:58:23 +02:00
Terry Louwers
bd0eb8cccf Translated using Weblate (Dutch)
Currently translated at 100.0% (574 of 574 strings)
2020-05-07 13:58:23 +02:00
nautilusx
09bb043952 Translated using Weblate (German)
Currently translated at 100.0% (574 of 574 strings)
2020-05-07 13:58:22 +02:00
Stypox
9ca6cfd637 Fix Kodi button showing up in unsupported services 2020-05-06 20:55:53 +02:00
Igor Nedoboy
3869a66fcc Translated using Weblate (Russian)
Currently translated at 100.0% (574 of 574 strings)
2020-05-06 13:33:14 +02:00
bopol
d1c94f5120 adapt CommentsInfoItemExtractorRefactoring 2020-05-05 15:03:59 +02:00
Igor Nedoboy
c55e9941ec Translated using Weblate (Russian)
Currently translated at 100.0% (574 of 574 strings)
2020-05-05 08:21:44 +02:00
Hosted Weblate
fa9a419d73 Merge branch 'origin/dev' into Weblate. 2020-05-04 17:49:25 +02:00
Software In Interlingua
ab4e0da6b4 Translated using Weblate (Interlingua)
Currently translated at 39.7% (228 of 573 strings)
2020-05-04 17:49:22 +02:00
Igor Nedoboy
073572681e Translated using Weblate (Russian)
Currently translated at 100.0% (573 of 573 strings)
2020-05-04 17:49:21 +02:00
wb9688
b630f269c4 Merge pull request #3511 from wb9688/ktlint
Ktlint
2020-05-04 15:13:07 +02:00
wb9688
40b1cd82b1 Merge pull request #2727 from vnagel/ageRestrictedContent
Restricted mode setting for youtube
2020-05-04 15:05:11 +02:00
Tobias Groza
abcbdef63b Merge pull request #3502 from wb9688/allow-translation
Allow time ago debug setting translation
2020-05-03 23:25:54 +02:00
Hosted Weblate
56d53d8805 Merge branch 'origin/dev' into Weblate. 2020-05-03 15:40:40 +02:00
Oymate
7433fe049c Translated using Weblate (Bengali (Bangladesh))
Currently translated at 29.6% (170 of 573 strings)
2020-05-03 15:40:40 +02:00
postsorino
bb2be49d3b Translated using Weblate (Greek)
Currently translated at 85.1% (488 of 573 strings)
2020-05-03 15:40:40 +02:00
Bruno Guerreiro
cd1b578e84 Translated using Weblate (Portuguese)
Currently translated at 100.0% (573 of 573 strings)
2020-05-03 15:40:40 +02:00
winqooq
c3df9b4105 Translated using Weblate (Russian)
Currently translated at 99.4% (570 of 573 strings)
2020-05-03 15:40:37 +02:00
wb9688
b0415a5289 Auto-format using Ktlint 2020-05-01 20:13:21 +02:00
wb9688
ff7344438b Optimize imports 2020-05-01 20:13:01 +02:00
wb9688
f5f8e5d279 Add Ktlint 2020-05-01 20:09:52 +02:00
Stypox
b4ddc8f96c Update to ExoPlayer 2.11.4 2020-05-01 15:03:54 +02:00
wb9688
8ebb1e29fa Allow time ago debug setting translation 2020-04-29 14:47:06 +02:00
Vincent Nagel
72c9845174 removed unnecessary method call 2020-04-25 21:39:53 -05:00
Vincent Nagel
f60cce54ea rename setting to "YouTube restricted mode" 2020-04-20 21:47:32 -05:00
Vincent Nagel
63087a4311 renamed to "restricted mode" 2020-04-20 21:46:40 -05:00
Vincent Nagel
5a193d50f6 remove duplicate line 2020-04-20 21:45:32 -05:00
Vincent Nagel
08a6e999b9 fix checkstyle errors 2020-04-20 21:45:32 -05:00
Vincent Nagel
e33cdca1ef added logging when context null in onPrefTreeClick 2020-04-20 21:45:32 -05:00
Vincent Nagel
9ede7a3c42 setupTabs() if ageRestrictedContent pref changed 2020-04-20 21:45:32 -05:00
Vincent Nagel
430d4e1ccd ageRestrictedContent cookie only sent for youtube
Now the age restricted content cookie is only sent when sending a
request to youtube. There's no need to remove the cookie when the
service changes because whether to add the cookie is determined by
looking at the url the request is being sent to.
2020-04-20 21:45:32 -05:00
Vincent Nagel
de4d6037d3 ageRestrictedContent first draft
Cookie updated whenever ageRestrictedContent setting is changed or
service is changed. Right now there is only a cookie for youtube, but
cookies for other services could be added in the future.

Problems with this approach: Even when the service is set to youtube,
the downloader doesn't only request youtube urls e.g. it also sends
reqeusts to i.ytimg.com, suggestqueries.google.com, and yt3.ggpht.com.
The ageRestrictedContent cookie is not normally sent when sending
requests to these other urls, so doing so might have unknown effects.
2020-04-20 21:45:32 -05:00
AioiLight
562754c0b9 Merge branch 'dev' into blocking-gesture-when-touch-from-navbar 2020-04-04 23:52:06 +09:00
AioiLight
d9c6f7acb6 Block the gesture when touch it from NavigationBar or StatusBar. 2020-04-03 05:11:36 +09:00
929 changed files with 4412 additions and 3428 deletions

8
.gitignore vendored
View File

@@ -10,3 +10,11 @@
*~
.weblate
*.class
# vscode / eclipse files
*.classpath
*.project
*.settings
bin/
.vscode/
*.code-workspace

View File

@@ -5,13 +5,13 @@ android:
components:
# The BuildTools version used by NewPipe
- tools
- build-tools-28.0.3
- build-tools-29.0.3
# The SDK version used to compile NewPipe
- android-28
- android-29
before_install:
- yes | sdkmanager "platforms;android-28"
- yes | sdkmanager "platforms;android-29"
script: ./gradlew -Dorg.gradle.jvmargs=-Xmx1536m assembleDebug lintDebug testDebugUnitTest
licenses:

View File

@@ -5,16 +5,16 @@ apply plugin: 'kotlin-kapt'
apply plugin: 'checkstyle'
android {
compileSdkVersion 28
buildToolsVersion '28.0.3'
compileSdkVersion 29
buildToolsVersion '29.0.3'
defaultConfig {
applicationId "org.schabi.newpipe"
resValue "string", "app_name", "NewPipe"
minSdkVersion 19
targetSdkVersion 28
versionCode 930
versionName "0.19.3"
targetSdkVersion 29
versionCode 950
versionName "0.19.5"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
@@ -66,6 +66,7 @@ android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
encoding 'utf-8'
}
// Required and used only by groupie
@@ -79,22 +80,22 @@ android {
}
ext {
androidxLibVersion = '1.0.0'
exoPlayerLibVersion = '2.10.8'
roomDbLibVersion = '2.1.0'
leakCanaryLibVersion = '1.5.4' //1.6.1
okHttpLibVersion = '3.12.6'
icepickLibVersion = '3.2.0'
stethoLibVersion = '1.5.0'
markwonVersion = '4.2.1'
checkstyleVersion = '8.31'
icepickVersion = '3.2.0'
checkstyleVersion = '8.32'
stethoVersion = '1.5.1'
leakCanaryVersion = '2.2'
exoPlayerVersion = '2.11.4'
androidxLifecycleVersion = '2.2.0'
androidxRoomVersion = '2.2.5'
groupieVersion = '2.8.0'
markwonVersion = '4.3.1'
}
checkstyle {
configFile rootProject.file('checkstyle.xml')
ignoreFailures false
showViolations true
toolVersion = "${checkstyleVersion}"
toolVersion = checkstyleVersion
}
task runCheckstyle(type: Checkstyle) {
@@ -116,88 +117,96 @@ task runCheckstyle(type: Checkstyle) {
}
}
tasks.withType(Checkstyle).each {
checkstyleTask -> checkstyleTask.doLast {
reports.all { report ->
def outputFile = report.destination
if (outputFile.exists() && outputFile.text.contains("severity=\"error\"")) {
throw new GradleException("There were checkstyle errors! For more info check $outputFile")
}
}
}
configurations {
ktlint
}
task runKtlint(type: JavaExec) {
main = "com.pinterest.ktlint.Main"
classpath = configurations.ktlint
args "src/**/*.kt"
}
task formatKtlint(type: JavaExec) {
main = "com.pinterest.ktlint.Main"
classpath = configurations.ktlint
args "-F", "src/**/*.kt"
}
afterEvaluate {
preDebugBuild.dependsOn runCheckstyle
preDebugBuild.dependsOn runCheckstyle, runKtlint
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "frankiesardo:icepick:${icepickVersion}"
kapt "frankiesardo:icepick-processor:${icepickVersion}"
debugImplementation "com.puppycrawl.tools:checkstyle:${checkstyleVersion}"
ktlint "com.pinterest:ktlint:0.35.0"
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation "android.arch.persistence.room:testing:1.1.1"
androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
debugImplementation "com.facebook.stetho:stetho:${stethoVersion}"
debugImplementation "com.facebook.stetho:stetho-okhttp3:${stethoVersion}"
debugImplementation "com.squareup.leakcanary:leakcanary-android:${leakCanaryVersion}"
implementation "com.squareup.leakcanary:leakcanary-object-watcher-android:${leakCanaryVersion}"
debugImplementation "androidx.multidex:multidex:2.0.1"
testImplementation 'junit:junit:4.13'
testImplementation 'org.mockito:mockito-core:3.3.3'
androidTestImplementation "androidx.test.ext:junit:1.1.1"
androidTestImplementation "androidx.room:room-testing:${androidxRoomVersion}"
androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0", {
exclude module: 'support-annotations'
})
}
implementation 'com.github.TeamNewPipe:NewPipeExtractor:fc3a69ed54b393e3e4e3a78ae6e89edc1d47c45a'
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.23.0'
implementation 'com.github.TeamNewPipe:NewPipeExtractor:bda83fe6a5b9a8a0751669fbc444fa49d72d0d2f'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation "androidx.legacy:legacy-support-v4:${androidxLibVersion}"
implementation "com.google.android.material:material:${androidxLibVersion}"
implementation "androidx.recyclerview:recyclerview:${androidxLibVersion}"
implementation "androidx.legacy:legacy-preference-v14:${androidxLibVersion}"
implementation "androidx.cardview:cardview:${androidxLibVersion}"
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation "com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751"
implementation "org.jsoup:jsoup:1.13.1"
implementation 'com.xwray:groupie:2.7.0'
implementation 'com.xwray:groupie-kotlin-android-extensions:2.7.0'
implementation "com.squareup.okhttp3:okhttp:3.12.11"
implementation 'androidx.lifecycle:lifecycle-livedata:2.0.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
implementation "com.google.android.exoplayer:exoplayer:${exoPlayerVersion}"
implementation "com.google.android.exoplayer:extension-mediasession:${exoPlayerVersion}"
// Originally in NewPipeExtractor
implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751'
implementation 'org.jsoup:jsoup:1.9.2'
implementation "com.google.android.material:material:1.1.0"
implementation 'ch.acra:acra:4.9.2' //4.11
implementation "androidx.appcompat:appcompat:1.1.0"
implementation "androidx.preference:preference:1.1.1"
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "androidx.cardview:cardview:1.0.0"
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
implementation 'de.hdodenhof:circleimageview:2.2.0'
implementation 'com.nononsenseapps:filepicker:4.2.1'
implementation "androidx.lifecycle:lifecycle-livedata:${androidxLifecycleVersion}"
implementation "androidx.lifecycle:lifecycle-viewmodel:${androidxLifecycleVersion}"
implementation "androidx.lifecycle:lifecycle-extensions:${androidxLifecycleVersion}"
implementation "com.google.android.exoplayer:exoplayer:${exoPlayerLibVersion}"
implementation "com.google.android.exoplayer:extension-mediasession:${exoPlayerLibVersion}"
implementation "androidx.room:room-runtime:${androidxRoomVersion}"
implementation "androidx.room:room-rxjava2:${androidxRoomVersion}"
kapt "androidx.room:room-compiler:${androidxRoomVersion}"
debugImplementation "com.facebook.stetho:stetho:${stethoLibVersion}"
debugImplementation "com.facebook.stetho:stetho-urlconnection:${stethoLibVersion}"
debugImplementation 'androidx.multidex:multidex:2.0.1'
implementation "com.xwray:groupie:${groupieVersion}"
implementation "com.xwray:groupie-kotlin-android-extensions:${groupieVersion}"
implementation 'io.reactivex.rxjava2:rxjava:2.2.2'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
implementation 'org.ocpsoft.prettytime:prettytime:4.0.3.Final'
implementation "androidx.room:room-runtime:${roomDbLibVersion}"
implementation "androidx.room:room-rxjava2:${roomDbLibVersion}"
kapt "androidx.room:room-compiler:${roomDbLibVersion}"
implementation "frankiesardo:icepick:${icepickLibVersion}"
kapt "frankiesardo:icepick-processor:${icepickLibVersion}"
debugImplementation "com.squareup.leakcanary:leakcanary-android:${leakCanaryLibVersion}"
releaseImplementation "com.squareup.leakcanary:leakcanary-android-no-op:${leakCanaryLibVersion}"
implementation "com.squareup.okhttp3:okhttp:${okHttpLibVersion}"
debugImplementation "com.facebook.stetho:stetho-okhttp3:${stethoLibVersion}"
implementation "de.hdodenhof:circleimageview:3.1.0"
implementation "com.nostra13.universalimageloader:universal-image-loader:1.9.5"
implementation "io.noties.markwon:core:${markwonVersion}"
implementation "io.noties.markwon:linkify:${markwonVersion}"
implementation "com.nononsenseapps:filepicker:4.2.1"
implementation "ch.acra:acra-core:5.5.0"
implementation "io.reactivex.rxjava2:rxjava:2.2.19"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
implementation "com.jakewharton.rxbinding2:rxbinding:2.2.0"
implementation "org.ocpsoft.prettytime:prettytime:4.0.5.Final"
}
static String getGitWorkingBranch() {

View File

@@ -116,4 +116,4 @@ class AppDatabaseTest {
testHelper.closeWhenFinished(database)
return database
}
}
}

View File

@@ -1,107 +0,0 @@
package org.schabi.newpipe;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import androidx.annotation.NonNull;
import androidx.multidex.MultiDex;
import com.facebook.stetho.Stetho;
import com.facebook.stetho.okhttp3.StethoInterceptor;
import com.squareup.leakcanary.AndroidHeapDumper;
import com.squareup.leakcanary.DefaultLeakDirectoryProvider;
import com.squareup.leakcanary.HeapDumper;
import com.squareup.leakcanary.LeakCanary;
import com.squareup.leakcanary.LeakDirectoryProvider;
import com.squareup.leakcanary.RefWatcher;
import org.schabi.newpipe.extractor.downloader.Downloader;
import java.io.File;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
public class DebugApp extends App {
private static final String TAG = DebugApp.class.toString();
@Override
protected void attachBaseContext(final Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
@Override
public void onCreate() {
super.onCreate();
initStetho();
}
@Override
protected Downloader getDownloader() {
DownloaderImpl downloader = DownloaderImpl.init(new OkHttpClient.Builder()
.addNetworkInterceptor(new StethoInterceptor()));
setCookiesToDownloader(downloader);
return downloader;
}
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);
}
@Override
protected boolean isDisposedRxExceptionsReported() {
return PreferenceManager.getDefaultSharedPreferences(this)
.getBoolean(getString(R.string.allow_disposed_exceptions_key), false);
}
@Override
protected RefWatcher installLeakCanary() {
return LeakCanary.refWatcher(this)
.heapDumper(new ToggleableHeapDumper(this))
// give each object 10 seconds to be gc'ed, before leak canary gets nosy on it
.watchDelay(10, TimeUnit.SECONDS)
.buildAndInstall();
}
public static class ToggleableHeapDumper implements HeapDumper {
private final HeapDumper dumper;
private final SharedPreferences preferences;
private final String dumpingAllowanceKey;
ToggleableHeapDumper(@NonNull final Context context) {
LeakDirectoryProvider leakDirectoryProvider = new DefaultLeakDirectoryProvider(context);
this.dumper = new AndroidHeapDumper(context, leakDirectoryProvider);
this.preferences = PreferenceManager.getDefaultSharedPreferences(context);
this.dumpingAllowanceKey = context.getString(R.string.allow_heap_dumping_key);
}
private boolean isDumpingAllowed() {
return preferences.getBoolean(dumpingAllowanceKey, false);
}
@Override
public File dumpHeap() {
return isDumpingAllowed() ? dumper.dumpHeap() : HeapDumper.RETRY_LATER;
}
}
}

View File

@@ -0,0 +1,59 @@
package org.schabi.newpipe
import android.content.Context
import androidx.multidex.MultiDex
import androidx.preference.PreferenceManager
import com.facebook.stetho.Stetho
import com.facebook.stetho.okhttp3.StethoInterceptor
import leakcanary.AppWatcher
import leakcanary.LeakCanary
import okhttp3.OkHttpClient
import org.schabi.newpipe.extractor.downloader.Downloader
class DebugApp : App() {
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
MultiDex.install(this)
}
override fun onCreate() {
super.onCreate()
initStetho()
// Give each object 10 seconds to be GC'ed, before LeakCanary gets nosy on it
AppWatcher.config = AppWatcher.config.copy(watchDurationMillis = 10000)
LeakCanary.config = LeakCanary.config.copy(dumpHeap = PreferenceManager
.getDefaultSharedPreferences(this).getBoolean(getString(
R.string.allow_heap_dumping_key), false))
}
override fun getDownloader(): Downloader {
val downloader = DownloaderImpl.init(OkHttpClient.Builder()
.addNetworkInterceptor(StethoInterceptor()))
setCookiesToDownloader(downloader)
return downloader
}
private fun initStetho() {
// Create an InitializerBuilder
val initializerBuilder = Stetho.newInitializerBuilder(this)
// Enable Chrome DevTools
initializerBuilder.enableWebKitInspector(Stetho.defaultInspectorModulesProvider(this))
// Enable command line interface
initializerBuilder.enableDumpapp(
Stetho.defaultDumperPluginsProvider(applicationContext))
// Use the InitializerBuilder to generate an Initializer
val initializer = initializerBuilder.build()
// Initialize Stetho with the Initializer
Stetho.initialize(initializer)
}
override fun isDisposedRxExceptionsReported(): Boolean {
return PreferenceManager.getDefaultSharedPreferences(this)
.getBoolean(getString(R.string.allow_disposed_exceptions_key), false)
}
}

View File

@@ -20,6 +20,7 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:logo="@mipmap/ic_launcher"
android:requestLegacyExternalStorage="true"
android:theme="@style/OpeningTheme"
tools:ignore="AllowBackup">
<activity

View File

@@ -9,19 +9,16 @@ import android.content.SharedPreferences;
import android.os.Build;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceManager;
import com.nostra13.universalimageloader.cache.memory.impl.LRULimitedMemoryCache;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.squareup.leakcanary.LeakCanary;
import com.squareup.leakcanary.RefWatcher;
import org.acra.ACRA;
import org.acra.config.ACRAConfiguration;
import org.acra.config.ACRAConfigurationException;
import org.acra.config.ConfigurationBuilder;
import org.acra.config.CoreConfiguration;
import org.acra.config.CoreConfigurationBuilder;
import org.acra.sender.ReportSenderFactory;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.downloader.Downloader;
@@ -72,13 +69,6 @@ public class App extends Application {
private static final Class<? extends ReportSenderFactory>[]
REPORT_SENDER_FACTORY_CLASSES = new Class[]{AcraReportSenderFactory.class};
private static App app;
private RefWatcher refWatcher;
@Nullable
public static RefWatcher getRefWatcher(final Context context) {
final App application = (App) context.getApplicationContext();
return application.refWatcher;
}
public static App getApp() {
return app;
@@ -95,13 +85,6 @@ public class App extends Application {
public void onCreate() {
super.onCreate();
if (LeakCanary.isInAnalyzerProcess(this)) {
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
return;
}
refWatcher = installLeakCanary();
app = this;
// Initialize settings first because others inits can use its values
@@ -136,7 +119,8 @@ public class App extends Application {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
getApplicationContext());
final String key = getApplicationContext().getString(R.string.recaptcha_cookies_key);
downloader.setCookies(prefs.getString(key, ""));
downloader.setCookie(ReCaptchaActivity.RECAPTCHA_COOKIES_KEY, prefs.getString(key, ""));
downloader.updateYoutubeRestrictedModeCookies(getApplicationContext());
}
private void configureRxJavaErrorHandler() {
@@ -218,7 +202,7 @@ public class App extends Application {
private void initACRA() {
try {
final ACRAConfiguration acraConfig = new ConfigurationBuilder(this)
final CoreConfiguration acraConfig = new CoreConfigurationBuilder(this)
.setReportSenderFactoryClasses(REPORT_SENDER_FACTORY_CLASSES)
.setBuildConfigClass(BuildConfig.class)
.build();
@@ -279,10 +263,6 @@ public class App extends Application {
appUpdateNotificationManager.createNotificationChannel(appUpdateChannel);
}
protected RefWatcher installLeakCanary() {
return RefWatcher.DISABLED;
}
protected boolean isDisposedRxExceptionsReported() {
return false;
}

View File

@@ -11,10 +11,10 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.squareup.leakcanary.RefWatcher;
import icepick.Icepick;
import icepick.State;
import leakcanary.AppWatcher;
public abstract class BaseFragment extends Fragment {
public static final ImageLoader IMAGE_LOADER = ImageLoader.getInstance();
@@ -78,16 +78,14 @@ public abstract class BaseFragment extends Fragment {
Icepick.saveInstanceState(this, outState);
}
protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) { }
protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) {
}
@Override
public void onDestroy() {
super.onDestroy();
RefWatcher refWatcher = App.getRefWatcher(getActivity());
if (refWatcher != null) {
refWatcher.watch(this);
}
AppWatcher.INSTANCE.getObjectWatcher().watch(this);
}
@Override
@@ -100,9 +98,11 @@ public abstract class BaseFragment extends Fragment {
// Init
//////////////////////////////////////////////////////////////////////////*/
protected void initViews(final View rootView, final Bundle savedInstanceState) { }
protected void initViews(final View rootView, final Bundle savedInstanceState) {
}
protected void initListeners() { }
protected void initListeners() {
}
/*//////////////////////////////////////////////////////////////////////////
// Utils

View File

@@ -1,7 +1,8 @@
package org.schabi.newpipe;
import android.content.Context;
import android.os.Build;
import android.text.TextUtils;
import android.preference.PreferenceManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -10,6 +11,8 @@ import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.extractor.downloader.Request;
import org.schabi.newpipe.extractor.downloader.Response;
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipe.util.CookieUtils;
import org.schabi.newpipe.util.InfoCache;
import org.schabi.newpipe.util.TLSSocketFactoryCompat;
import java.io.IOException;
@@ -20,6 +23,7 @@ import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@@ -40,9 +44,13 @@ import static org.schabi.newpipe.MainActivity.DEBUG;
public final class DownloaderImpl extends Downloader {
public static final String USER_AGENT
= "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Firefox/68.0";
public static final String YOUTUBE_RESTRICTED_MODE_COOKIE_KEY
= "youtube_restricted_mode_key";
public static final String YOUTUBE_RESTRICTED_MODE_COOKIE = "PREF=f2=8000000";
public static final String YOUTUBE_DOMAIN = "youtube.com";
private static DownloaderImpl instance;
private String mCookies;
private Map<String, String> mCookies;
private OkHttpClient client;
private DownloaderImpl(final OkHttpClient.Builder builder) {
@@ -54,6 +62,7 @@ public final class DownloaderImpl extends Downloader {
// .cache(new Cache(new File(context.getExternalCacheDir(), "okhttp"),
// 16 * 1024 * 1024))
.build();
this.mCookies = new HashMap<>();
}
/**
@@ -121,12 +130,50 @@ public final class DownloaderImpl extends Downloader {
}
}
public String getCookies() {
return mCookies;
public String getCookies(final String url) {
List<String> resultCookies = new ArrayList<>();
if (url.contains(YOUTUBE_DOMAIN)) {
String youtubeCookie = getCookie(YOUTUBE_RESTRICTED_MODE_COOKIE_KEY);
if (youtubeCookie != null) {
resultCookies.add(youtubeCookie);
}
}
// Recaptcha cookie is always added TODO: not sure if this is necessary
String recaptchaCookie = getCookie(ReCaptchaActivity.RECAPTCHA_COOKIES_KEY);
if (recaptchaCookie != null) {
resultCookies.add(recaptchaCookie);
}
return CookieUtils.concatCookies(resultCookies);
}
public void setCookies(final String cookies) {
mCookies = cookies;
public String getCookie(final String key) {
return mCookies.get(key);
}
public void setCookie(final String key, final String cookie) {
mCookies.put(key, cookie);
}
public void removeCookie(final String key) {
mCookies.remove(key);
}
public void updateYoutubeRestrictedModeCookies(final Context context) {
String restrictedModeEnabledKey =
context.getString(R.string.youtube_restricted_mode_enabled);
boolean restrictedModeEnabled = PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(restrictedModeEnabledKey, false);
updateYoutubeRestrictedModeCookies(restrictedModeEnabled);
}
public void updateYoutubeRestrictedModeCookies(final boolean youtubeRestrictedModeEnabled) {
if (youtubeRestrictedModeEnabled) {
setCookie(YOUTUBE_RESTRICTED_MODE_COOKIE_KEY,
YOUTUBE_RESTRICTED_MODE_COOKIE);
} else {
removeCookie(YOUTUBE_RESTRICTED_MODE_COOKIE_KEY);
}
InfoCache.getInstance().clearCache();
}
/**
@@ -152,8 +199,9 @@ public final class DownloaderImpl extends Downloader {
.method("GET", null).url(siteUrl)
.addHeader("User-Agent", USER_AGENT);
if (!TextUtils.isEmpty(mCookies)) {
requestBuilder.addHeader("Cookie", mCookies);
String cookies = getCookies(siteUrl);
if (!cookies.isEmpty()) {
requestBuilder.addHeader("Cookie", cookies);
}
final okhttp3.Request request = requestBuilder.build();
@@ -192,8 +240,9 @@ public final class DownloaderImpl extends Downloader {
.method(httpMethod, requestBody).url(url)
.addHeader("User-Agent", USER_AGENT);
if (!TextUtils.isEmpty(mCookies)) {
requestBuilder.addHeader("Cookie", mCookies);
String cookies = getCookies(url);
if (!cookies.isEmpty()) {
requestBuilder.addHeader("Cookie", cookies);
}
for (Map.Entry<String, List<String>> pair : headers.entrySet()) {

View File

@@ -165,7 +165,7 @@ public class MainActivity extends AppCompatActivity {
drawerItems.getMenu()
.add(R.id.menu_tabs_group, kioskId, 0, KioskTranslator
.getTranslatedKioskName(ks, this))
.setIcon(KioskTranslator.getKioskIcons(ks, this));
.setIcon(KioskTranslator.getKioskIcon(ks, this));
kioskId++;
}
@@ -175,24 +175,24 @@ public class MainActivity extends AppCompatActivity {
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_channel));
drawerItems.getMenu()
.add(R.id.menu_tabs_group, ITEM_ID_FEED, ORDER, R.string.fragment_feed_title)
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.rss));
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_rss));
drawerItems.getMenu()
.add(R.id.menu_tabs_group, ITEM_ID_BOOKMARKS, ORDER, R.string.tab_bookmarks)
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_bookmark));
drawerItems.getMenu()
.add(R.id.menu_tabs_group, ITEM_ID_DOWNLOADS, ORDER, R.string.downloads)
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.download));
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_file_download));
drawerItems.getMenu()
.add(R.id.menu_tabs_group, ITEM_ID_HISTORY, ORDER, R.string.action_history)
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.history));
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_history));
//Settings and About
drawerItems.getMenu()
.add(R.id.menu_options_about_group, ITEM_ID_SETTINGS, ORDER, R.string.settings)
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.settings));
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_settings));
drawerItems.getMenu()
.add(R.id.menu_options_about_group, ITEM_ID_ABOUT, ORDER, R.string.tab_about)
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.info));
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_info_outline));
toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.drawer_open,
R.string.drawer_close);
@@ -420,7 +420,7 @@ public class MainActivity extends AppCompatActivity {
drawerItems.getMenu()
.add(R.id.menu_tabs_group, kioskId, ORDER,
KioskTranslator.getTranslatedKioskName(ks, this))
.setIcon(KioskTranslator.getKioskIcons(ks, this));
.setIcon(KioskTranslator.getKioskIcon(ks, this));
kioskId++;
}
@@ -429,24 +429,24 @@ public class MainActivity extends AppCompatActivity {
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_channel));
drawerItems.getMenu()
.add(R.id.menu_tabs_group, ITEM_ID_FEED, ORDER, R.string.fragment_feed_title)
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.rss));
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_rss));
drawerItems.getMenu()
.add(R.id.menu_tabs_group, ITEM_ID_BOOKMARKS, ORDER, R.string.tab_bookmarks)
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_bookmark));
drawerItems.getMenu()
.add(R.id.menu_tabs_group, ITEM_ID_DOWNLOADS, ORDER, R.string.downloads)
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.download));
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_file_download));
drawerItems.getMenu()
.add(R.id.menu_tabs_group, ITEM_ID_HISTORY, ORDER, R.string.action_history)
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.history));
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_history));
//Settings and About
drawerItems.getMenu()
.add(R.id.menu_options_about_group, ITEM_ID_SETTINGS, ORDER, R.string.settings)
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.settings));
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_settings));
drawerItems.getMenu()
.add(R.id.menu_options_about_group, ITEM_ID_ABOUT, ORDER, R.string.tab_about)
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.info));
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_info_outline));
}
@Override

View File

@@ -51,6 +51,7 @@ public class ReCaptchaActivity extends AppCompatActivity {
public static final String RECAPTCHA_URL_EXTRA = "recaptcha_url_extra";
public static final String TAG = ReCaptchaActivity.class.toString();
public static final String YT_URL = "https://www.youtube.com";
public static final String RECAPTCHA_COOKIES_KEY = "recaptcha_cookies";
private WebView webView;
private String foundCookies = "";
@@ -168,7 +169,7 @@ public class ReCaptchaActivity extends AppCompatActivity {
prefs.edit().putString(key, foundCookies).apply();
// give cookies to Downloader class
DownloaderImpl.getInstance().setCookies(foundCookies);
DownloaderImpl.getInstance().setCookie(RECAPTCHA_COOKIES_KEY, foundCookies);
setResult(RESULT_OK);
}

View File

@@ -25,6 +25,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.app.NotificationCompat;
import androidx.fragment.app.FragmentManager;
@@ -43,15 +44,15 @@ import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.AndroidTvUtils;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.AndroidTvUtils;
import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PermissionHelper;
import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.views.FocusOverlayView;
import org.schabi.newpipe.util.urlfinder.UrlFinder;
import org.schabi.newpipe.views.FocusOverlayView;
import java.io.Serializable;
import java.util.ArrayList;
@@ -313,7 +314,9 @@ public class RouterActivity extends AppCompatActivity {
final RadioButton radioButton
= (RadioButton) inflater.inflate(R.layout.list_radio_icon_item, null);
radioButton.setText(item.description);
radioButton.setCompoundDrawablesWithIntrinsicBounds(item.icon, 0, 0, 0);
radioButton.setCompoundDrawablesWithIntrinsicBounds(
AppCompatResources.getDrawable(getApplicationContext(), item.icon),
null, null, null);
radioButton.setChecked(false);
radioButton.setId(id++);
radioButton.setLayoutParams(new RadioGroup.LayoutParams(
@@ -366,26 +369,26 @@ public class RouterActivity extends AppCompatActivity {
returnList.add(new AdapterChoiceItem(getString(R.string.show_info_key),
getString(R.string.show_info),
resolveResourceIdFromAttr(context, R.attr.info)));
resolveResourceIdFromAttr(context, R.attr.ic_info_outline)));
if (capabilities.contains(VIDEO) && !(isExtVideoEnabled && linkType != LinkType.STREAM)) {
returnList.add(new AdapterChoiceItem(getString(R.string.video_player_key),
getString(R.string.video_player),
resolveResourceIdFromAttr(context, R.attr.play)));
resolveResourceIdFromAttr(context, R.attr.ic_play_arrow)));
returnList.add(new AdapterChoiceItem(getString(R.string.popup_player_key),
getString(R.string.popup_player),
resolveResourceIdFromAttr(context, R.attr.popup)));
resolveResourceIdFromAttr(context, R.attr.ic_popup)));
}
if (capabilities.contains(AUDIO) && !(isExtAudioEnabled && linkType != LinkType.STREAM)) {
returnList.add(new AdapterChoiceItem(getString(R.string.background_player_key),
getString(R.string.background_player),
resolveResourceIdFromAttr(context, R.attr.audio)));
resolveResourceIdFromAttr(context, R.attr.ic_headset)));
}
returnList.add(new AdapterChoiceItem(getString(R.string.download_key),
getString(R.string.download),
resolveResourceIdFromAttr(context, R.attr.download)));
resolveResourceIdFromAttr(context, R.attr.ic_file_download)));
return returnList;
}

View File

@@ -2,8 +2,6 @@ package org.schabi.newpipe.about;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.LayoutInflater;
@@ -17,9 +15,9 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import org.schabi.newpipe.R;
import org.schabi.newpipe.util.ShareUtils;
import java.util.Arrays;
import java.util.Comparator;
/**
* Fragment containing the software licenses.
@@ -27,7 +25,7 @@ import java.util.Comparator;
public class LicenseFragment extends Fragment {
private static final String ARG_COMPONENTS = "components";
private SoftwareComponent[] softwareComponents;
private SoftwareComponent mComponentForContextMenu;
private SoftwareComponent componentForContextMenu;
public static LicenseFragment newInstance(final SoftwareComponent[] softwareComponents) {
if (softwareComponents == null) {
@@ -46,7 +44,7 @@ public class LicenseFragment extends Fragment {
* @param context the context to use
* @param license the license to show
*/
public static void showLicense(final Context context, final License license) {
private static void showLicense(final Context context, final License license) {
new LicenseFragmentHelper((Activity) context).execute(license);
}
@@ -57,45 +55,34 @@ public class LicenseFragment extends Fragment {
.getParcelableArray(ARG_COMPONENTS);
// Sort components by name
Arrays.sort(softwareComponents, new Comparator<SoftwareComponent>() {
@Override
public int compare(final SoftwareComponent o1, final SoftwareComponent o2) {
return o1.getName().compareTo(o2.getName());
}
});
Arrays.sort(softwareComponents, (o1, o2) -> o1.getName().compareTo(o2.getName()));
}
@Nullable
@Override
public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container,
@Nullable final Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_licenses, container, false);
ViewGroup softwareComponentsView = rootView.findViewById(R.id.software_components);
final View rootView = inflater.inflate(R.layout.fragment_licenses, container, false);
final ViewGroup softwareComponentsView = rootView.findViewById(R.id.software_components);
View licenseLink = rootView.findViewById(R.id.app_read_license);
licenseLink.setOnClickListener(new OnReadFullLicenseClickListener());
final View licenseLink = rootView.findViewById(R.id.app_read_license);
licenseLink.setOnClickListener(v ->
showLicense(getActivity(), StandardLicenses.GPL3));
for (final SoftwareComponent component : softwareComponents) {
View componentView = inflater
final View componentView = inflater
.inflate(R.layout.item_software_component, container, false);
TextView softwareName = componentView.findViewById(R.id.name);
TextView copyright = componentView.findViewById(R.id.copyright);
final TextView softwareName = componentView.findViewById(R.id.name);
final TextView copyright = componentView.findViewById(R.id.copyright);
softwareName.setText(component.getName());
copyright.setText(getContext().getString(R.string.copyright,
copyright.setText(getString(R.string.copyright,
component.getYears(),
component.getCopyrightOwner(),
component.getLicense().getAbbreviation()));
componentView.setTag(component);
componentView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
Context context = v.getContext();
if (context != null) {
showLicense(context, component.getLicense());
}
}
});
componentView.setOnClickListener(v ->
showLicense(getActivity(), component.getLicense()));
softwareComponentsView.addView(componentView);
registerForContextMenu(componentView);
}
@@ -105,40 +92,28 @@ public class LicenseFragment extends Fragment {
@Override
public void onCreateContextMenu(final ContextMenu menu, final View v,
final ContextMenu.ContextMenuInfo menuInfo) {
MenuInflater inflater = getActivity().getMenuInflater();
SoftwareComponent component = (SoftwareComponent) v.getTag();
final MenuInflater inflater = getActivity().getMenuInflater();
final SoftwareComponent component = (SoftwareComponent) v.getTag();
menu.setHeaderTitle(component.getName());
inflater.inflate(R.menu.software_component, menu);
super.onCreateContextMenu(menu, v, menuInfo);
mComponentForContextMenu = (SoftwareComponent) v.getTag();
componentForContextMenu = (SoftwareComponent) v.getTag();
}
@Override
public boolean onContextItemSelected(final MenuItem item) {
// item.getMenuInfo() is null so we use the tag of the view
final SoftwareComponent component = mComponentForContextMenu;
final SoftwareComponent component = componentForContextMenu;
if (component == null) {
return false;
}
switch (item.getItemId()) {
case R.id.action_website:
openWebsite(component.getLink());
ShareUtils.openUrlInBrowser(getActivity(), component.getLink());
return true;
case R.id.action_show_license:
showLicense(getContext(), component.getLicense());
showLicense(getActivity(), component.getLicense());
}
return false;
}
private void openWebsite(final String componentLink) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(componentLink));
startActivity(browserIntent);
}
private static class OnReadFullLicenseClickListener implements View.OnClickListener {
@Override
public void onClick(final View v) {
LicenseFragment.showLicense(v.getContext(), StandardLicenses.GPL3);
}
}
}

View File

@@ -3,8 +3,10 @@ package org.schabi.newpipe.about;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Base64;
import android.webkit.WebView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
@@ -12,6 +14,7 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.util.ThemeHelper;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
import java.nio.charset.StandardCharsets;
@@ -26,28 +29,18 @@ public class LicenseFragmentHelper extends AsyncTask<Object, Void, Integer> {
weakReference = new WeakReference<>(activity);
}
private static String getFinishString(final Activity activity) {
return activity.getApplicationContext().getResources().getString(R.string.finish);
}
/**
* @param context the context to use
* @param license the license
* @return String which contains a HTML formatted license page
* styled according to the context's theme
*/
public static String getFormattedLicense(final Context context, final License license) {
if (context == null) {
throw new NullPointerException("context is null");
}
if (license == null) {
throw new NullPointerException("license is null");
}
StringBuilder licenseContent = new StringBuilder();
String webViewData;
private static String getFormattedLicense(@NonNull final Context context,
@NonNull final License license) {
final StringBuilder licenseContent = new StringBuilder();
final String webViewData;
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
final BufferedReader in = new BufferedReader(new InputStreamReader(
context.getAssets().open(license.getFilename()), StandardCharsets.UTF_8));
String str;
while ((str = in.readLine()) != null) {
@@ -56,13 +49,11 @@ public class LicenseFragmentHelper extends AsyncTask<Object, Void, Integer> {
in.close();
// split the HTML file and insert the stylesheet into the HEAD of the file
String[] insert = licenseContent.toString().split("</head>");
webViewData = insert[0] + "<style type=\"text/css\">"
+ getLicenseStylesheet(context) + "</style></head>"
+ insert[1];
} catch (Exception e) {
throw new NullPointerException("could not get license file:"
+ getLicenseStylesheet(context));
webViewData = licenseContent.toString().replace("</head>",
"<style>" + getLicenseStylesheet(context) + "</style></head>");
} catch (IOException e) {
throw new IllegalArgumentException(
"Could not get license file: " + license.getFilename(), e);
}
return webViewData;
}
@@ -71,21 +62,19 @@ public class LicenseFragmentHelper extends AsyncTask<Object, Void, Integer> {
* @param context
* @return String which is a CSS stylesheet according to the context's theme
*/
public static String getLicenseStylesheet(final Context context) {
boolean isLightTheme = ThemeHelper.isLightThemeSelected(context);
return "body{padding:12px 15px;margin:0;background:#"
+ getHexRGBColor(context, isLightTheme
private static String getLicenseStylesheet(final Context context) {
final boolean isLightTheme = ThemeHelper.isLightThemeSelected(context);
return "body{padding:12px 15px;margin:0;"
+ "background:#" + getHexRGBColor(context, isLightTheme
? R.color.light_license_background_color
: R.color.dark_license_background_color)
+ ";color:#"
+ getHexRGBColor(context, isLightTheme
: R.color.dark_license_background_color) + ";"
+ "color:#" + getHexRGBColor(context, isLightTheme
? R.color.light_license_text_color
: R.color.dark_license_text_color) + ";}"
+ "a[href]{color:#"
+ getHexRGBColor(context, isLightTheme
: R.color.dark_license_text_color) + "}"
+ "a[href]{color:#" + getHexRGBColor(context, isLightTheme
? R.color.light_youtube_primary_color
: R.color.dark_youtube_primary_color) + ";}"
+ "pre{white-space: pre-wrap;}";
: R.color.dark_youtube_primary_color) + "}"
+ "pre{white-space:pre-wrap}";
}
/**
@@ -95,13 +84,13 @@ public class LicenseFragmentHelper extends AsyncTask<Object, Void, Integer> {
* @param color the color number from R.color
* @return a six characters long String with hexadecimal RGB values
*/
public static String getHexRGBColor(final Context context, final int color) {
private static String getHexRGBColor(final Context context, final int color) {
return context.getResources().getString(color).substring(3);
}
@Nullable
private Activity getActivity() {
Activity activity = weakReference.get();
final Activity activity = weakReference.get();
if (activity != null && activity.isFinishing()) {
return null;
@@ -118,22 +107,22 @@ public class LicenseFragmentHelper extends AsyncTask<Object, Void, Integer> {
@Override
protected void onPostExecute(final Integer result) {
Activity activity = getActivity();
final Activity activity = getActivity();
if (activity == null) {
return;
}
String webViewData = getFormattedLicense(activity, license);
AlertDialog.Builder alert = new AlertDialog.Builder(activity);
final String webViewData = Base64.encodeToString(getFormattedLicense(activity, license)
.getBytes(StandardCharsets.UTF_8), Base64.NO_PADDING);
final WebView webView = new WebView(activity);
webView.loadData(webViewData, "text/html; charset=UTF-8", "base64");
final AlertDialog.Builder alert = new AlertDialog.Builder(activity);
alert.setTitle(license.getName());
WebView wv = new WebView(activity);
wv.loadData(webViewData, "text/html; charset=UTF-8", null);
alert.setView(wv);
assureCorrectAppLanguage(activity.getApplicationContext());
alert.setNegativeButton(getFinishString(activity), (dialog, which) -> dialog.dismiss());
alert.setView(webView);
assureCorrectAppLanguage(activity);
alert.setNegativeButton(activity.getString(R.string.finish),
(dialog, which) -> dialog.dismiss());
alert.show();
}
}

View File

@@ -1,12 +1,17 @@
package org.schabi.newpipe.database.feed.dao
import androidx.room.*
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update
import io.reactivex.Flowable
import java.util.Date
import org.schabi.newpipe.database.feed.model.FeedEntity
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity
import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.database.subscription.SubscriptionEntity
import java.util.*
@Dao
abstract class FeedDAO {

View File

@@ -1,6 +1,11 @@
package org.schabi.newpipe.database.feed.dao
import androidx.room.*
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update
import io.reactivex.Flowable
import io.reactivex.Maybe
import org.schabi.newpipe.database.feed.model.FeedGroupEntity

View File

@@ -27,11 +27,11 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity
]
)
data class FeedEntity(
@ColumnInfo(name = STREAM_ID)
var streamId: Long,
@ColumnInfo(name = STREAM_ID)
var streamId: Long,
@ColumnInfo(name = SUBSCRIPTION_ID)
var subscriptionId: Long
@ColumnInfo(name = SUBSCRIPTION_ID)
var subscriptionId: Long
) {
companion object {
@@ -40,4 +40,4 @@ data class FeedEntity(
const val STREAM_ID = "stream_id"
const val SUBSCRIPTION_ID = "subscription_id"
}
}
}

View File

@@ -13,18 +13,18 @@ import org.schabi.newpipe.local.subscription.FeedGroupIcon
indices = [Index(SORT_ORDER)]
)
data class FeedGroupEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = ID)
val uid: Long,
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = ID)
val uid: Long,
@ColumnInfo(name = NAME)
var name: String,
@ColumnInfo(name = NAME)
var name: String,
@ColumnInfo(name = ICON)
var icon: FeedGroupIcon,
@ColumnInfo(name = ICON)
var icon: FeedGroupIcon,
@ColumnInfo(name = SORT_ORDER)
var sortOrder: Long = -1
@ColumnInfo(name = SORT_ORDER)
var sortOrder: Long = -1
) {
companion object {
const val FEED_GROUP_TABLE = "feed_group"
@@ -36,4 +36,4 @@ data class FeedGroupEntity(
const val GROUP_ALL_ID = -1L
}
}
}

View File

@@ -29,11 +29,11 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity
]
)
data class FeedGroupSubscriptionEntity(
@ColumnInfo(name = GROUP_ID)
var feedGroupId: Long,
@ColumnInfo(name = GROUP_ID)
var feedGroupId: Long,
@ColumnInfo(name = SUBSCRIPTION_ID)
var subscriptionId: Long
@ColumnInfo(name = SUBSCRIPTION_ID)
var subscriptionId: Long
) {
companion object {
@@ -42,4 +42,4 @@ data class FeedGroupSubscriptionEntity(
const val GROUP_ID = "group_id"
const val SUBSCRIPTION_ID = "subscription_id"
}
}
}

View File

@@ -4,10 +4,10 @@ import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey
import java.util.Date
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity.Companion.FEED_LAST_UPDATED_TABLE
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity.Companion.SUBSCRIPTION_ID
import org.schabi.newpipe.database.subscription.SubscriptionEntity
import java.util.*
@Entity(
tableName = FEED_LAST_UPDATED_TABLE,
@@ -20,12 +20,12 @@ import java.util.*
]
)
data class FeedLastUpdatedEntity(
@PrimaryKey
@ColumnInfo(name = SUBSCRIPTION_ID)
var subscriptionId: Long,
@PrimaryKey
@ColumnInfo(name = SUBSCRIPTION_ID)
var subscriptionId: Long,
@ColumnInfo(name = LAST_UPDATED)
var lastUpdated: Date? = null
@ColumnInfo(name = LAST_UPDATED)
var lastUpdated: Date? = null
) {
companion object {
@@ -34,4 +34,4 @@ data class FeedLastUpdatedEntity(
const val SUBSCRIPTION_ID = "subscription_id"
const val LAST_UPDATED = "last_updated"
}
}
}

View File

@@ -2,21 +2,21 @@ package org.schabi.newpipe.database.history.model
import androidx.room.ColumnInfo
import androidx.room.Embedded
import java.util.Date
import org.schabi.newpipe.database.stream.model.StreamEntity
import java.util.*
data class StreamHistoryEntry(
@Embedded
val streamEntity: StreamEntity,
@Embedded
val streamEntity: StreamEntity,
@ColumnInfo(name = StreamHistoryEntity.JOIN_STREAM_ID)
val streamId: Long,
@ColumnInfo(name = StreamHistoryEntity.JOIN_STREAM_ID)
val streamId: Long,
@ColumnInfo(name = StreamHistoryEntity.STREAM_ACCESS_DATE)
val accessDate: Date,
@ColumnInfo(name = StreamHistoryEntity.STREAM_ACCESS_DATE)
val accessDate: Date,
@ColumnInfo(name = StreamHistoryEntity.STREAM_REPEAT_COUNT)
val repeatCount: Long
@ColumnInfo(name = StreamHistoryEntity.STREAM_REPEAT_COUNT)
val repeatCount: Long
) {
fun toStreamHistoryEntity(): StreamHistoryEntity {

View File

@@ -8,14 +8,14 @@ import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.extractor.stream.StreamInfoItem
class PlaylistStreamEntry(
@Embedded
val streamEntity: StreamEntity,
@Embedded
val streamEntity: StreamEntity,
@ColumnInfo(name = PlaylistStreamEntity.JOIN_STREAM_ID)
val streamId: Long,
@ColumnInfo(name = PlaylistStreamEntity.JOIN_STREAM_ID)
val streamId: Long,
@ColumnInfo(name = PlaylistStreamEntity.JOIN_INDEX)
val joinIndex: Int
@ColumnInfo(name = PlaylistStreamEntity.JOIN_INDEX)
val joinIndex: Int
) : LocalItem {
@Throws(IllegalArgumentException::class)

View File

@@ -2,24 +2,24 @@ package org.schabi.newpipe.database.stream
import androidx.room.ColumnInfo
import androidx.room.Embedded
import java.util.Date
import org.schabi.newpipe.database.LocalItem
import org.schabi.newpipe.database.history.model.StreamHistoryEntity
import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.extractor.stream.StreamInfoItem
import java.util.*
class StreamStatisticsEntry(
@Embedded
val streamEntity: StreamEntity,
@Embedded
val streamEntity: StreamEntity,
@ColumnInfo(name = StreamHistoryEntity.JOIN_STREAM_ID)
val streamId: Long,
@ColumnInfo(name = StreamHistoryEntity.JOIN_STREAM_ID)
val streamId: Long,
@ColumnInfo(name = STREAM_LATEST_DATE)
val latestAccessDate: Date,
@ColumnInfo(name = STREAM_LATEST_DATE)
val latestAccessDate: Date,
@ColumnInfo(name = STREAM_WATCH_COUNT)
val watchCount: Long
@ColumnInfo(name = STREAM_WATCH_COUNT)
val watchCount: Long
) : LocalItem {
fun toStreamInfoItem(): StreamInfoItem {

View File

@@ -1,15 +1,19 @@
package org.schabi.newpipe.database.stream.dao
import androidx.room.*
import androidx.room.ColumnInfo
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import io.reactivex.Flowable
import java.util.Date
import org.schabi.newpipe.database.BasicDAO
import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_ID
import org.schabi.newpipe.extractor.stream.StreamType
import org.schabi.newpipe.extractor.stream.StreamType.AUDIO_LIVE_STREAM
import org.schabi.newpipe.extractor.stream.StreamType.LIVE_STREAM
import java.util.*
import kotlin.collections.ArrayList
@Dao
abstract class StreamDAO : BasicDAO<StreamEntity> {
@@ -94,7 +98,6 @@ abstract class StreamDAO : BasicDAO<StreamEntity> {
if (existentMinimalStream.duration > 0 && newerStream.duration < 0) {
newerStream.duration = existentMinimalStream.duration
}
}
}
@@ -116,21 +119,22 @@ abstract class StreamDAO : BasicDAO<StreamEntity> {
* Minimal entry class used when comparing/updating an existent stream.
*/
internal data class StreamCompareFeed(
@ColumnInfo(name = STREAM_ID)
var uid: Long = 0,
@ColumnInfo(name = STREAM_ID)
var uid: Long = 0,
@ColumnInfo(name = StreamEntity.STREAM_TYPE)
var streamType: StreamType,
@ColumnInfo(name = StreamEntity.STREAM_TYPE)
var streamType: StreamType,
@ColumnInfo(name = StreamEntity.STREAM_TEXTUAL_UPLOAD_DATE)
var textualUploadDate: String? = null,
@ColumnInfo(name = StreamEntity.STREAM_TEXTUAL_UPLOAD_DATE)
var textualUploadDate: String? = null,
@ColumnInfo(name = StreamEntity.STREAM_UPLOAD_DATE)
var uploadDate: Date? = null,
@ColumnInfo(name = StreamEntity.STREAM_UPLOAD_DATE)
var uploadDate: Date? = null,
@ColumnInfo(name = StreamEntity.STREAM_IS_UPLOAD_DATE_APPROXIMATION)
var isUploadDateApproximation: Boolean? = null,
@ColumnInfo(name = StreamEntity.STREAM_IS_UPLOAD_DATE_APPROXIMATION)
var isUploadDateApproximation: Boolean? = null,
@ColumnInfo(name = StreamEntity.STREAM_DURATION)
var duration: Long)
@ColumnInfo(name = StreamEntity.STREAM_DURATION)
var duration: Long
)
}

View File

@@ -1,6 +1,13 @@
package org.schabi.newpipe.database.stream.model
import androidx.room.*
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.Index
import androidx.room.PrimaryKey
import java.io.Serializable
import java.util.Calendar
import java.util.Date
import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_SERVICE_ID
import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_TABLE
import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_URL
@@ -9,8 +16,6 @@ import org.schabi.newpipe.extractor.stream.StreamInfo
import org.schabi.newpipe.extractor.stream.StreamInfoItem
import org.schabi.newpipe.extractor.stream.StreamType
import org.schabi.newpipe.player.playqueue.PlayQueueItem
import java.io.Serializable
import java.util.*
@Entity(tableName = STREAM_TABLE,
indices = [
@@ -18,42 +23,42 @@ import java.util.*
]
)
data class StreamEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = STREAM_ID)
var uid: Long = 0,
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = STREAM_ID)
var uid: Long = 0,
@ColumnInfo(name = STREAM_SERVICE_ID)
var serviceId: Int,
@ColumnInfo(name = STREAM_SERVICE_ID)
var serviceId: Int,
@ColumnInfo(name = STREAM_URL)
var url: String,
@ColumnInfo(name = STREAM_URL)
var url: String,
@ColumnInfo(name = STREAM_TITLE)
var title: String,
@ColumnInfo(name = STREAM_TITLE)
var title: String,
@ColumnInfo(name = STREAM_TYPE)
var streamType: StreamType,
@ColumnInfo(name = STREAM_TYPE)
var streamType: StreamType,
@ColumnInfo(name = STREAM_DURATION)
var duration: Long,
@ColumnInfo(name = STREAM_DURATION)
var duration: Long,
@ColumnInfo(name = STREAM_UPLOADER)
var uploader: String,
@ColumnInfo(name = STREAM_UPLOADER)
var uploader: String,
@ColumnInfo(name = STREAM_THUMBNAIL_URL)
var thumbnailUrl: String? = null,
@ColumnInfo(name = STREAM_THUMBNAIL_URL)
var thumbnailUrl: String? = null,
@ColumnInfo(name = STREAM_VIEWS)
var viewCount: Long? = null,
@ColumnInfo(name = STREAM_VIEWS)
var viewCount: Long? = null,
@ColumnInfo(name = STREAM_TEXTUAL_UPLOAD_DATE)
var textualUploadDate: String? = null,
@ColumnInfo(name = STREAM_TEXTUAL_UPLOAD_DATE)
var textualUploadDate: String? = null,
@ColumnInfo(name = STREAM_UPLOAD_DATE)
var uploadDate: Date? = null,
@ColumnInfo(name = STREAM_UPLOAD_DATE)
var uploadDate: Date? = null,
@ColumnInfo(name = STREAM_IS_UPLOAD_DATE_APPROXIMATION)
var isUploadDateApproximation: Boolean? = null
@ColumnInfo(name = STREAM_IS_UPLOAD_DATE_APPROXIMATION)
var isUploadDateApproximation: Boolean? = null
) : Serializable {
@Ignore

View File

@@ -1,6 +1,10 @@
package org.schabi.newpipe.database.subscription
import androidx.room.*
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import io.reactivex.Flowable
import io.reactivex.Maybe
import org.schabi.newpipe.database.BasicDAO

View File

@@ -396,13 +396,11 @@ public class DownloadDialog extends DialogFragment
Log.d(TAG, "initToolbar() called with: toolbar = [" + toolbar + "]");
}
boolean isLight = ThemeHelper.isLightThemeSelected(getActivity());
toolbar.setTitle(R.string.download_dialog_title);
toolbar.setNavigationIcon(isLight ? R.drawable.ic_arrow_back_black_24dp
: R.drawable.ic_arrow_back_white_24dp);
toolbar.setNavigationIcon(
ThemeHelper.resolveResourceIdFromAttr(requireContext(), R.attr.ic_arrow_back));
toolbar.inflateMenu(R.menu.dialog_url);
toolbar.setNavigationOnClickListener(v -> getDialog().dismiss());
toolbar.setNavigationOnClickListener(v -> requireDialog().dismiss());
toolbar.setNavigationContentDescription(R.string.cancel);
okButton = toolbar.findViewById(R.id.okay);

View File

@@ -1,7 +1,9 @@
package org.schabi.newpipe.fragments;
import android.content.Context;
import android.content.res.ColorStateList;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -30,6 +32,7 @@ import org.schabi.newpipe.settings.tabs.Tab;
import org.schabi.newpipe.settings.tabs.TabsManager;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.ServiceHelper;
import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.views.ScrollableTabLayout;
import java.util.ArrayList;
@@ -45,6 +48,9 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
private boolean hasTabsChanged = false;
private boolean previousYoutubeRestrictedModeEnabled;
private String youtubeRestrictedModeEnabledKey;
/*//////////////////////////////////////////////////////////////////////////
// Fragment's LifeCycle
//////////////////////////////////////////////////////////////////////////*/
@@ -53,7 +59,6 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
tabsManager = TabsManager.getManager(activity);
tabsManager.setSavedTabsListener(() -> {
if (DEBUG) {
@@ -66,6 +71,11 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
hasTabsChanged = true;
}
});
youtubeRestrictedModeEnabledKey = getString(R.string.youtube_restricted_mode_enabled);
previousYoutubeRestrictedModeEnabled =
PreferenceManager.getDefaultSharedPreferences(getContext())
.getBoolean(youtubeRestrictedModeEnabledKey, false);
}
@Override
@@ -82,6 +92,8 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
tabLayout = rootView.findViewById(R.id.main_tab_layout);
viewPager = rootView.findViewById(R.id.pager);
tabLayout.setTabIconTint(ColorStateList.valueOf(
ThemeHelper.resolveColorFromAttr(requireContext(), R.attr.colorAccent)));
tabLayout.setupWithViewPager(viewPager);
tabLayout.addOnTabSelectedListener(this);
@@ -92,7 +104,13 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
public void onResume() {
super.onResume();
if (hasTabsChanged) {
boolean youtubeRestrictedModeEnabled =
PreferenceManager.getDefaultSharedPreferences(getContext())
.getBoolean(youtubeRestrictedModeEnabledKey, false);
if (previousYoutubeRestrictedModeEnabled != youtubeRestrictedModeEnabled) {
previousYoutubeRestrictedModeEnabled = youtubeRestrictedModeEnabled;
setupTabs();
} else if (hasTabsChanged) {
setupTabs();
}
}

View File

@@ -21,6 +21,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import com.jakewharton.rxbinding2.view.RxView;
@@ -38,6 +39,7 @@ import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
import org.schabi.newpipe.local.subscription.SubscriptionManager;
import org.schabi.newpipe.player.playqueue.ChannelPlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.AnimationUtils;
import org.schabi.newpipe.util.ExtractorHelper;
@@ -45,6 +47,7 @@ import org.schabi.newpipe.util.ImageDisplayConstants;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.ShareUtils;
import org.schabi.newpipe.util.ThemeHelper;
import java.util.ArrayList;
import java.util.Iterator;
@@ -65,7 +68,8 @@ import static org.schabi.newpipe.util.AnimationUtils.animateBackgroundColor;
import static org.schabi.newpipe.util.AnimationUtils.animateTextColor;
import static org.schabi.newpipe.util.AnimationUtils.animateView;
public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
implements View.OnClickListener {
private static final int BUTTON_DEBOUNCE_INTERVAL = 100;
private final CompositeDisposable disposables = new CompositeDisposable();
private Disposable subscribeButtonMonitor;
@@ -79,6 +83,8 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
private ImageView headerChannelBanner;
private ImageView headerAvatarView;
private TextView headerTitleView;
private ImageView headerSubChannelAvatarView;
private TextView headerSubChannelTitleView;
private TextView headerSubscribersTextView;
private Button headerSubscribeButton;
private View playlistCtrl;
@@ -156,7 +162,10 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
headerSubscribersTextView = headerRootLayout.findViewById(R.id.channel_subscriber_view);
headerSubscribeButton = headerRootLayout.findViewById(R.id.channel_subscribe_button);
playlistCtrl = headerRootLayout.findViewById(R.id.playlist_control);
headerSubChannelAvatarView =
headerRootLayout.findViewById(R.id.sub_channel_avatar_view);
headerSubChannelTitleView =
headerRootLayout.findViewById(R.id.sub_channel_title_view);
headerPlayAllButton = headerRootLayout.findViewById(R.id.playlist_ctrl_play_all_button);
headerPopupButton = headerRootLayout.findViewById(R.id.playlist_ctrl_play_popup_button);
@@ -165,6 +174,14 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
return headerRootLayout;
}
@Override
protected void initListeners() {
super.initListeners();
headerSubChannelTitleView.setOnClickListener(this);
headerSubChannelAvatarView.setOnClickListener(this);
}
/*//////////////////////////////////////////////////////////////////////////
// Menu
//////////////////////////////////////////////////////////////////////////*/
@@ -358,8 +375,8 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
int backgroundDuration = isButtonVisible ? 300 : 0;
int textDuration = isButtonVisible ? 200 : 0;
int subscribeBackground = ContextCompat
.getColor(activity, R.color.subscribe_background_color);
int subscribeBackground = ThemeHelper
.resolveColorFromAttr(activity, R.attr.colorPrimary);
int subscribeText = ContextCompat.getColor(activity, R.color.subscribe_text_color);
int subscribedBackground = ContextCompat
.getColor(activity, R.color.subscribed_background_color);
@@ -394,6 +411,34 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
return ExtractorHelper.getChannelInfo(serviceId, url, forceLoad);
}
/*//////////////////////////////////////////////////////////////////////////
// OnClick
//////////////////////////////////////////////////////////////////////////*/
@Override
public void onClick(final View v) {
if (isLoading.get() || currentInfo == null) {
return;
}
switch (v.getId()) {
case R.id.sub_channel_avatar_view:
case R.id.sub_channel_title_view:
if (!TextUtils.isEmpty(currentInfo.getParentChannelUrl())) {
try {
NavigationHelper.openChannelFragment(getFragmentManager(),
currentInfo.getServiceId(), currentInfo.getParentChannelUrl(),
currentInfo.getParentChannelName());
} catch (Exception e) {
ErrorActivity.reportUiError((AppCompatActivity) getActivity(), e);
}
} else if (DEBUG) {
Log.i(TAG, "Can't open parent channel because we got no channel URL");
}
break;
}
}
/*//////////////////////////////////////////////////////////////////////////
// Contract
//////////////////////////////////////////////////////////////////////////*/
@@ -404,6 +449,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
IMAGE_LOADER.cancelDisplayTask(headerChannelBanner);
IMAGE_LOADER.cancelDisplayTask(headerAvatarView);
IMAGE_LOADER.cancelDisplayTask(headerSubChannelAvatarView);
animateView(headerSubscribeButton, false, 100);
}
@@ -416,6 +462,8 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
ImageDisplayConstants.DISPLAY_BANNER_OPTIONS);
IMAGE_LOADER.displayImage(result.getAvatarUrl(), headerAvatarView,
ImageDisplayConstants.DISPLAY_AVATAR_OPTIONS);
IMAGE_LOADER.displayImage(result.getParentChannelAvatarUrl(), headerSubChannelAvatarView,
ImageDisplayConstants.DISPLAY_AVATAR_OPTIONS);
headerSubscribersTextView.setVisibility(View.VISIBLE);
if (result.getSubscriberCount() >= 0) {
@@ -425,6 +473,17 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
headerSubscribersTextView.setText(R.string.subscribers_count_not_available);
}
if (!TextUtils.isEmpty(currentInfo.getParentChannelName())) {
headerSubChannelTitleView.setText(String.format(
getString(R.string.channel_created_by),
currentInfo.getParentChannelName())
);
headerSubChannelTitleView.setVisibility(View.VISIBLE);
headerSubChannelAvatarView.setVisibility(View.VISIBLE);
} else {
headerSubChannelTitleView.setVisibility(View.GONE);
}
if (menuRssButton != null) {
menuRssButton.setVisible(!TextUtils.isEmpty(result.getFeedUrl()));
}

View File

@@ -41,12 +41,12 @@ import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.search.SearchExtractor;
import org.schabi.newpipe.extractor.search.SearchInfo;
import org.schabi.newpipe.util.AndroidTvUtils;
import org.schabi.newpipe.fragments.BackPressable;
import org.schabi.newpipe.fragments.list.BaseListFragment;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.AndroidTvUtils;
import org.schabi.newpipe.util.AnimationUtils;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.ExtractorHelper;

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