1
mirror of https://github.com/TeamNewPipe/NewPipe synced 2025-09-20 11:20:52 +02:00

Compare commits

...

286 Commits

Author SHA1 Message Date
Tobi
49429ff40a Merge pull request #10700 from TeamNewPipe/newpipe_0.26.1
Newpipe 0.26.1
2023-12-26 18:26:48 +01:00
TobiGr
3df21ad25e Bump version to 0.26.1 (996) 2023-12-26 16:59:02 +01:00
TobiGr
d0f4600be4 Add changelog for NewPipe 0.26.1 2023-12-26 16:58:49 +01:00
TobiGr
0fa2e76c3e Fix NPE when ChannelTabLHFactory not implemented for a service
Fixes #10698
2023-12-26 16:55:52 +01:00
Stypox
67629938d6 Merge pull request #10470 from TeamNewPipe/release-0.26.0
Release 0.26.0
2023-12-21 22:40:05 +01:00
Hosted Weblate
9aff49bd88 Translated using Weblate (Portuguese (Portugal))
Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Danish)

Currently translated at 88.2% (640 of 725 strings)

Translated using Weblate (Serbian)

Currently translated at 17.1% (13 of 76 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Filipino)

Currently translated at 32.1% (233 of 725 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Romanian)

Currently translated at 99.4% (721 of 725 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Indonesian)

Currently translated at 97.3% (74 of 76 strings)

Translated using Weblate (Arabic (Libya))

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (French)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Polish)

Currently translated at 61.8% (47 of 76 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 28.9% (22 of 76 strings)

Translated using Weblate (German)

Currently translated at 81.5% (62 of 76 strings)

Merge branch 'origin/dev' into Weblate.

Translated using Weblate (Bengali)

Currently translated at 78.7% (571 of 725 strings)

Translated using Weblate (Basque)

Currently translated at 95.0% (689 of 725 strings)

Translated using Weblate (Turkish)

Currently translated at 43.4% (33 of 76 strings)

Translated using Weblate (Lithuanian)

Currently translated at 92.9% (674 of 725 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 30.2% (23 of 76 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.8% (724 of 725 strings)

Translated using Weblate (Interlingua)

Currently translated at 32.0% (232 of 725 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 94.6% (686 of 725 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 94.6% (686 of 725 strings)

Translated using Weblate (Romanian)

Currently translated at 89.3% (648 of 725 strings)

Translated using Weblate (German)

Currently translated at 81.5% (62 of 76 strings)

Translated using Weblate (German)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Filipino)

Currently translated at 32.1% (233 of 725 strings)

Translated using Weblate (Filipino)

Currently translated at 32.1% (233 of 725 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Swedish)

Currently translated at 72.3% (55 of 76 strings)

Translated using Weblate (Esperanto)

Currently translated at 3.9% (3 of 76 strings)

Translated using Weblate (Swedish)

Currently translated at 99.7% (723 of 725 strings)

Translated using Weblate (Esperanto)

Currently translated at 71.0% (515 of 725 strings)

Translated using Weblate (Esperanto)

Currently translated at 2.6% (2 of 76 strings)

Translated using Weblate (Tigrinya)

Currently translated at 8.4% (61 of 725 strings)

Translated using Weblate (Vietnamese)

Currently translated at 43.4% (33 of 76 strings)

Translated using Weblate (German)

Currently translated at 81.5% (62 of 76 strings)

Translated using Weblate (Finnish)

Currently translated at 98.3% (713 of 725 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Esperanto)

Currently translated at 70.0% (508 of 725 strings)

Added translation using Weblate (English (Old))

Added translation using Weblate (Aymara)

Added translation using Weblate (English (Middle))

Added translation using Weblate (Arabic (Najdi))

Added translation using Weblate (German (Low))

Added translation using Weblate (Sicilian)

Added translation using Weblate (Kashmiri)

Added translation using Weblate (Burmese)

Translated using Weblate (Tigrinya)

Currently translated at 3.5% (26 of 725 strings)

Translated using Weblate (Georgian)

Currently translated at 91.1% (661 of 725 strings)

Translated using Weblate (French)

Currently translated at 98.8% (717 of 725 strings)

Translated using Weblate (Vietnamese)

Currently translated at 42.1% (32 of 76 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Interlingua)

Currently translated at 31.3% (227 of 725 strings)

Translated using Weblate (Vietnamese)

Currently translated at 35.5% (27 of 76 strings)

Translated using Weblate (Esperanto)

Currently translated at 69.2% (502 of 725 strings)

Translated using Weblate (Esperanto)

Currently translated at 69.2% (502 of 725 strings)

Translated using Weblate (German)

Currently translated at 81.5% (62 of 76 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Bulgarian)

Currently translated at 63.8% (463 of 725 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Esperanto)

Currently translated at 66.3% (481 of 725 strings)

Translated using Weblate (French)

Currently translated at 98.6% (715 of 725 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Turkish)

Currently translated at 31.5% (24 of 76 strings)

Translated using Weblate (Vietnamese)

Currently translated at 97.3% (706 of 725 strings)

Translated using Weblate (Swedish)

Currently translated at 98.4% (714 of 725 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Vietnamese)

Currently translated at 94.6% (686 of 725 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Chinese (Traditional, Hong Kong))

Currently translated at 21.0% (16 of 76 strings)

Translated using Weblate (Chinese (Traditional, Hong Kong))

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (French)

Currently translated at 98.2% (712 of 725 strings)

Deleted translation using Weblate (English (Middle))

Co-authored-by: /dev/urandom <dev.urandom@posteo.org>
Co-authored-by: A <ogloppi@mailbox.org>
Co-authored-by: Agnieszka C <aga_04@o2.pl>
Co-authored-by: Aitor Salaberria <trslbrr@gmail.com>
Co-authored-by: Alexthegib <traducoes@skiff.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Ans Virlis <tddakk@yahoo.com>
Co-authored-by: AudricV <AudricV@users.noreply.hosted.weblate.org>
Co-authored-by: ButterflyOfFire <boffire@users.noreply.hosted.weblate.org>
Co-authored-by: Cem TÜRKER <cemburbut@gmail.com>
Co-authored-by: Danr <mdp43140@gmail.com>
Co-authored-by: David Svane <davidcygnus@users.noreply.hosted.weblate.org>
Co-authored-by: Edward <edwardchirita@mailbox.org>
Co-authored-by: Erik Matson <erik@nextleveltranslation.com>
Co-authored-by: Fjuro <ifjuro@proton.me>
Co-authored-by: Giorgi Taba K'obakhidze <t@gtk.ge>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Ihfandi <ihfandicahyo@gmail.com>
Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com>
Co-authored-by: Jener Gomes <jenerg1@gmail.com>
Co-authored-by: Kristoffer Grundström <swedishsailfishosuser@tutanota.com>
Co-authored-by: LiftedStarfish <liftedstarfish@protonmail.com>
Co-authored-by: NEXI <nexiphotographer@gmail.com>
Co-authored-by: Napstaguy04 <brokenscreen3@gmail.com>
Co-authored-by: Nista <42772160+Nista11@users.noreply.github.com>
Co-authored-by: P.O <rasmusson.mikael@protonmail.com>
Co-authored-by: PiryusQ <piryusq@gmail.com>
Co-authored-by: Ray <ray@users.noreply.hosted.weblate.org>
Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: ShareASmile <aapshergill@gmail.com>
Co-authored-by: Software In Interlingua <softinterlingua@gmail.com>
Co-authored-by: Stypox <stypox@pm.me>
Co-authored-by: TXRdev Archive <lckphanaf9999@gmail.com>
Co-authored-by: Tmpod <tom@tmpod.dev>
Co-authored-by: TobiGr <TobiGr@users.noreply.github.com>
Co-authored-by: Translator <kvb@tuta.io>
Co-authored-by: VfBFan <VfBFan@users.noreply.hosted.weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: bittin1ddc447d824349b2 <bittin@reimu.nl>
Co-authored-by: ferarilalon <ferarilalongpt@gmail.com>
Co-authored-by: fsbat0 <fsbat@duck.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: ngocanhtve <ngocanh.tve@gmail.com>
Co-authored-by: notlin4 <iamnotlin4@gmail.com>
Co-authored-by: searinminecraft <114207889+searinminecraft@users.noreply.github.com>
Co-authored-by: sum1tookshoe <gamingwithshoe@gmail.com>
Co-authored-by: trunars <trunars@gmail.com>
Co-authored-by: İbrahim Dinç <woltytherespectful@gmail.com>
Co-authored-by: Макар Разин <makarrazin14@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ar/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/cs/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/de/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/eo/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/es/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/hi/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/id/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/it/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pa/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pl/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ru/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sr/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sv/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/tr/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/uk/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/vi/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/zh_Hant_HK/
Translation: NewPipe/Metadata
2023-12-21 22:37:00 +01:00
Stypox
5b999a88f8 Merge pull request #10673 from Stypox/transaction-too-large
Fix transaction too large in channel tab fragments
2023-12-21 22:30:22 +01:00
Stypox
482531836f Merge pull request #10670 from Stypox/feed-oom
Fix OutOfMemory when fetching feed
2023-12-21 22:29:46 +01:00
Stypox
b3c82f54df Merge pull request #10671 from Stypox/channel-main-tab-lag
Fix application lagging with many main page tabs
2023-12-21 22:28:59 +01:00
Stypox
77fa4bbe2f Update NewPipeExtractor to v0.23.1 2023-12-21 22:28:09 +01:00
Stypox
495c9850b4 Fix transaction too large for channel tab fragments 2023-12-20 23:57:43 +01:00
Stypox
c0f8d145f8 Fix lag with many channels on main page
Disable loading all tabs at once, since there can be many of them, and use default strategy of only keeping in memory the two tabs adjacent to the current tab.
2023-12-20 22:47:57 +01:00
Stypox
80f33daeeb Fix OutOfMemory when fetching feed
Reduced memory footprint of FeedUpdateInfo objects. Those objects might stay around for a while and accumulate (up to BUFFER_COUNT_BEFORE_INSERT = 20 at the moment), so in order not to fill up the memory it's better to keep as little data as possible.
Previously ChannelInfo data was stored, causing ReadyChannelTabLinkHandler objects to be also stored uselessly (and those channel tabs contain prefetched JSON data which used ~700KB of memory).
2023-12-20 20:22:45 +01:00
Stypox
a16dcb63b5 Merge pull request #10645 from Stypox/fix-fragment-manager
Fix crashes due to wrong root fragment manager
2023-12-20 12:03:24 +01:00
Stypox
b871b5d2dd Fix crashes due to wrong root fragment manager 2023-12-10 16:06:07 +01:00
Stypox
e876647af5 Update NewPipeExtractor to v0.23.0 2023-12-10 15:58:45 +01:00
Stypox
8d59812827 Fix channel avatar not loading correctly sometimes
The fix just involves removing some really outdated code (6 years ago) added in 33e29be7db (diff-38bd2cf1b92659b499c08e1cf6ac9ef384c7e13381b906f2f98c57cbb758756dR778) (blame: 9318bb5306/app/src/main/java/org/schabi/newpipe/detail/VideoItemDetailActivity.java (L778)).
What that code did was setting the 'buddy' image to the uploader avatar as a placeholder, and then setting the actual image if it existed and after it had loaded.
That code remained there up until now, but now it doesn't make sense anymore, since Picasso already takes care of setting placeholders.
The problem is, starting from #10066 the actual uploader image is set before (not after) those lines of code, making them do the wrong thing, i.e. always overwrite the currently set image.
But then why did the channel avatar image work normally sometimes?
My guess is that since Picasso loads images in the background, when opening a video from scratch setting the placeholder still happened before Picasso finished loading the image.
However when the image is already cached it's loaded much faster and therefore setting the placeholder happens after, effectively hiding the loaded image.
2023-12-10 15:12:38 +01:00
TobiGr
e39ac885de Update new version check to match new API structure
See TeamNewPipe/web-api#17
2023-12-10 15:12:38 +01:00
TobiGr
e6965622bd Fix crash with disabled thumbnails when trying to play a stream 2023-12-10 15:12:38 +01:00
TobiGr
0d8d3479e1 NewPipe 0.26.0 (995) 2023-12-10 15:12:38 +01:00
Stypox
35c1dfd145 Update changelog for NewPipe 0.26.0 (995) 2023-12-10 15:05:29 +01:00
Hosted Weblate
096115def7 Translated using Weblate (Bengali)
Currently translated at 78.7% (571 of 725 strings)

Translated using Weblate (Basque)

Currently translated at 95.0% (689 of 725 strings)

Translated using Weblate (Turkish)

Currently translated at 43.4% (33 of 76 strings)

Translated using Weblate (Lithuanian)

Currently translated at 92.9% (674 of 725 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 30.2% (23 of 76 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.8% (724 of 725 strings)

Translated using Weblate (Interlingua)

Currently translated at 32.0% (232 of 725 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 94.6% (686 of 725 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 94.6% (686 of 725 strings)

Translated using Weblate (Romanian)

Currently translated at 89.3% (648 of 725 strings)

Translated using Weblate (German)

Currently translated at 81.5% (62 of 76 strings)

Translated using Weblate (German)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Filipino)

Currently translated at 32.1% (233 of 725 strings)

Translated using Weblate (Filipino)

Currently translated at 32.1% (233 of 725 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Swedish)

Currently translated at 72.3% (55 of 76 strings)

Translated using Weblate (Esperanto)

Currently translated at 3.9% (3 of 76 strings)

Translated using Weblate (Swedish)

Currently translated at 99.7% (723 of 725 strings)

Translated using Weblate (Esperanto)

Currently translated at 71.0% (515 of 725 strings)

Translated using Weblate (Esperanto)

Currently translated at 2.6% (2 of 76 strings)

Translated using Weblate (Tigrinya)

Currently translated at 8.4% (61 of 725 strings)

Translated using Weblate (Vietnamese)

Currently translated at 43.4% (33 of 76 strings)

Translated using Weblate (German)

Currently translated at 81.5% (62 of 76 strings)

Translated using Weblate (Finnish)

Currently translated at 98.3% (713 of 725 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Esperanto)

Currently translated at 70.0% (508 of 725 strings)

Added translation using Weblate (English (Old))

Added translation using Weblate (Aymara)

Added translation using Weblate (English (Middle))

Added translation using Weblate (Arabic (Najdi))

Added translation using Weblate (German (Low))

Added translation using Weblate (Sicilian)

Added translation using Weblate (Kashmiri)

Added translation using Weblate (Burmese)

Translated using Weblate (Tigrinya)

Currently translated at 3.5% (26 of 725 strings)

Translated using Weblate (Georgian)

Currently translated at 91.1% (661 of 725 strings)

Translated using Weblate (French)

Currently translated at 98.8% (717 of 725 strings)

Translated using Weblate (Vietnamese)

Currently translated at 42.1% (32 of 76 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Interlingua)

Currently translated at 31.3% (227 of 725 strings)

Translated using Weblate (Vietnamese)

Currently translated at 35.5% (27 of 76 strings)

Translated using Weblate (Esperanto)

Currently translated at 69.2% (502 of 725 strings)

Translated using Weblate (Esperanto)

Currently translated at 69.2% (502 of 725 strings)

Translated using Weblate (German)

Currently translated at 81.5% (62 of 76 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Bulgarian)

Currently translated at 63.8% (463 of 725 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Esperanto)

Currently translated at 66.3% (481 of 725 strings)

Translated using Weblate (French)

Currently translated at 98.6% (715 of 725 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Turkish)

Currently translated at 31.5% (24 of 76 strings)

Translated using Weblate (Vietnamese)

Currently translated at 97.3% (706 of 725 strings)

Translated using Weblate (Swedish)

Currently translated at 98.4% (714 of 725 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Vietnamese)

Currently translated at 94.6% (686 of 725 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Chinese (Traditional, Hong Kong))

Currently translated at 21.0% (16 of 76 strings)

Translated using Weblate (Chinese (Traditional, Hong Kong))

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (French)

Currently translated at 98.2% (712 of 725 strings)

Deleted translation using Weblate (English (Middle))

Co-authored-by: /dev/urandom <dev.urandom@posteo.org>
Co-authored-by: A <ogloppi@mailbox.org>
Co-authored-by: Aitor Salaberria <trslbrr@gmail.com>
Co-authored-by: Alexthegib <traducoes@skiff.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Ans Virlis <tddakk@yahoo.com>
Co-authored-by: AudricV <AudricV@users.noreply.hosted.weblate.org>
Co-authored-by: Cem TÜRKER <cemburbut@gmail.com>
Co-authored-by: Edward <edwardchirita@mailbox.org>
Co-authored-by: Erik Matson <erik@nextleveltranslation.com>
Co-authored-by: Giorgi Taba K'obakhidze <t@gtk.ge>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Jener Gomes <jenerg1@gmail.com>
Co-authored-by: Kristoffer Grundström <swedishsailfishosuser@tutanota.com>
Co-authored-by: LiftedStarfish <liftedstarfish@protonmail.com>
Co-authored-by: Napstaguy04 <brokenscreen3@gmail.com>
Co-authored-by: P.O <rasmusson.mikael@protonmail.com>
Co-authored-by: PiryusQ <piryusq@gmail.com>
Co-authored-by: Ray <ray@users.noreply.hosted.weblate.org>
Co-authored-by: ShareASmile <aapshergill@gmail.com>
Co-authored-by: Software In Interlingua <softinterlingua@gmail.com>
Co-authored-by: TXRdev Archive <lckphanaf9999@gmail.com>
Co-authored-by: TobiGr <TobiGr@users.noreply.github.com>
Co-authored-by: Translator <kvb@tuta.io>
Co-authored-by: VfBFan <VfBFan@users.noreply.hosted.weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: bittin1ddc447d824349b2 <bittin@reimu.nl>
Co-authored-by: ferarilalon <ferarilalongpt@gmail.com>
Co-authored-by: fsbat0 <fsbat@duck.com>
Co-authored-by: ngocanhtve <ngocanh.tve@gmail.com>
Co-authored-by: notlin4 <iamnotlin4@gmail.com>
Co-authored-by: sum1tookshoe <gamingwithshoe@gmail.com>
Co-authored-by: trunars <trunars@gmail.com>
Co-authored-by: İbrahim Dinç <woltytherespectful@gmail.com>
Co-authored-by: Макар Разин <makarrazin14@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/de/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/eo/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ru/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sv/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/tr/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/vi/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/zh_Hant_HK/
Translation: NewPipe/Metadata
2023-12-10 14:50:31 +01:00
Stypox
e784af3e2d Merge pull request #10446 from AudricV/dl_improve_video_audio_stream_selection
Improve audio stream selection for video-only streams in the downloader
2023-12-07 16:48:57 +01:00
Stypox
ce30108efc Improve javadoc for getAudioStreamFor 2023-12-07 16:40:32 +01:00
Stypox
edbd623e21 Fix Matrix channel link
#newpipe:matrix.org is unofficial, #newpipe:libera.chat is the official one
2023-12-07 16:11:59 +01:00
Stypox
7cfd537755 Merge pull request #10494 from TobiGr/fix-new-streams
Fix notifying about old "new" streams
2023-12-07 14:12:54 +01:00
opusforlife2
ddd6d03e0b Add Matrix room link to ReadMe (#10632) 2023-12-06 18:34:43 +00:00
Tobi
b4a0e08d9d Update app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt
Co-authored-by: Stypox <stypox@pm.me>
2023-11-23 17:12:16 +01:00
Stypox
545f9ae5f3 Merge pull request #10489 from sqproman/missing_quotation_replace_char_crash
Quote filename replacement characters to fix crashes when downloading streams with special characters
2023-11-16 20:19:01 +01:00
Stypox
be4a5a5f3e Merge pull request #10576 from AudricV/fix-npe-feed-new-items-button
Fix crash when setting the masking of the new feed items button if the context is null
2023-11-16 09:02:24 +01:00
Stypox
3dc593fe88 Merge pull request #10577 from AudricV/fix-npe-play-queue-audio-track-menu
Fix crash when building the play queue audio track menu if the player is null
2023-11-16 09:01:11 +01:00
Stypox
e8ed18f1cf Merge pull request #10578 from AudricV/try-fix-player-service-foreground-start
Restore player service start handling before player UI separation and fix some issues in this service
2023-11-16 08:59:56 +01:00
Stypox
bf8890b0df Merge pull request #10579 from AudricV/exclude-hls-opus-streams-for-playback
Remove OPUS HLS streams from playable streams
2023-11-16 08:30:49 +01:00
AudricV
e5fda35c51 Remove OPUS HLS streams from playable streams
This format is not supported by ExoPlayer when returned as HLS streams, so we
can't play streams using this format and this delivery method.

Also improve the Javadoc of ListHelper.getPlayableStreams.
2023-11-15 23:37:22 +01:00
AudricV
84d50da009 Restore player service start handling before player UI separation
This behavior was present before 0.24.0 and the player UI separation and
avoided crashes for which their exception contained
"Context.startForegroundService() did not then call Service.startForeground()".

Some player nullability checks have been also added, and the player service is
now stopped when it has been started from a media button and there is nothing
to play.
2023-11-15 23:21:20 +01:00
AudricV
2cf7764714 Fix crash when building the play queue audio track menu if the player is null
As the player can be null in some cases, we have to make sure that the player
is not null, by using Optionals on the player itself instead of its methods
returning Optionals.

If the player is null, the play queue audio track menu will now be hidden.
2023-11-15 21:45:56 +01:00
AudricV
9fab0ec94f Fix crash when setting the masking of the new feed items button if the context is null
As the fragment context can be null in some cases, we have to make sure that
the context is not null before calling
DeviceUtils.hasAnimationsAnimatorDurationEnabled.

If the context is null, the button will now not be hidden automatically.
2023-11-15 19:04:45 +01:00
Stypox
6d694518fe Merge pull request #10491 from TeamNewPipe/readme
[README] Remove Bitcoin and Bountysource donation options
2023-10-27 05:41:59 +02:00
TobiGr
5265b767cb Fix notifiying about old "new" streams
Add tests for `FeedDAO.unlinkStreamsOlderThan(:offsetDateTime) `
Closes #10237
2023-10-14 18:33:21 +02:00
TobiGr
d10a93fe4f [README] Remove Bountysource badge 2023-10-13 17:30:13 +02:00
TobiGr
995986ecc7 [README] Remove Bitcoin and Bountysource donation options 2023-10-13 17:30:13 +02:00
akko
6d0bb02544 adds quotation to create filename util replacement char 2023-10-13 11:28:09 +07:00
TobiGr
6f51c47dc9 Deleted translation using Weblate (Sicilian) 2023-10-07 17:39:49 +02:00
TobiGr
626daf89c1 Deleted translation using Weblate (Kashmiri) 2023-10-07 17:39:44 +02:00
Hosted Weblate
b18ccffeb4 Added translation using Weblate (English (Middle))
Deleted translation using Weblate (German (Low))

Deleted translation using Weblate (English (Old))

Deleted translation using Weblate (English (Middle))

Deleted translation using Weblate (Burmese)

Deleted translation using Weblate (Aymara)

Deleted translation using Weblate (Arabic (Najdi))

Co-authored-by: TobiGr <TobiGr@users.noreply.github.com>
Co-authored-by: Weblate <noreply@weblate.org>
2023-10-07 15:39:43 +00:00
Hosted Weblate
2ab2185e0a Translated using Weblate (Odia)
Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Serbian)

Currently translated at 17.1% (13 of 76 strings)

Translated using Weblate (Portuguese (Portugal))

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Arabic (Libya))

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Finnish)

Currently translated at 98.0% (711 of 725 strings)

Translated using Weblate (French)

Currently translated at 98.2% (712 of 725 strings)

Translated using Weblate (Indonesian)

Currently translated at 94.7% (72 of 76 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Hebrew)

Currently translated at 51.3% (39 of 76 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Korean)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (76 of 76 strings)

Translated using Weblate (Polish)

Currently translated at 61.8% (47 of 76 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (76 of 76 strings)

Co-authored-by: Agnieszka C <aga_04@o2.pl>
Co-authored-by: ButterflyOfFire <boffire@users.noreply.hosted.weblate.org>
Co-authored-by: Fjuro <ifjuro@proton.me>
Co-authored-by: GET100PERCENT <eraofphysics@yahoo.com>
Co-authored-by: Hoseok Seo <ddinghoya@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com>
Co-authored-by: Linerly <linerly@proton.me>
Co-authored-by: NEXI <nexiphotographer@gmail.com>
Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: ShareASmile <aapshergill@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: Åzze <laitinen.jere222@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ar/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/cs/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/es/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/he/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/hi/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/id/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/it/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pa/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pl/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sr/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/uk/
Translation: NewPipe/Metadata
2023-10-07 17:21:24 +02:00
TobiGr
be47609405 Add changelog for NewPipe 0.26.0 (995) 2023-10-05 14:49:35 +02:00
Hosted Weblate
5dee7a5262 Translated using Weblate (Portuguese)
Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Serbian)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Thai)

Currently translated at 29.3% (213 of 725 strings)

Translated using Weblate (Belarusian)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Azerbaijani)

Currently translated at 95.0% (689 of 725 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Serbian)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (ryu (generated) (ryu))

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Odia)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Sardinian)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Estonian)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Hebrew)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Portuguese)

Currently translated at 99.7% (723 of 725 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Serbian)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (German)

Currently translated at 100.0% (725 of 725 strings)

Translated using Weblate (Odia)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Estonian)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Portuguese)

Currently translated at 95.2% (685 of 719 strings)

Translated using Weblate (Odia)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Arabic (Libya))

Currently translated at 99.1% (713 of 719 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (ryu (generated) (ryu))

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (German)

Currently translated at 81.3% (61 of 75 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (French)

Currently translated at 98.4% (708 of 719 strings)

Translated using Weblate (German)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Arabic (Libya))

Currently translated at 99.3% (714 of 719 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Indonesian)

Currently translated at 99.8% (718 of 719 strings)

Translated using Weblate (French)

Currently translated at 97.7% (703 of 719 strings)

Translated using Weblate (German)

Currently translated at 99.4% (715 of 719 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Hebrew)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Czech)

Currently translated at 95.5% (687 of 719 strings)

Translated using Weblate (Greek)

Currently translated at 99.8% (718 of 719 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Serbian)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (719 of 719 strings)

Translated using Weblate (German)

Currently translated at 99.3% (714 of 719 strings)

Co-authored-by: Agnieszka C <aga_04@o2.pl>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Alexthegib <traducoes@skiff.com>
Co-authored-by: AudricV <AudricV@users.noreply.hosted.weblate.org>
Co-authored-by: ButterflyOfFire <boffire@users.noreply.hosted.weblate.org>
Co-authored-by: Emin Tufan Çetin <etcetin@gmail.com>
Co-authored-by: Eric <hamburger2048@users.noreply.hosted.weblate.org>
Co-authored-by: Fjuro <ifjuro@proton.me>
Co-authored-by: GET100PERCENT <eraofphysics@yahoo.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com>
Co-authored-by: Jeff Huang <s8321414@gmail.com>
Co-authored-by: Linerly <linerly@protonmail.com>
Co-authored-by: NEXI <nexiphotographer@gmail.com>
Co-authored-by: Nidi <nizamismidov4@gmail.com>
Co-authored-by: Peter Dave Hello <hsu@peterdavehello.org>
Co-authored-by: Philip Goto <philip.goto@gmail.com>
Co-authored-by: Priit Jõerüüt <hwlate@joeruut.com>
Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
Co-authored-by: Retrial <giwrgosmant@gmail.com>
Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: Sergio Marques <so.boston.android@gmail.com>
Co-authored-by: ShareASmile <aapshergill@gmail.com>
Co-authored-by: TobiGr <tobigr@mail.de>
Co-authored-by: Vasilis K <skyhirules@gmail.com>
Co-authored-by: VfBFan <VfBFan@users.noreply.hosted.weblate.org>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: bowornsin <bowornsin@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: kuragehime <kuragehime641@gmail.com>
Co-authored-by: nautilusx <translate@disroot.org>
Co-authored-by: zmni <zmni@outlook.com>
Co-authored-by: Макар Разин <makarrazin14@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/de/
Translation: NewPipe/Metadata
2023-10-05 03:09:31 +02:00
Stypox
bff7ada2d1 Merge pull request #8248 from dtcxzyw/fix-readd-to-playlist
Fix inconsistency between user interaction and database commit order when re-adding videos to the playlist
2023-10-03 17:45:44 +02:00
Tobi
ed33d1d4f7 Fix images in README.sr.md 2023-10-02 16:21:27 +02:00
Tobi
64e64f72f7 Update README.asm.md 2023-10-02 16:18:54 +02:00
TobiGr
d3c783832a Fix screenshot URLs in multiple READMEs 2023-10-02 16:16:53 +02:00
TobiGr
d963b69d5c Fix links to README.sr.md 2023-10-02 16:06:33 +02:00
Tobi
49ce9ba387 Fix links to other READMEs in README.sr.md 2023-10-02 16:00:25 +02:00
NEXI
d63a6d3f75 Create Serbian README (#10465) 2023-10-02 15:58:26 +02:00
TobiGr
3d5a8af52b Fix inconsistency when LocalPlaylist is used as MainFragment tab 2023-10-02 02:56:30 +02:00
Yingwei Zheng
1cf670dad9 Fix inconsistency between user interaction and database commit order when re-adding videos to the playlist 2023-10-02 02:56:30 +02:00
Tobi
b50e3c07d2 Use PR labeler fork
This updates some libs
2023-10-02 02:15:25 +02:00
Tobi
fe7d1692c3 Fix PR labeler permissions
Although the permission to modify PRs is granted to the entire workflow, the job still reports that it does not the permission to do so:
GITHUB_TOKEN Permissions
  Contents: read
  Metadata: read
  PullRequests: read
This adds the permission to the job directly
2023-09-27 10:06:34 +02:00
TobiGr
0758cd6980 Fix wrongly formatted string ressources
There were multiple substitutions specified in non-positional format in the ressources video_details_list_item and share_playlist_content_details
2023-09-26 11:22:22 +02:00
Siddhesh Naik
e80b6b3057 Add playlist name and video name to playlist sharing content (#10427)
- Currently, only a list of videos separated by newline are added in
  the share content.
- This makes it difficult to identify a specific video in a list of
  Urls.
- Used string resources for the sharing content formats.
- Added a confirmation dialog for users to choose between sharing
  playlist formats.
- Added Playlist name as the header and corresponding video name for
  each video url in following format.

Playlist
- Music1: https://media-url1
- Music2: https://media-url2
- Music3: https://media-url3


Co-authored-by: TobiGr <tobigr@users.noreply.github.com>
2023-09-26 11:11:33 +02:00
Tobi
9c86afe40d Merge pull request #10453 from TeamNewPipe/pr-labeler
Add content: read permission to PR size labeler workflow
2023-09-26 10:42:01 +02:00
Tobi
db4619f5a4 Add content: read permission to PR size labeler workflow 2023-09-26 10:40:17 +02:00
Tobi
f90d74ca31 Merge pull request #10447 from TeamNewPipe/pr-labeler
Add write permission to PR labeler workflow
2023-09-24 20:27:58 +02:00
Tobi
609f0a2eee Add write permission to PR labeler workflow 2023-09-24 20:24:57 +02:00
AudricV
77bbbc88f8 Use ListHelper to get secondary audio streams for video-only streams
Instead of searching for the first audio stream matching a compatible media
format, this change makes SecondaryStreamHelper.getAudioStreamFor use methods
isLimitingDataUsage, getAudioFormatComparator and getAudioIndexByHighestRank of
ListHelper to get an audio stream which can be muxed into a video-only stream,
if available.

This allows users to download videos with the highest audio quality available
if no resolution limit on mobile data usage has been set.

The order of formats used to search a compatible audio stream has been kept.
2023-09-24 18:23:45 +02:00
AudricV
cdb79ef78a Make isLimitingDataUsage method of ListHelper package-private and fix some typos in the class 2023-09-24 18:23:44 +02:00
Tobi
1630e309fb Merge pull request #9987 from Edwardsoen/add_high_resolution_to_default_option
Include a high-resolution option in the default resolution settings.
2023-09-24 17:54:18 +02:00
Stypox
2d4f56f57c Merge pull request #10170 from TeamNewPipe/actions/pr-size-labeler
Add workflow "PR size labeler" to label PRs based on the number of changed lines
2023-09-24 09:34:33 +02:00
TobiGr
d622993483 Add workflow "PR size labeler" to label PRs based on the number of changed lines
This should help reviewers to determine which PRs to review.
2023-09-24 09:33:44 +02:00
Tobi
c68a6ee0ed Merge pull request #10436 from TeamNewPipe/fix/license-restore
Fix restoring software license dialog
2023-09-23 14:11:09 +02:00
TobiGr
94c1438913 Use "done" button to close license dialogs.
Rename string res "recaptcha_done_button" to "done".
2023-09-23 13:56:49 +02:00
TobiGr
e206a26a85 Restore license dialog buttons to open the SoftwareComponent's website
Do not keep the active License but the active SoftwareComponent.
2023-09-23 13:49:09 +02:00
TobiGr
242e20316b [AboutFragment / LicenseFragment] Fix license restore after rotation
Do not restore last opened license after a rotation change when the license was closed earlier.

This commit adds onCancelListener and onDismissListener to the AlertDialogs which are used to display the licenses.
2023-09-23 13:49:09 +02:00
TobiGr
279fd2399d Remove translations without default value 2023-09-22 21:44:58 +02:00
kuragehime
a5fcb41ab0 Translated using Weblate (ryu (generated) (ryu))
Currently translated at 100.0% (713 of 713 strings)
2023-09-22 21:38:28 +02:00
Marian Hanzel
cb4f656673 Translated using Weblate (Slovak)
Currently translated at 18.6% (14 of 75 strings)

Translation: NewPipe/Metadata
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sk/
2023-09-22 21:38:28 +02:00
ShareASmile
b9e5ee6759 Translated using Weblate (Punjabi)
Currently translated at 100.0% (713 of 713 strings)
2023-09-22 21:38:28 +02:00
ShareASmile
1084b7c3ad Translated using Weblate (Hindi)
Currently translated at 100.0% (713 of 713 strings)
2023-09-22 21:38:28 +02:00
Yaron Shahrabani
39c06c5461 Translated using Weblate (Hebrew)
Currently translated at 100.0% (713 of 713 strings)
2023-09-22 21:38:28 +02:00
Jeff Huang
b9c7f8769b Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (713 of 713 strings)
2023-09-22 21:38:28 +02:00
Eric
dc45adf7f2 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (713 of 713 strings)
2023-09-22 21:38:28 +02:00
Agnieszka C
a69af42f7f Translated using Weblate (Polish)
Currently translated at 100.0% (713 of 713 strings)
2023-09-22 21:38:28 +02:00
Ihor Hordiichuk
1a5dfae7a0 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (713 of 713 strings)
2023-09-22 21:38:28 +02:00
Linerly
d41b5d80ad Translated using Weblate (Indonesian)
Currently translated at 100.0% (713 of 713 strings)
2023-09-22 21:38:28 +02:00
Rex_sa
f0bcb3ba28 Translated using Weblate (Arabic)
Currently translated at 100.0% (713 of 713 strings)
2023-09-22 21:38:28 +02:00
Marian Hanzel
7da35bf71d Translated using Weblate (Slovak)
Currently translated at 99.7% (711 of 713 strings)
2023-09-22 21:38:28 +02:00
Vasilis K
03c339dd4b Translated using Weblate (Greek)
Currently translated at 100.0% (713 of 713 strings)
2023-09-22 21:38:28 +02:00
kuragehime
11c74bd26b Translated using Weblate (Japanese)
Currently translated at 100.0% (713 of 713 strings)
2023-09-22 21:38:28 +02:00
gallegonovato
0a292cf893 Translated using Weblate (Spanish)
Currently translated at 100.0% (713 of 713 strings)
2023-09-22 21:38:28 +02:00
TobiGr
ac6811867f Translated using Weblate (German)
Currently translated at 100.0% (713 of 713 strings)
2023-09-22 21:38:28 +02:00
VfBFan
0c9df501e8 Translated using Weblate (German)
Currently translated at 100.0% (713 of 713 strings)
2023-09-22 21:38:28 +02:00
Hosted Weblate
4c4f9b45d9 Translated using Weblate (Kazakh)
Currently translated at 0.5% (4 of 702 strings)

Translated using Weblate (Kazakh)

Currently translated at 6.6% (5 of 75 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (702 of 702 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (702 of 702 strings)

Merge branch 'origin/dev' into Weblate.

Translated using Weblate (Spanish)

Currently translated at 100.0% (702 of 702 strings)

Translated using Weblate (ryu (generated) (ryu))

Currently translated at 100.0% (702 of 702 strings)

Translated using Weblate (Hebrew)

Currently translated at 100.0% (702 of 702 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (702 of 702 strings)

Translated using Weblate (Greek)

Currently translated at 99.8% (701 of 702 strings)

Translated using Weblate (Japanese)

Currently translated at 98.2% (690 of 702 strings)

Translated using Weblate (Serbian)

Currently translated at 100.0% (702 of 702 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (702 of 702 strings)

Translated using Weblate (German)

Currently translated at 80.0% (60 of 75 strings)

Translated using Weblate (German)

Currently translated at 100.0% (702 of 702 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (702 of 702 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (702 of 702 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (702 of 702 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (702 of 702 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (702 of 702 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (702 of 702 strings)

Translated using Weblate (Greek)

Currently translated at 97.8% (687 of 702 strings)

Translated using Weblate (Serbian)

Currently translated at 98.5% (692 of 702 strings)

Translated using Weblate (German)

Currently translated at 99.5% (699 of 702 strings)

Translated using Weblate (Odia)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Portuguese (Portugal))

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Serbian)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Indonesian)

Currently translated at 99.8% (685 of 686 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Serbian)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Odia)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Hungarian)

Currently translated at 99.7% (684 of 686 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Serbian)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Serbian)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Serbian)

Currently translated at 16.0% (12 of 75 strings)

Translated using Weblate (Galician)

Currently translated at 99.5% (683 of 686 strings)

Translated using Weblate (Serbian)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Serbian)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Serbian)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Serbian)

Currently translated at 16.0% (12 of 75 strings)

Translated using Weblate (Bengali)

Currently translated at 83.8% (575 of 686 strings)

Translated using Weblate (Azerbaijani)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Serbian)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (686 of 686 strings)

Co-authored-by: Agnieszka C <aga_04@o2.pl>
Co-authored-by: Aidos <goldenbit.kz@yandex.kz>
Co-authored-by: Daniel Rozario <rozario@tuta.io>
Co-authored-by: Emin Tufan Çetin <etcetin@gmail.com>
Co-authored-by: Eric <hamburger2048@users.noreply.hosted.weblate.org>
Co-authored-by: Fjuro <ifjuro@proton.me>
Co-authored-by: GET100PERCENT <eraofphysics@yahoo.com>
Co-authored-by: GnuPGを使うべきだ <dieeeazpnnqbpddh@cock.email>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Igor Rückert <igorruckert@yahoo.com.br>
Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com>
Co-authored-by: Jeff Huang <s8321414@gmail.com>
Co-authored-by: Linerly <linerly@protonmail.com>
Co-authored-by: NEXI <nexiphotographer@gmail.com>
Co-authored-by: Nidi <nizamismidov4@gmail.com>
Co-authored-by: Philip Goto <philip.goto@gmail.com>
Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
Co-authored-by: ShareASmile <aapshergill@gmail.com>
Co-authored-by: Subham Jena <subhamjena8465@gmail.com>
Co-authored-by: Tibor Botfai (gidano) <gidano@gmail.com>
Co-authored-by: TobiGr <tobigr@mail.de>
Co-authored-by: Vasilis K <skyhirules@gmail.com>
Co-authored-by: VfBFan <VfBFan@users.noreply.hosted.weblate.org>
Co-authored-by: WB <dln0@proton.me>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: kuragehime <kuragehime641@gmail.com>
Co-authored-by: nexi <nexiphotographer@gmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: zmni <zmni@outlook.com>
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/de/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/kk/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sr/
Translation: NewPipe/Metadata
2023-09-22 21:38:28 +02:00
Audric V
5a921c9f10 Merge pull request #10440 from Stypox/remove-deobfuscation-exception
Update extractor and remove DeobfuscateException
2023-09-22 16:29:13 +02:00
Stypox
bdc2aa2b39 Update extractor and remove DeobfuscateException
In ErrorInfo it was treated separately from other ParsingExceptions, including by showing a customized message, which has now been removed.
2023-09-22 10:43:37 +02:00
Stypox
b508dd69be Merge pull request #10062 from Stypox/multiple-images
Allow selecting image quality among multiple images
2023-09-22 10:20:19 +02:00
Stypox
f8b756c8bc Make question mark localizable 2023-09-22 10:14:45 +02:00
Stypox
027b829c38 Use @DrawableRes in PicassoHelper 2023-09-22 10:14:45 +02:00
Stypox
0a2d6d1d62 Add test for ImageStrategy 2023-09-22 10:14:45 +02:00
Stypox
1b485ddb5a Allow using CHECKSTYLE:OFF comments 2023-09-22 10:14:45 +02:00
Stypox
0085ca6416 Fix loading images from db even if disabled 2023-09-22 10:14:44 +02:00
Stypox
87dca0f7ec Separate imageListToDbUrl from choosePreferredImage
imageListToDbUrl should be used if the URL is going to be saved to the database, to avoid saving nothing in case at the moment of saving the user preference is to not show images.
2023-09-22 10:14:44 +02:00
Stypox
37af2c87e8 Fix possible NPE in PlayQueueNavigator 2023-09-22 10:14:44 +02:00
Stypox
bf908f0b7d Add documentation and fix SonarCloud issue 2023-09-22 10:14:44 +02:00
Stypox
8d463b9577 Further improve image resolution strategy
Now using multiple comparison steps instead of magic values
2023-09-22 10:14:44 +02:00
Stypox
4f7d206736 Display all thumbnails in description tab 2023-09-22 10:14:44 +02:00
Stypox
35073c780d Implement better image selection strategy 2023-09-22 10:14:44 +02:00
Stypox
0a8f28b1c6 Add image quality preference 2023-09-22 10:14:43 +02:00
Stypox
af2375948d Support obtaining multiple images from the extractor 2023-09-22 09:57:33 +02:00
Tobi
e2de83188a Merge pull request #10199 from TeamNewPipe/feat/player/accessibility
Improved accessibility of player interfaces
2023-09-21 15:57:38 +02:00
TobiGr
2a1b506d98 Improved accessibility of player interfaces 2023-09-21 12:20:00 +02:00
Stypox
b798ff5c92 Merge pull request #10435 from TeamNewPipe/imp/codequality
Improve codequality
2023-09-20 21:24:44 +02:00
Tobi
673aa0a87b Merge pull request #10428 from Isira-Seneviratne/AGP_8.1
Bump AGP to 8.1.1
2023-09-20 20:20:36 +02:00
TobiGr
779ea19222 Fix doc formatting 2023-09-20 19:44:23 +02:00
Isira Seneviratne
a1f2b7f8e8 Switch to Files.createDirectories() 2023-09-20 19:44:23 +02:00
Isira Seneviratne
fcb855cea9 Bump AGP to 8.1.1 2023-09-20 19:44:23 +02:00
Tobi
50fb48f66d Merge pull request #10244 from TacoTheDank/bumpMaterial
Update Google Material library
2023-09-20 18:19:53 +02:00
TobiGr
0acc3532c9 Remove useless override 2023-09-20 15:42:09 +02:00
TobiGr
8bf2d996ea Reorder the modifiers to comply with the Java Language Specification. 2023-09-20 15:41:57 +02:00
TobiGr
748c2babe9 Add comments and annotations 2023-09-20 15:41:21 +02:00
Tobi
6859f73c54 Merge pull request #10224 from TacoTheDank/moreKotlinMath
Replace MathUtils.clamp with Kotlin coerceIn
2023-09-20 11:04:54 +02:00
TacoTheDank
b1faed586d Replace MathUtils.clamp with Kotlin coerceIn 2023-09-19 16:32:37 -04:00
TacoTheDank
6c848b4766 Update Google Material library 2023-09-19 16:30:09 -04:00
Stypox
725c18eada Merge pull request #10165 from TeamNewPipe/fix/media-format
Fix downloads of streams with missing MediaFormat
2023-09-19 15:54:12 +02:00
Stypox
992bb5d7be Simplify retrieveMediaFormatFromContentTypeHeader
Also check for nullity
2023-09-19 15:33:49 +02:00
Stypox
9e353f1cdc Merge pull request #10394 from TeamNewPipe/fix/memory-leaks
Fix memory leaks and add documentation
2023-09-19 14:17:23 +02:00
TobiGr
8f83e39970 Fix three memory leaks
Add documentation to BaseFragment.initViews(View, Bundle) and BaseFragment.initListeners()
2023-09-19 00:13:16 +02:00
Stypox
0eae9e7cdc Merge pull request #9182 from Theta-Dev/channel-tabs
Add support for channel tabs
2023-09-18 23:46:13 +02:00
TobiGr
031b893196 Remove unused content not supported TextView 2023-09-18 23:22:32 +02:00
TobiGr
64da7a06c0 Fix previous ActionBar title visible for a few miliseconds when opening ChannelFragment 2023-09-18 23:22:32 +02:00
TobiGr
57eaa1bbe1 Apply review
Co-Authored-By:  Audric V <74829229+AudricV@users.noreply.github.com>
2023-09-18 23:22:32 +02:00
TobiGr
109d06b4bb Deduplicate code to initialize ClickListeners on playlist controls
Add the separate utility class PlayButtonHelper to handle the initialization of the listeners.
The ClickListeners on playlist controls had different behaviours. This commit fixes that.

The commit also refactors the way how the app determines whether it is started for the first time. The previous version was not clean and recent in this PR caused it to fail.
2023-09-18 23:22:32 +02:00
AudricV
0d9910cbbe Fix SubscriptionManagerTest tests
The breakage of these tests is related to the channel tabs changes.

The testRememberRecentStreams test method has been removed, as it doesn't seem
to be relevant anymore to managing subscriptions.
2023-09-18 23:22:32 +02:00
AudricV
8fbc8ffc7c Remove unneeded German translation 2023-09-18 23:22:32 +02:00
AudricV
f2ee3859ab Hide the upload date element on the About tab
This empty element should be always hidden for this tab, as there is no upload
date available for channels.
2023-09-18 23:22:32 +02:00
AudricV
89dc44be61 Always show the About tab and support having no description 2023-09-18 23:22:32 +02:00
TobiGr
6ab8716e69 Extract actual feed loading code into separate method
Increase readability
2023-09-18 23:22:32 +02:00
TobiGr
5c7c382323 Add missing @Override annotations to setupMetadata() implementations 2023-09-18 23:22:32 +02:00
Stypox
78b4b9441e Update NewPipeExtractor and adapt imports 2023-09-18 23:22:32 +02:00
Stypox
9e55014a13 Fix wrongly themed channel header
Since it is embedded in the app bar and has red as background color, it should be themed in the same way as the toolbar.
2023-09-18 23:22:32 +02:00
Stypox
6f23b56b06 Use consistent name for livestreams tab in settings keys 2023-09-18 23:22:32 +02:00
Stypox
1519527356 Fix loading feed when a channel tab is empty 2023-09-18 23:22:32 +02:00
Stypox
6b3a178f2a Show snackbar with feed loading errors 2023-09-18 23:22:32 +02:00
Stypox
604419dd1f Make channel banner placeholder match YouTube's size
YouTube's "Desktop Max" thumbnails are 2560x423, while our previous placeholder banner was 2550x427. The extractor actually returns a lower resolution "Desktop Max" banner at 1060x175, but the ratio wrt 2560x423 is off by ~0.1%

The PNG was optimized with OptiPNG
2023-09-18 23:22:32 +02:00
Stypox
c48e702a50 Improve placeholder channel banner handling
Now the placeholder gets hidden if there is no banner url or the user disabled images, to save space
2023-09-18 23:22:32 +02:00
Stypox
1061bce4f3 Add avatar and bannner URLs to channel About tab 2023-09-18 23:22:32 +02:00
Stypox
013d513450 Add space above channel description (About tab) 2023-09-18 23:22:32 +02:00
ThetaDev
dca32efadf add channel banner placeholder 2023-09-18 23:22:32 +02:00
ThetaDev
28d952a643 feat: filter fetched channel tabs 2023-09-18 23:22:32 +02:00
ThetaDev
a2a717bd49 update NPE 2023-09-18 23:22:32 +02:00
ThetaDev
753a92055c feat: add playlist controls to channel tab 2023-09-18 23:22:32 +02:00
Stypox
371f986773 Fix some code smells 2023-09-18 23:22:32 +02:00
Stypox
a1e8b9be4e Fix channel tabs in main page setting title themselves 2023-09-18 23:22:32 +02:00
Stypox
c076a0f771 Channels are now an Info
The previous "main" tab is now just a normal tab returned in getTabs().
Various part of the code that used to handle channels as ListInfo now either take the first (playable, i.e. with streams) tab (e.g. the ChannelTabPlayQueue), or take all of them combined (e.g. the feed).
2023-09-18 23:22:32 +02:00
ThetaDev
dfbd39e898 fix: limit channel header height 2023-09-18 23:22:32 +02:00
ThetaDev
b5893f3fa3 fix: notification menu option disappears when switching tabs 2023-09-18 23:22:32 +02:00
Stypox
e3614cb932 Move channel header to collapsible app bar 2023-09-18 23:22:32 +02:00
ThetaDev
193c3e5b3d fix: NPE in ChannelFragment::onSaveInstanceState 2023-09-18 23:22:32 +02:00
ThetaDev
c03c344f49 refactor: rename ChannelInfo to ChannelAbout
fix: localize about tab name
2023-09-18 23:22:32 +02:00
ThetaDev
25e3031830 cleanup: remove empty constructor from ChannelFragment 2023-09-18 23:22:31 +02:00
ThetaDev
b7911a8fd8 remove fragment_channel_info 2023-09-18 23:22:31 +02:00
ThetaDev
88384dc35e update extractor 2023-09-18 23:22:31 +02:00
ThetaDev
39b4ed082c refactor: common code from ChannelInfo/Description -> BaseInfoFragment 2023-09-18 23:22:31 +02:00
ThetaDev
d87aa23ae0 update NewPipeExtractor 2023-09-18 23:22:31 +02:00
ThetaDev
be548dcb52 fix: channel tab title not being set 2023-09-18 23:22:31 +02:00
ThetaDev
4357a34339 fix: ChannelFragment: save last tab 2023-09-18 23:22:31 +02:00
ThetaDev
2c03ba204e refactor: adjustments to updated tab extractor API 2023-09-18 23:22:31 +02:00
ThetaDev
2c98d079de fix: cache channel data 2023-09-18 23:22:31 +02:00
ThetaDev
16cd47fa2e fix: missing album tab key 2023-09-18 23:22:31 +02:00
ThetaDev
74a8bfba93 feat: add album tab 2023-09-18 23:22:31 +02:00
ThetaDev
c929f00456 fix: remember selected channel tab on screen rotation 2023-09-18 23:22:31 +02:00
ThetaDev
bb062f07f9 feat: add option to hide channel tabs 2023-09-18 23:22:31 +02:00
ThetaDev
c3d1e75a8f fix: scrollable channel description 2023-09-18 23:22:31 +02:00
ThetaDev
506e3724a6 fix: add progress spinners 2023-09-18 23:22:31 +02:00
ThetaDev
4859ab67d4 feat: prettier channel info page 2023-09-18 23:22:31 +02:00
ThetaDev
6d84d19520 fix: handle unsupported content 2023-09-18 23:22:31 +02:00
ThetaDev
8627efd0a1 fix: get notified menu option on all tabs 2023-09-18 23:22:31 +02:00
ThetaDev
6d13cf5e71 feat: add channel tabs 2023-09-18 23:22:31 +02:00
Rishab Aggarwal
7e2ab0d384 Improved downloading experience (#10407)
* added LoadingDialog for improving download experience

* [LoadingDialog] Apply some review comments and make title customizable.

* removed permission handling from loading Dialog

* fix checks

* remove <p> Tag from first sentence

---------

Co-authored-by: rishabaggarwal <Rishabaggarwal@sharechat.com>
Co-authored-by: TobiGr <tobigr@users.noreply.github.com>
2023-09-18 05:24:03 +05:30
TobiGr
19640d5e7c Add documentation to increase maintainablilty
Rename a variable
2023-09-18 01:45:53 +02:00
Edward
d1a82a85cd Include a high-resolution option in the default resolution settings. 2023-09-18 01:15:22 +02:00
Isira Seneviratne
b1ab261890 Merge pull request #10248 from Isira-Seneviratne/NIO_downloads
Improve the download helpers using the Java 7 NIO API.
2023-09-17 21:09:02 +05:30
Tobi
038278283a Merge pull request #10234 from TacoTheDank/bumpMisc
Update miscellaneous libraries
2023-09-17 16:35:40 +02:00
TacoTheDank
c74bd11a6f Update miscellaneous libraries 2023-09-17 15:43:43 +02:00
TobiGr
f2c2f1735e Replace RuntimeException with IOException
The RuntimeException was not explicitly declared and thus not caught at every call of this constructor. This change ensures that this possible exception is handled by the dedicated error handlers.
2023-09-17 15:31:19 +02:00
TobiGr
4e41e12bd2 Small code and doc improvements
Remove unnecessary else-branch and use Collections.isEmpty().
Add doc comment for splitFilename()
2023-09-17 15:31:19 +02:00
Isira Seneviratne
6df808f266 Use Path in the download helper classes. 2023-09-17 14:50:26 +02:00
Isira Seneviratne
2cb973f150 Use desugar_jdk_libs_nio. 2023-09-17 14:50:26 +02:00
Tobi
b5463cf5e1 Merge pull request #10406 from ShareASmile/fix-language-selector
Fix language Picker Selecting Wrong Languages
2023-09-09 00:52:07 +02:00
K Gill
862546205a fix wrongly placed uchinaguchi in language selector settings caus..
..ing language picker to select wrong languages
2023-09-08 16:33:17 +05:30
Audric V
7c1790bbfd Merge pull request #10396 from AudricV/one-stream-main-player-queue-button
Show play queue button in main player when there is one stream
2023-08-31 15:06:06 +02:00
AudricV
2d16a06bc4 Show play queue button in main player when there is one stream 2023-08-30 19:45:53 +02:00
Tobi
25cf917969 Merge pull request #10377 from TeamNewPipe/image-minimizer
Image minizier: replace Number.toFixed(0) with Math.floor()
2023-08-25 00:54:55 +02:00
Tobi
d09c650afd Merge pull request #10376 from TeamNewPipe/fix-string-formats
Fix string formats
2023-08-24 21:14:03 +02:00
AudricV
2b833c5250 Fix audio_track_name string formats 2023-08-24 20:41:11 +02:00
TobiGr
510db568eb Image minizier: replace Number.toFixed(0) with Math.floor()
Number.toFixed returns a string, Math.floor a number
2023-08-24 11:53:35 +02:00
Hosted Weblate
e4003c842b Translated using Weblate (Arabic)
Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Odia)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Malayalam)

Currently translated at 6.6% (5 of 75 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (German)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (German)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Swedish)

Currently translated at 99.7% (684 of 686 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Estonian)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Albanian)

Currently translated at 82.7% (568 of 686 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (French)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (686 of 686 strings)

Added translation using Weblate (Burmese)

Translated using Weblate (ryu (generated) (ryu))

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Hebrew)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Slovak)

Currently translated at 98.9% (679 of 686 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (German)

Currently translated at 100.0% (686 of 686 strings)

Translated using Weblate (ryu (generated) (ryu))

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (75 of 75 strings)

Translated using Weblate (Croatian)

Currently translated at 91.8% (628 of 684 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (French)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (ryu (generated) (ryu))

Currently translated at 98.6% (675 of 684 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Odia)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Urdu)

Currently translated at 74.2% (508 of 684 strings)

Translated using Weblate (Vietnamese)

Currently translated at 99.2% (679 of 684 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Korean)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Portuguese (Portugal))

Currently translated at 100.0% (75 of 75 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (75 of 75 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (75 of 75 strings)

Translated using Weblate (Portuguese (Portugal))

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Galician)

Currently translated at 99.5% (681 of 684 strings)

Translated using Weblate (Finnish)

Currently translated at 89.9% (615 of 684 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (684 of 684 strings)

Co-authored-by: Agnieszka C <aga_04@o2.pl>
Co-authored-by: Alex25820 <alexs25820@gmail.com>
Co-authored-by: Alexthegib <jcwkgxc@nightorb.com>
Co-authored-by: AudricV <AudricV@users.noreply.hosted.weblate.org>
Co-authored-by: C. Rüdinger <Mail-an-CR@web.de>
Co-authored-by: Eric <hamburger2048@users.noreply.hosted.weblate.org>
Co-authored-by: Fjuro <ifjuro@proton.me>
Co-authored-by: GET100PERCENT <eraofphysics@yahoo.com>
Co-authored-by: Hoseok Seo <ddinghoya@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Igor Rückert <igorruckert@yahoo.com.br>
Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com>
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Co-authored-by: Jani Kinnunen <janikinnunen340@gmail.com>
Co-authored-by: Jeff Huang <s8321414@gmail.com>
Co-authored-by: Joel A <joeax910@student.liu.se>
Co-authored-by: Jorge Pelaez <jorpelae@yahoo.co.jp>
Co-authored-by: Linerly <linerly@protonmail.com>
Co-authored-by: Milan Šalka <salka.milan@googlemail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Philip Goto <philip.goto@gmail.com>
Co-authored-by: Priit Jõerüüt <hwlate@joeruut.com>
Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: Sergio Marques <so.boston.android@gmail.com>
Co-authored-by: ShareASmile <aapshergill@gmail.com>
Co-authored-by: Shifa Graphics <shifagraphix@gmail.com>
Co-authored-by: TXRdev Archive <lckphanaf9999@gmail.com>
Co-authored-by: Vasilis K <skyhirules@gmail.com>
Co-authored-by: VfBFan <drop0815@posteo.de>
Co-authored-by: W L <wl@mailhole.de>
Co-authored-by: WB <dln0@proton.me>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: kuragehime <kuragehime641@gmail.com>
Co-authored-by: nautilusx <translate@disroot.org>
Co-authored-by: random r <epsilin@yopmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: tellmeY18 <vysakh_b190622ec@nitc.ac.in>
Co-authored-by: thami simo <simo.azad@gmail.com>
Co-authored-by: Макар Разин <makarrazin14@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/cs/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ml/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt_PT/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/uk/
Translation: NewPipe/Metadata
2023-08-23 21:29:25 +02:00
TobiGr
68957d3880 Fix grammar in JDoc 2023-08-22 16:23:22 +02:00
Tobi
e6747066ae Merge pull request #10360 from TeamNewPipe/improvement/tabSelected
Simplify `MainActivity.tabSelected(MenuItem)`
2023-08-22 10:57:14 +02:00
TobiGr
62f0abee47 Simplify MainActivity.tabSelected(MenuItem)
Rename variables and skip iterations if kiosk was found.
2023-08-19 21:58:44 +02:00
TobiGr
db5ed48dbb Fix some sonar warnings and make some smaller improvements 2023-08-14 23:09:50 +02:00
TobiGr
ba84e7eead Display "Unknown quality" if quality is unknown and not MediaFormat name 2023-08-14 23:06:32 +02:00
TobiGr
e51067177e Add tests for new methods retrieving MediaFormats
Fix failing tests
2023-08-14 23:06:32 +02:00
TobiGr
f3859ed710 Retrieve MediaFormat for streams that could not be extracted by the extractor 2023-08-14 23:06:32 +02:00
TobiGr
0db12e5561 Rename StreamSizeWrapper to StreamInfoWrapper 2023-08-14 22:48:39 +02:00
Stypox
ac5f991c0c Merge pull request #10331 from TeamNewPipe/improve_bug_template
Make "latest release" link more obvious to bug reporters
2023-08-12 19:46:15 +02:00
opusforlife2
4a0ff3f7ef Make latest release link more obvious to bug reporters 2023-08-12 15:08:03 +00:00
Stypox
601b1ef742 Merge pull request #10313 from mhmdanas/fix-capitalization-of-night-theme
Make capitalization of "Night theme" setting consistent with others
2023-08-07 23:07:48 +02:00
triallax
d957725805 Make capitalization of "Night theme" setting consistent with others
Been a pet peeve of mine for some time.
2023-08-07 20:40:33 +01:00
Stypox
4201723d10 Merge pull request #10304 from TeamNewPipe/fix/media.ccc.de
Adjust empty state message for ListInfoFragments depending on Info stream type
2023-08-06 10:07:33 +02:00
Stypox
bef79e77aa Update app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java 2023-08-06 10:07:13 +02:00
TobiGr
32f74273f0 Adjust empty state message for ListInfoFragments depending on Info stream type
Show "no streams" for SoundClound.
Show "no live streams" for MeidaCCCLiveStreamKiosk.
Otherwise show "no videos"
2023-08-05 03:50:28 +02:00
TobiGr
c69bcaafbb Fixed some Sonar warnings 2023-08-03 12:02:08 +02:00
Tobi
50d7d1b7b3 Merge pull request #10275 from J-Stutzmann/fix/audio-focus
Fix player audio focus not respecting mute
2023-08-03 11:55:40 +02:00
J-Stutzmann
c06d61a83c Made audio-focus calls respect mute state. 2023-08-02 23:44:23 -04:00
TobiGr
bc4f0c699f Ignore false positive inspection 2023-08-02 20:44:30 +02:00
Stypox
1e8efa7165 Merge pull request #10283 from TeamNewPipe/release/0.25.2
Release v0.25.2 (994)
2023-08-02 20:14:14 +02:00
Stypox
d4019f4b54 Update NewPipeExtractor to v0.22.7 2023-08-02 20:12:55 +02:00
TobiGr
3f0f66f106 Bump version to 0.25.2 (994) 2023-08-02 20:02:22 +02:00
Hosted Weblate
8f644e8aaf Translated using Weblate (Urdu)
Currently translated at 5.3% (4 of 75 strings)

Translated using Weblate (Urdu)

Currently translated at 73.2% (501 of 684 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (75 of 75 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (75 of 75 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (75 of 75 strings)

Translated using Weblate (Polish)

Currently translated at 61.3% (46 of 75 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (75 of 75 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (75 of 75 strings)

Translated using Weblate (Estonian)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Hebrew)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (684 of 684 strings)

Translated using Weblate (German)

Currently translated at 100.0% (684 of 684 strings)

Co-authored-by: Agnieszka C <aga_04@o2.pl>
Co-authored-by: Eric <hamburger2048@users.noreply.hosted.weblate.org>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com>
Co-authored-by: Jeff Huang <s8321414@gmail.com>
Co-authored-by: Priit Jõerüüt <hwlate@joeruut.com>
Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: ShareASmile <aapshergill@gmail.com>
Co-authored-by: Shifa Graphics <shifagraphix@gmail.com>
Co-authored-by: Vasilis K <skyhirules@gmail.com>
Co-authored-by: VfBFan <drop0815@posteo.de>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: random r <epsilin@yopmail.com>
Co-authored-by: rickeesingh <rickeesingh231@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ar/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/es/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/hi/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/it/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pa/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pl/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ur/
Translation: NewPipe/Metadata
2023-08-02 19:57:41 +02:00
TobiGr
27f77518fe Update NewPipe Extractor to 39a911db9f 2023-07-31 23:59:28 +02:00
Hosted Weblate
b56f3b3324 Translated using Weblate (Punjabi)
Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (French)

Currently translated at 93.2% (69 of 74 strings)

Translated using Weblate (Toki Pona)

Currently translated at 6.5% (45 of 683 strings)

Translated using Weblate (Toki Pona)

Currently translated at 2.7% (2 of 74 strings)

Translated using Weblate (French)

Currently translated at 100.0% (683 of 683 strings)

Added translation using Weblate (Toki Pona)

Translated using Weblate (ryu (generated) (ryu))

Currently translated at 96.3% (658 of 683 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 8.3% (57 of 683 strings)

Translated using Weblate (Portuguese (Portugal))

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Hebrew)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (French)

Currently translated at 100.0% (683 of 683 strings)

Co-authored-by: Eric <hamburger2048@users.noreply.hosted.weblate.org>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Jeff Huang <s8321414@gmail.com>
Co-authored-by: John Donne <akheron@zaclys.net>
Co-authored-by: Linerly <linerly@protonmail.com>
Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: ShareASmile <aapshergill@gmail.com>
Co-authored-by: Translator <kvb@tuta.io>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: William <Electroboss@users.noreply.hosted.weblate.org>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: kuragehime <kuragehime641@gmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/fr/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/tok/
Translation: NewPipe/Metadata
2023-07-31 23:46:11 +02:00
TobiGr
0195655479 Add changelog for NewPipe 0.25.2 (994) 2023-07-31 23:43:41 +02:00
Tobi
3c91ec33ae Merge pull request #10122 from TeamNewPipe/fix/media-tunneling
Disable media tunneling by default on known unsupported devices
2023-07-31 23:30:24 +02:00
Tobi
6b3f51e5ea Merge pull request #10281 from TeamNewPipe/okio
Update com.squareup.okio:okio to 3.4.0
2023-07-31 23:29:39 +02:00
TobiGr
d6a1170ddb Replace settings migration with automatic check for device blacklist version 2023-07-31 23:00:54 +02:00
TobiGr
428a7d418b Update com.squareup.okio:okio to 3.4.0
Use okio 3.4.0 explicity to fix vulnerability introduced through okhttp3 (3.3.0).
See https://www.cve.org/CVERecord?id=CVE-2023-3635 for more details on the vulnerability.
2023-07-31 21:53:49 +02:00
TobiGr
40d102fcb5 Disable media tunneling by default on new devices
Sony BRAVIA_VH1, BRAVIA_VH2, BRAVIA_ATV2, BRAVIA_ATV3_4K
Phillips 4K (O)LED TV (PH7M_EU_5596)
Panasonic 4KTV-JUP (TX_50JXW834)
Bouygtel4K (HMB9213NW)
2023-07-29 22:08:51 +02:00
TobiGr
1db73370a7 Ensure that imports handle disabling media tunneling correctly
Store in preferences whether media tunneling was disabled automatically.
Show info in ExoPlayer settings if media tunneling was disabled autmatically.
2023-07-29 22:08:51 +02:00
TobiGr
8b63b437d8 Disable media tunneling if the device is known for not supporting it
Revert removing the Utils related to media tunneling.
2023-07-29 14:13:03 +02:00
TobiGr
78e577d260 Make some constants private and annotate params 2023-07-29 14:13:03 +02:00
Tobi
96a7cc2971 Merge pull request #10250 from kuragehimekurara1/dev
Added Uchinaguchi translation and README
2023-07-24 19:36:32 +02:00
TobiGr
9eedbae879 Fix ryu translation syntax 2023-07-24 19:33:27 +02:00
kuragehime
38d3b3c7ef Added Uchinaguchi (ryu) to language selector 2023-07-24 19:31:31 +02:00
kuragehime
e4d3b74f1b Added Uchinaguchi translation 2023-07-24 19:31:31 +02:00
TobiGr
54f3003a6f Added Uchinaguchi README
Co-authored-by:  kuragehime <kuragehime641@gmail.com>
2023-07-24 19:31:31 +02:00
TobiGr
cbc7b8ce18 Fix wrongly formatted string resource audio_track_name
Closes #10243
2023-07-24 19:14:00 +02:00
Hosted Weblate
ec7d01b794 Translated using Weblate (Swedish)
Currently translated at 72.9% (54 of 74 strings)

Translated using Weblate (Estonian)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (German)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Hebrew)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (683 of 683 strings)

Translated using Weblate (Dutch)

Currently translated at 64.8% (48 of 74 strings)

Translated using Weblate (German)

Currently translated at 81.0% (60 of 74 strings)

Translated using Weblate (Albanian)

Currently translated at 81.0% (552 of 681 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (681 of 681 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (681 of 681 strings)

Translated using Weblate (French)

Currently translated at 93.2% (69 of 74 strings)

Translated using Weblate (Vietnamese)

Currently translated at 33.7% (25 of 74 strings)

Translated using Weblate (Bulgarian)

Currently translated at 66.5% (453 of 681 strings)

Translated using Weblate (Finnish)

Currently translated at 87.3% (595 of 681 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (681 of 681 strings)

Translated using Weblate (German)

Currently translated at 81.0% (60 of 74 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (681 of 681 strings)

Translated using Weblate (Japanese)

Currently translated at 12.1% (9 of 74 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (681 of 681 strings)

Translated using Weblate (Vietnamese)

Currently translated at 32.4% (24 of 74 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (681 of 681 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (681 of 681 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (681 of 681 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (74 of 74 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (681 of 681 strings)

Translated using Weblate (Romanian)

Currently translated at 96.0% (654 of 681 strings)

Translated using Weblate (Japanese)

Currently translated at 99.7% (679 of 681 strings)

Translated using Weblate (Korean)

Currently translated at 12.1% (9 of 74 strings)

Translated using Weblate (Korean)

Currently translated at 12.1% (9 of 74 strings)

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (681 of 681 strings)

Translated using Weblate (Korean)

Currently translated at 100.0% (681 of 681 strings)

Translated using Weblate (German)

Currently translated at 79.7% (59 of 74 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (681 of 681 strings)

Co-authored-by: Agnieszka C <aga_04@o2.pl>
Co-authored-by: AhHyeon An <toto1444@gmail.com>
Co-authored-by: AioiLight <info@aioilight.space>
Co-authored-by: Alex25820 <alexs25820@gmail.com>
Co-authored-by: Anonymous <deni76@tutanota.com>
Co-authored-by: Anxhelo Lushka <anxhelo1995@gmail.com>
Co-authored-by: Arsi Kiikka <arsikiikka20@gmail.com>
Co-authored-by: David Braz <davidbrazps2@gmail.com>
Co-authored-by: Edward <edwardchirita@mailbox.org>
Co-authored-by: Eric <hamburger2048@users.noreply.hosted.weblate.org>
Co-authored-by: Etienne Barrier <etienne.barrier@gmail.com>
Co-authored-by: Fjuro <ifjuro@proton.me>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Igor Rückert <igorruckert@yahoo.com.br>
Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com>
Co-authored-by: Jeff Huang <s8321414@gmail.com>
Co-authored-by: MJ Kim <faith@users.noreply.hosted.weblate.org>
Co-authored-by: Philip Goto <philip.goto@gmail.com>
Co-authored-by: Priit Jõerüüt <hwlate@joeruut.com>
Co-authored-by: Rex_sa <rex.sa@pm.me>
Co-authored-by: ShareASmile <aapshergill@gmail.com>
Co-authored-by: TXRdev Archive <lckphanaf9999@gmail.com>
Co-authored-by: Vasilis K <skyhirules@gmail.com>
Co-authored-by: VfBFan <drop0815@posteo.de>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: kuragehime <kuragehime641@gmail.com>
Co-authored-by: nautilusx <translate@disroot.org>
Co-authored-by: ngocanhtve <ngocanh.tve@gmail.com>
Co-authored-by: random r <epsilin@yopmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: zmni <zmni@outlook.com>
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ar/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/de/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/fr/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ja/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ko/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/nl/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sv/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/vi/
Translation: NewPipe/Metadata
2023-07-24 19:04:23 +02:00
Tobi
3edd4c012d Merge pull request #10195 from AudricV/player_refactor-renderers-activation-or-deactivation
Refactor Player.useVideoSource logic and improve its comments
2023-07-22 14:12:35 +02:00
Tobi
3243f97ff2 Merge pull request #10233 from TeamNewPipe/actions/mimmizer-pr
Minimize images in PR descriptions
2023-07-20 23:18:03 +02:00
Isira Seneviratne
c658f28b02 Merge pull request #10078 from Isira-Seneviratne/Improve_feed_notifications
Improve new stream notifications
2023-07-20 06:39:19 +05:30
AudricV
5ab3a4a9e0 Refactor Player.useVideoSource logic and improve its comments
- don't check for isAudioOnly == !videoEnabled, as this prevents enabling again
video and text tracks renderers in some cases;
- when reloading play queue manager if that's needed, disable or enable video
and text tracks renderers, as they may need to be enabled again in some cases
like starting a video in main player, opening play queue, switching to
background player on it and switching back to main player;
- disable or enable video renderers also for streams with AUDIO_STREAM
StreamType, as doing so doesn't raise any issue and simplifies code;
- reword and move some comments to make them easier to understand.
2023-07-19 22:52:18 +02:00
Isira Seneviratne
cb00c57009 Set channel icon for stream notifications 2023-07-19 05:52:59 +05:30
Tobi
cd2884d412 Merge pull request #10235 from TacoTheDank/bumpRoom
Update AndroidX Room library
2023-07-18 22:35:30 +02:00
Tobi
471137093a Merge pull request #9719 from Marius1501/tabs_on_bottom
Added bottom main-tabs feature
2023-07-18 22:03:47 +02:00
Tobi
57064479c8 Merge pull request #8456 from SydneyDrone/database_tests
Add database test for SubscriptionManager
2023-07-18 08:55:35 +02:00
Stypox
528bd502b4 Improve SubscriptionManager tests
- fix checkstyle errors
- tests do not run in order, so each one has to do its own assertions separately from what others did
- the uid of an entity in the database needn't be the same of the one created in-memory, since the uid gets assigned upon inserting in the database
- some database functions return a `Completable` that doesn't do anything until it is subscribed to or awaited, so I added `.awaitBlocking()` where needed
- the data of an entity in-memory does not get updated automatically when the corresponding entity in the database is changed, so some tests have been removed
- `manager.insertSubscription` only inserts recent streams, so they need to have a date set on them (I also made related items hardcoded and not dependent on what the channel is currently doing)
2023-07-18 08:36:29 +02:00
SydneyDrone
90bc1905f5 Create SubscriptionManagerTest.java 2023-07-18 08:36:29 +02:00
TacoTheDank
a01e59e9db Update AndroidX Room library 2023-07-17 21:09:44 -04:00
TacoTheDank
3f944c1bb2 Fix MigrationTestHelper deprecation 2023-07-17 21:09:21 -04:00
Tobi
43ef852117 Merge pull request #10230 from TeamNewPipe/fix/offline-stream-chooser
[Download] Fix audio stream selection
2023-07-17 23:47:21 +02:00
TobiGr
bf22515bcd Fix README 2023-07-17 22:18:08 +02:00
Tobi
4c17c7b45b Merge pull request #10240 from TeamNewPipe/readmes
Add translated READMEs
2023-07-17 22:08:31 +02:00
TobiGr
ec21200787 Add links to all READMEs 2023-07-17 21:38:26 +02:00
TobiGr
25fea73704 Add Russian README
Taken from #8711 with updated screenshots

Co-authored-by:  Vik <63919734+ViktorOn@users.noreply.github.com>
2023-07-17 21:38:26 +02:00
TobiGr
2377d85efb Add German README
Taken from #8712 with updated screenshots and applied reviews.

Co-authored-by: Nico Haas <nico.haas@aisec.fraunhofer.de>
Co-authored-by: poolitzer <github@poolitzer.eu>
Co-authered-by: TobiGr <tobigr@users.noreply.github.com>
2023-07-17 21:38:26 +02:00
TobiGr
ddef550637 Add French README
Taken from #9296 with updated screenshots

Co-authored-by: eze-kiel <hugoblanc@fastmail.com>
2023-07-17 21:38:26 +02:00
Tobi
2f0ed7f3b7 Merge pull request #10232 from Stypox/leakcanary-fix
Fix LeakCanary startup in debug builds and fix a memory leak
2023-07-17 19:42:24 +02:00
TobiGr
b6bdd359d6 Add Assamese README
Taken from #9618 with updated screenshots

Co-authored-by:  Abhilash <121420261+WirelessAlien@users.noreply.github.com>
2023-07-17 18:54:38 +02:00
TobiGr
a4453bc699 Add Punjabi README
Taken from #9621 with updated screenshots.

Co-authored-by:  K Gill <60492161+ShareASmile@users.noreply.github.com>
2023-07-17 18:54:38 +02:00
TobiGr
3e87c40856 Add Italian README
Taken from #10157

Co-authored-by:  Mirko Di <84203046+mirk0dex@users.noreply.github.com>
2023-07-17 18:54:38 +02:00
Tobi
d80e531a2e Merge pull request #9421 from seojun0924/patch-2
Update README.ko.md
2023-07-17 16:28:48 +02:00
Tobi
d25e84a461 Merge pull request #9897 from rogerjs93/patch-1
Update README.es.md
2023-07-17 01:40:17 +02:00
TobiGr
05cc520665 Fix pure logo
The previous version was not properly vertically aligned. The default alignement from the logo is used now.
2023-07-17 01:28:55 +02:00
TobiGr
eeec6fd002 Replace null check with use of NotificationManagerCompat.from 2023-07-17 01:28:55 +02:00
Isira Seneviratne
795bc82c7f Show number of new streams in the collapsed summary notification. 2023-07-17 01:28:55 +02:00
Isira Seneviratne
7742c40ac0 Create individual stream notifications for convenience on Android 7.0 and later. 2023-07-17 01:28:55 +02:00
TobiGr
d9e2ada369 Minimize images in PR descriptions 2023-07-15 02:33:53 +02:00
Stypox
5d6158ea76 No need to manually mark fragment as destroyed for LeakCanary
It already does so automatically.
2023-07-14 20:48:05 +02:00
Stypox
00257e969e Fix PlayerService leakead by Binder instance
Also see https://stackoverflow.com/q/63787707
2023-07-14 18:34:20 +02:00
Stypox
135f0f7249 Make all leak canary libs debugImplementation-only 2023-07-14 18:32:30 +02:00
Stypox
fdd8b76add Fix DebugApp doing unneeded AppWatcher.manualInstall 2023-07-14 18:32:04 +02:00
TobiGr
6b7ffbba4c [Download] Fix audio stream selection
Closes #10180
2023-07-14 17:06:12 +02:00
Tobi
8cfba4003d Merge pull request #10229 from Koitharu/bugfix/feed_crash
Fix crash after feed update
2023-07-14 15:31:12 +02:00
Koitharu
01b46edf1a Fix crash after feed update 2023-07-14 11:41:52 +03:00
Stypox
f8599d17c2 Merge pull request #10085 from TacoTheDank/bumpLeakCanary
Update LeakCanary library
2023-07-12 19:05:38 +02:00
TacoTheDank
db7de05f2b Update LeakCanary library 2023-07-11 20:32:29 -04:00
Roger Salas
bb1f5d8f38 Update README.es.md 2023-03-08 19:27:13 +02:00
Stypox
65680b2ccf Only update main tabs position when it changes 2023-02-26 15:58:09 +01:00
Stypox
c8ffe65acf Simplify code to set tab layout position 2023-02-26 15:42:49 +01:00
ge78fug
26b29ca78d Made the requested color changes 2023-02-07 18:46:40 +01:00
ge78fug
38db0cc713 Changed the color 2023-01-31 16:07:57 +01:00
Marius Wagner
ee217eb9b7 Merge branch 'TeamNewPipe:dev' into tabs_on_bottom 2023-01-31 13:37:47 +01:00
Marius Wagner
2b37721a6e Update app/src/main/res/values/strings.xml
Co-authored-by: Stypox <stypox@pm.me>
2023-01-29 19:37:46 +01:00
ge78fug
0821f6463a Added bottom main-tabs feature 2023-01-25 19:25:57 +01:00
seojun0924
16b0df69b1 Update README.ko.md
Updated Korean README with latest version of README
2022-11-19 01:03:18 +09:00
418 changed files with 13120 additions and 3767 deletions

View File

@@ -14,7 +14,7 @@ body:
attributes:
label: "Checklist"
options:
- label: "I am able to reproduce the bug with the [latest version](https://github.com/TeamNewPipe/NewPipe/releases/latest)."
- label: "I am able to reproduce the bug with the latest version given here: [CLICK THIS LINK](https://github.com/TeamNewPipe/NewPipe/releases/latest)."
required: true
- label: "I made sure that there are *no existing issues* - [open](https://github.com/TeamNewPipe/NewPipe/issues) or [closed](https://github.com/TeamNewPipe/NewPipe/issues?q=is%3Aissue+is%3Aclosed) - which I could contribute my information to."
required: true

17
.github/changed-lines-count-labeler.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
# Add 'size/small' label to any changes with less than 50 lines
size/small:
max: 49
# Add 'size/medium' label to any changes between 50 and 249 lines
size/medium:
min: 50
max: 249
# Add 'size/large' label to any changes between 250 and 749 lines
size/large:
min: 250
max: 749
# Add 'size/giant' label to any changes for more than 749 lines
size/giant:
min: 750

View File

@@ -17,6 +17,8 @@ module.exports = async ({github, context}) => {
initialBody = context.payload.comment.body;
} else if (context.eventName == 'issues') {
initialBody = context.payload.issue.body;
} else if (context.eventName == 'pull_request') {
initialBody = context.payload.pull_request.body;
} else {
console.log('Aborting: No body found');
return;
@@ -74,9 +76,17 @@ module.exports = async ({github, context}) => {
repo: context.repo.repo,
body: newBody
});
} else if (context.eventName == 'pull_request') {
console.log('Updating pull request', context.payload.pull_request.number);
await github.rest.pulls.update({
pull_number: context.payload.pull_request.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: newBody
});
}
// Asnyc replace function from https://stackoverflow.com/a/48032528
// Async replace function from https://stackoverflow.com/a/48032528
async function replaceAsync(str, regex, asyncFn) {
const promises = [];
str.replace(regex, (match, ...args) => {
@@ -128,7 +138,7 @@ module.exports = async ({github, context}) => {
if (shouldModify) {
wasMatchModified = true;
console.log(`Modifying match '${match}'`);
return `<img alt="${g1}" src="${g2}" width=${Math.min(600, (IMG_MAX_HEIGHT_PX * probeAspectRatio).toFixed(0))} />`;
return `<img alt="${g1}" src="${g2}" width=${Math.min(600, Math.floor(IMG_MAX_HEIGHT_PX * probeAspectRatio))} />`;
}
console.log(`Match '${match}' is ok/will not be modified`);

View File

@@ -5,6 +5,8 @@ on:
types: [created, edited]
issues:
types: [opened, edited]
pull_request:
types: [opened, edited]
permissions:
issues: write

18
.github/workflows/pr-labeler.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
name: "PR size labeler"
on: [pull_request]
permissions:
contents: read
pull-requests: write
jobs:
changed-lines-count-labeler:
runs-on: ubuntu-latest
name: Automatically labelling pull requests based on the changed lines count
permissions:
pull-requests: write
steps:
- name: Set a label
uses: TeamNewPipe/changed-lines-count-labeler@main
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
configuration-path: .github/changed-lines-count-labeler.yml

File diff suppressed because one or more lines are too long

View File

@@ -20,8 +20,8 @@ android {
resValue "string", "app_name", "NewPipe"
minSdk 21
targetSdk 33
versionCode 993
versionName "0.25.1"
versionCode 996
versionName "0.26.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -50,9 +50,6 @@ android {
}
}
// Keep the release build type at the end of the list to override 'archivesBaseName' of
// debug build. This seems to be a Gradle bug, therefore
// TODO: update Gradle version
release {
if (System.properties.containsKey('packageSuffix')) {
applicationIdSuffix System.getProperty('packageSuffix')
@@ -110,16 +107,16 @@ ext {
checkstyleVersion = '10.12.1'
androidxLifecycleVersion = '2.5.1'
androidxRoomVersion = '2.4.3'
androidxRoomVersion = '2.5.2'
androidxWorkVersion = '2.7.1'
icepickVersion = '3.2.0'
exoPlayerVersion = '2.18.7'
googleAutoServiceVersion = '1.0.1'
googleAutoServiceVersion = '1.1.1'
groupieVersion = '2.10.1'
markwonVersion = '4.6.2'
leakCanaryVersion = '2.9.1'
leakCanaryVersion = '2.12'
stethoVersion = '1.6.0'
mockitoVersion = '4.0.0'
}
@@ -192,7 +189,7 @@ sonar {
dependencies {
/** Desugaring **/
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs_nio:2.0.3'
/** NewPipe libraries **/
// You can use a local version by uncommenting a few lines in settings.gradle
@@ -200,7 +197,7 @@ dependencies {
// name and the commit hash with the commit hash of the (pushed) commit you want to test
// This works thanks to JitPack: https://jitpack.io/
implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751'
implementation 'com.github.TeamNewPipe:NewPipeExtractor:8495ad619e'
implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.23.1'
implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0'
/** Checkstyle **/
@@ -208,7 +205,7 @@ dependencies {
ktlint 'com.pinterest:ktlint:0.45.2'
/** Kotlin **/
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin_version}"
implementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}"
/** AndroidX **/
implementation 'androidx.appcompat:appcompat:1.5.1'
@@ -232,7 +229,7 @@ dependencies {
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01'
implementation "androidx.work:work-runtime-ktx:${androidxWorkVersion}"
implementation "androidx.work:work-rxjava3:${androidxWorkVersion}"
implementation 'com.google.android.material:material:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
/** Third-party libraries **/
// Instance state boilerplate elimination
@@ -244,6 +241,9 @@ dependencies {
// HTTP client
implementation "com.squareup.okhttp3:okhttp:4.11.0"
// okhttp3:4.11.0 introduces a vulnerability from com.squareup.okio:okio@3.3.0,
// remove com.squareup.okio:okio when updating okhttp
implementation "com.squareup.okio:okio:3.4.0"
// Media player
implementation "com.google.android.exoplayer:exoplayer-core:${exoPlayerVersion}"
@@ -288,9 +288,9 @@ dependencies {
/** Debugging **/
// Memory leak detection
implementation "com.squareup.leakcanary:leakcanary-object-watcher-android:${leakCanaryVersion}"
implementation "com.squareup.leakcanary:plumber-android:${leakCanaryVersion}"
debugImplementation "com.squareup.leakcanary:leakcanary-android:${leakCanaryVersion}"
debugImplementation "com.squareup.leakcanary:leakcanary-object-watcher-android:${leakCanaryVersion}"
debugImplementation "com.squareup.leakcanary:plumber-android:${leakCanaryVersion}"
debugImplementation "com.squareup.leakcanary:leakcanary-android-core:${leakCanaryVersion}"
// Debug bridge for Android
debugImplementation "com.facebook.stetho:stetho:${stethoVersion}"
debugImplementation "com.facebook.stetho:stetho-okhttp3:${stethoVersion}"

View File

@@ -4,7 +4,6 @@ import android.content.ContentValues
import android.database.sqlite.SQLiteDatabase
import androidx.room.Room
import androidx.room.testing.MigrationTestHelper
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
@@ -33,8 +32,7 @@ class DatabaseMigrationTest {
@get:Rule
val testHelper = MigrationTestHelper(
InstrumentationRegistry.getInstrumentation(),
AppDatabase::class.java.canonicalName,
FrameworkSQLiteOpenHelperFactory()
AppDatabase::class.java
)
@Test

View File

@@ -0,0 +1,124 @@
package org.schabi.newpipe.database
import android.content.Context
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import io.reactivex.rxjava3.core.Single
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Test
import org.schabi.newpipe.database.feed.dao.FeedDAO
import org.schabi.newpipe.database.feed.model.FeedEntity
import org.schabi.newpipe.database.feed.model.FeedGroupEntity
import org.schabi.newpipe.database.stream.StreamWithState
import org.schabi.newpipe.database.stream.dao.StreamDAO
import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.database.subscription.SubscriptionDAO
import org.schabi.newpipe.database.subscription.SubscriptionEntity
import org.schabi.newpipe.extractor.ServiceList
import org.schabi.newpipe.extractor.channel.ChannelInfo
import org.schabi.newpipe.extractor.stream.StreamType
import java.io.IOException
import java.time.OffsetDateTime
import kotlin.streams.toList
class FeedDAOTest {
private lateinit var db: AppDatabase
private lateinit var feedDAO: FeedDAO
private lateinit var streamDAO: StreamDAO
private lateinit var subscriptionDAO: SubscriptionDAO
private val serviceId = ServiceList.YouTube.serviceId
private val stream1 = StreamEntity(1, serviceId, "https://youtube.com/watch?v=1", "stream 1", StreamType.VIDEO_STREAM, 1000, "channel-1", "https://youtube.com/channel/1", "https://i.ytimg.com/vi/1/hqdefault.jpg", 100, "2023-01-01", OffsetDateTime.parse("2023-01-01T00:00:00Z"))
private val stream2 = StreamEntity(2, serviceId, "https://youtube.com/watch?v=2", "stream 2", StreamType.VIDEO_STREAM, 1000, "channel-1", "https://youtube.com/channel/1", "https://i.ytimg.com/vi/1/hqdefault.jpg", 100, "2023-01-02", OffsetDateTime.parse("2023-01-02T00:00:00Z"))
private val stream3 = StreamEntity(3, serviceId, "https://youtube.com/watch?v=3", "stream 3", StreamType.LIVE_STREAM, 1000, "channel-1", "https://youtube.com/channel/1", "https://i.ytimg.com/vi/1/hqdefault.jpg", 100, "2023-01-03", OffsetDateTime.parse("2023-01-03T00:00:00Z"))
private val stream4 = StreamEntity(4, serviceId, "https://youtube.com/watch?v=4", "stream 4", StreamType.VIDEO_STREAM, 1000, "channel-2", "https://youtube.com/channel/2", "https://i.ytimg.com/vi/1/hqdefault.jpg", 100, "2023-08-10", OffsetDateTime.parse("2023-08-10T00:00:00Z"))
private val stream5 = StreamEntity(5, serviceId, "https://youtube.com/watch?v=5", "stream 5", StreamType.VIDEO_STREAM, 1000, "channel-2", "https://youtube.com/channel/2", "https://i.ytimg.com/vi/1/hqdefault.jpg", 100, "2023-08-20", OffsetDateTime.parse("2023-08-20T00:00:00Z"))
private val stream6 = StreamEntity(6, serviceId, "https://youtube.com/watch?v=6", "stream 6", StreamType.VIDEO_STREAM, 1000, "channel-3", "https://youtube.com/channel/3", "https://i.ytimg.com/vi/1/hqdefault.jpg", 100, "2023-09-01", OffsetDateTime.parse("2023-09-01T00:00:00Z"))
private val stream7 = StreamEntity(7, serviceId, "https://youtube.com/watch?v=7", "stream 7", StreamType.VIDEO_STREAM, 1000, "channel-4", "https://youtube.com/channel/4", "https://i.ytimg.com/vi/1/hqdefault.jpg", 100, "2023-08-10", OffsetDateTime.parse("2023-08-10T00:00:00Z"))
private val allStreams = listOf(
stream1, stream2, stream3, stream4, stream5, stream6, stream7
)
@Before
fun createDb() {
val context = ApplicationProvider.getApplicationContext<Context>()
db = Room.inMemoryDatabaseBuilder(
context, AppDatabase::class.java
).build()
feedDAO = db.feedDAO()
streamDAO = db.streamDAO()
subscriptionDAO = db.subscriptionDAO()
}
@After
@Throws(IOException::class)
fun closeDb() {
db.close()
}
@Test
fun testUnlinkStreamsOlderThan_KeepOne() {
setupUnlinkDelete("2023-08-15T00:00:00Z")
val streams = feedDAO.getStreams(
FeedGroupEntity.GROUP_ALL_ID, includePlayed = true, includePartiallyPlayed = true, null
)
.blockingGet()
val allowedStreams = listOf(stream3, stream5, stream6, stream7)
assertEqual(streams, allowedStreams)
}
@Test
fun testUnlinkStreamsOlderThan_KeepMultiple() {
setupUnlinkDelete("2023-08-01T00:00:00Z")
val streams = feedDAO.getStreams(
FeedGroupEntity.GROUP_ALL_ID, includePlayed = true, includePartiallyPlayed = true, null
)
.blockingGet()
val allowedStreams = listOf(stream3, stream4, stream5, stream6, stream7)
assertEqual(streams, allowedStreams)
}
private fun assertEqual(streams: List<StreamWithState>?, allowedStreams: List<StreamEntity>) {
assertNotNull(streams)
assertEquals(allowedStreams, streams!!.stream().map { it.stream }.toList().sortedBy { it.uid })
}
private fun setupUnlinkDelete(time: String) {
clearAndFillTables()
Single.fromCallable {
feedDAO.unlinkStreamsOlderThan(OffsetDateTime.parse(time))
}.blockingSubscribe()
Single.fromCallable {
streamDAO.deleteOrphans()
}.blockingSubscribe()
}
private fun clearAndFillTables() {
db.clearAllTables()
streamDAO.insertAll(allStreams)
subscriptionDAO.insertAll(
listOf(
SubscriptionEntity.from(ChannelInfo(serviceId, "1", "https://youtube.com/channel/1", "https://youtube.com/channel/1", "channel-1")),
SubscriptionEntity.from(ChannelInfo(serviceId, "2", "https://youtube.com/channel/2", "https://youtube.com/channel/2", "channel-2")),
SubscriptionEntity.from(ChannelInfo(serviceId, "3", "https://youtube.com/channel/3", "https://youtube.com/channel/3", "channel-3")),
SubscriptionEntity.from(ChannelInfo(serviceId, "4", "https://youtube.com/channel/4", "https://youtube.com/channel/4", "channel-4")),
)
)
feedDAO.insertAll(
listOf(
FeedEntity(1, 1),
FeedEntity(2, 1),
FeedEntity(3, 1),
FeedEntity(4, 2),
FeedEntity(5, 2),
FeedEntity(6, 3),
FeedEntity(7, 4),
)
)
}
}

View File

@@ -0,0 +1,82 @@
package org.schabi.newpipe.local.subscription;
import static org.junit.Assert.assertEquals;
import androidx.test.core.app.ApplicationProvider;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.schabi.newpipe.database.AppDatabase;
import org.schabi.newpipe.database.feed.model.FeedGroupEntity;
import org.schabi.newpipe.database.subscription.SubscriptionEntity;
import org.schabi.newpipe.extractor.channel.ChannelInfo;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.testUtil.TestDatabase;
import org.schabi.newpipe.testUtil.TrampolineSchedulerRule;
import java.io.IOException;
import java.util.List;
public class SubscriptionManagerTest {
private AppDatabase database;
private SubscriptionManager manager;
@Rule
public TrampolineSchedulerRule trampolineScheduler = new TrampolineSchedulerRule();
private SubscriptionEntity getAssertOneSubscriptionEntity() {
final List<SubscriptionEntity> entities = manager
.getSubscriptions(FeedGroupEntity.GROUP_ALL_ID, "", false)
.blockingFirst();
assertEquals(1, entities.size());
return entities.get(0);
}
@Before
public void setup() {
database = TestDatabase.Companion.createReplacingNewPipeDatabase();
manager = new SubscriptionManager(ApplicationProvider.getApplicationContext());
}
@After
public void cleanUp() {
database.close();
}
@Test
public void testInsert() throws ExtractionException, IOException {
final ChannelInfo info = ChannelInfo.getInfo("https://www.youtube.com/c/3blue1brown");
final SubscriptionEntity subscription = SubscriptionEntity.from(info);
manager.insertSubscription(subscription);
final SubscriptionEntity readSubscription = getAssertOneSubscriptionEntity();
// the uid has changed, since the uid is chosen upon inserting, but the rest should match
assertEquals(subscription.getServiceId(), readSubscription.getServiceId());
assertEquals(subscription.getUrl(), readSubscription.getUrl());
assertEquals(subscription.getName(), readSubscription.getName());
assertEquals(subscription.getAvatarUrl(), readSubscription.getAvatarUrl());
assertEquals(subscription.getSubscriberCount(), readSubscription.getSubscriberCount());
assertEquals(subscription.getDescription(), readSubscription.getDescription());
}
@Test
public void testUpdateNotificationMode() throws ExtractionException, IOException {
final ChannelInfo info = ChannelInfo.getInfo("https://www.youtube.com/c/veritasium");
final SubscriptionEntity subscription = SubscriptionEntity.from(info);
subscription.setNotificationMode(0);
manager.insertSubscription(subscription);
manager.updateNotificationMode(subscription.getServiceId(), subscription.getUrl(), 1)
.blockingAwait();
final SubscriptionEntity anotherSubscription = getAssertOneSubscriptionEntity();
assertEquals(0, subscription.getNotificationMode());
assertEquals(subscription.getUrl(), anotherSubscription.getUrl());
assertEquals(1, anotherSubscription.getNotificationMode());
}
}

View File

@@ -12,15 +12,21 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.test.internal.runner.junit4.statement.UiThreadStatement
import org.junit.Assert
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.schabi.newpipe.R
import org.schabi.newpipe.extractor.MediaFormat
import org.schabi.newpipe.extractor.downloader.Response
import org.schabi.newpipe.extractor.stream.AudioStream
import org.schabi.newpipe.extractor.stream.Stream
import org.schabi.newpipe.extractor.stream.SubtitlesStream
import org.schabi.newpipe.extractor.stream.VideoStream
import org.schabi.newpipe.util.StreamItemAdapter.StreamInfoWrapper
@MediumTest
@RunWith(AndroidJUnit4::class)
@@ -84,7 +90,7 @@ class StreamItemAdapterTest {
@Test
fun subtitleStreams_noIcon() {
val adapter = StreamItemAdapter<SubtitlesStream, Stream>(
StreamItemAdapter.StreamSizeWrapper(
StreamItemAdapter.StreamInfoWrapper(
(0 until 5).map {
SubtitlesStream.Builder()
.setContent("https://example.com", true)
@@ -105,7 +111,7 @@ class StreamItemAdapterTest {
@Test
fun audioStreams_noIcon() {
val adapter = StreamItemAdapter<AudioStream, Stream>(
StreamItemAdapter.StreamSizeWrapper(
StreamItemAdapter.StreamInfoWrapper(
(0 until 5).map {
AudioStream.Builder()
.setId(Stream.ID_UNKNOWN)
@@ -123,12 +129,109 @@ class StreamItemAdapterTest {
}
}
@Test
fun retrieveMediaFormatFromFileTypeHeaders() {
val streams = getIncompleteAudioStreams(5)
val wrapper = StreamInfoWrapper(streams, context)
val retrieveMediaFormat = { stream: AudioStream, response: Response ->
StreamInfoWrapper.retrieveMediaFormatFromFileTypeHeaders(stream, wrapper, response)
}
val helper = AssertionHelper(streams, wrapper, retrieveMediaFormat)
helper.assertInvalidResponse(getResponse(mapOf(Pair("content-length", "mp3"))), 0)
helper.assertInvalidResponse(getResponse(mapOf(Pair("file-type", "mp0"))), 1)
helper.assertValidResponse(getResponse(mapOf(Pair("x-amz-meta-file-type", "aiff"))), 2, MediaFormat.AIFF)
helper.assertValidResponse(getResponse(mapOf(Pair("file-type", "mp3"))), 3, MediaFormat.MP3)
}
@Test
fun retrieveMediaFormatFromContentDispositionHeader() {
val streams = getIncompleteAudioStreams(11)
val wrapper = StreamInfoWrapper(streams, context)
val retrieveMediaFormat = { stream: AudioStream, response: Response ->
StreamInfoWrapper.retrieveMediaFormatFromContentDispositionHeader(stream, wrapper, response)
}
val helper = AssertionHelper(streams, wrapper, retrieveMediaFormat)
helper.assertInvalidResponse(getResponse(mapOf(Pair("content-length", "mp3"))), 0)
helper.assertInvalidResponse(
getResponse(mapOf(Pair("Content-Disposition", "filename=\"train.png\""))), 1
)
helper.assertInvalidResponse(
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"data.csv\""))), 2
)
helper.assertInvalidResponse(
getResponse(mapOf(Pair("Content-Disposition", "form-data; filename=\"data.csv\""))), 3
)
helper.assertInvalidResponse(
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"fieldName\"; filename*=\"filename.jpg\""))), 4
)
helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Disposition", "filename=\"train.ogg\""))),
5, MediaFormat.OGG
)
helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Disposition", "some-form-data; filename=\"audio.flac\""))),
6, MediaFormat.FLAC
)
helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.aiff\"; filename=\"audio.aiff\""))),
7, MediaFormat.AIFF
)
helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"alien?\"; filename*=UTF-8''%CE%B1%CE%BB%CE%B9%CF%B5%CE%BD.m4a"))),
8, MediaFormat.M4A
)
helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.mp3\"; filename=\"audio.opus\"; filename*=UTF-8''alien.opus"))),
9, MediaFormat.OPUS
)
helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.mp3\"; filename=\"audio.opus\"; filename*=\"UTF-8''alien.opus\""))),
10, MediaFormat.OPUS
)
}
@Test
fun retrieveMediaFormatFromContentTypeHeader() {
val streams = getIncompleteAudioStreams(12)
val wrapper = StreamInfoWrapper(streams, context)
val retrieveMediaFormat = { stream: AudioStream, response: Response ->
StreamInfoWrapper.retrieveMediaFormatFromContentTypeHeader(stream, wrapper, response)
}
val helper = AssertionHelper(streams, wrapper, retrieveMediaFormat)
helper.assertInvalidResponse(getResponse(mapOf(Pair("content-length", "984501"))), 0)
helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "audio/xyz"))), 1)
helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "mp3"))), 2)
helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "mp3"))), 3)
helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "audio/mpeg"))), 4)
helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "audio/aif"))), 5)
helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "whatever"))), 6)
helper.assertInvalidResponse(getResponse(mapOf()), 7)
helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Type", "audio/flac"))), 8, MediaFormat.FLAC
)
helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Type", "audio/wav"))), 9, MediaFormat.WAV
)
helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Type", "audio/opus"))), 10, MediaFormat.OPUS
)
helper.assertValidResponse(
getResponse(mapOf(Pair("Content-Type", "audio/aiff"))), 11, MediaFormat.AIFF
)
}
/**
* @return a list of video streams, in which their video only property mirrors the provided
* [videoOnly] vararg.
*/
private fun getVideoStreams(vararg videoOnly: Boolean) =
StreamItemAdapter.StreamSizeWrapper(
StreamItemAdapter.StreamInfoWrapper(
videoOnly.map {
VideoStream.Builder()
.setId(Stream.ID_UNKNOWN)
@@ -161,6 +264,19 @@ class StreamItemAdapterTest {
}
)
private fun getIncompleteAudioStreams(size: Int): List<AudioStream> {
val list = ArrayList<AudioStream>(size)
for (i in 1..size) {
list.add(
AudioStream.Builder()
.setId(Stream.ID_UNKNOWN)
.setContent("https://example.com/$i", true)
.build()
)
}
return list
}
/**
* Checks whether the item at [position] in the [spinner] has the correct icon visibility when
* it is shown in normal mode (selected) and in dropdown mode (user is choosing one of a list).
@@ -196,11 +312,56 @@ class StreamItemAdapterTest {
streams.forEachIndexed { index, stream ->
val secondaryStreamHelper: SecondaryStreamHelper<T>? = stream?.let {
SecondaryStreamHelper(
StreamItemAdapter.StreamSizeWrapper(streams, context),
StreamItemAdapter.StreamInfoWrapper(streams, context),
it
)
}
put(index, secondaryStreamHelper)
}
}
private fun getResponse(headers: Map<String, String>): Response {
val listHeaders = HashMap<String, List<String>>()
headers.forEach { entry ->
listHeaders[entry.key] = listOf(entry.value)
}
return Response(200, null, listHeaders, "", "")
}
/**
* Helper class for assertion related to extractions of [MediaFormat]s.
*/
class AssertionHelper<T : Stream>(
private val streams: List<T>,
private val wrapper: StreamInfoWrapper<T>,
private val retrieveMediaFormat: (stream: T, response: Response) -> Boolean
) {
/**
* Assert that an invalid response does not result in wrongly extracted [MediaFormat].
*/
fun assertInvalidResponse(
response: Response,
index: Int
) {
assertFalse(
"invalid header returns valid value", retrieveMediaFormat(streams[index], response)
)
assertNull("Media format extracted although stated otherwise", wrapper.getFormat(index))
}
/**
* Assert that a valid response results in correctly extracted and handled [MediaFormat].
*/
fun assertValidResponse(
response: Response,
index: Int,
format: MediaFormat
) {
assertTrue(
"header was not recognized", retrieveMediaFormat(streams[index], response)
)
assertEquals("Wrong media format extracted", format, wrapper.getFormat(index))
}
}
}

View File

@@ -3,7 +3,6 @@ package org.schabi.newpipe
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
@@ -13,8 +12,6 @@ class DebugApp : App() {
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(

View File

@@ -20,9 +20,11 @@ import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.ktx.ExceptionUtils;
import org.schabi.newpipe.settings.NewPipeSettings;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.PicassoHelper;
import org.schabi.newpipe.util.image.ImageStrategy;
import org.schabi.newpipe.util.image.PicassoHelper;
import org.schabi.newpipe.util.ServiceHelper;
import org.schabi.newpipe.util.StateSaver;
import org.schabi.newpipe.util.image.PreferredImageQuality;
import java.io.IOException;
import java.io.InterruptedIOException;
@@ -99,8 +101,9 @@ public class App extends Application {
// Initialize image loader
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
PicassoHelper.init(this);
PicassoHelper.setShouldLoadImages(
prefs.getBoolean(getString(R.string.download_thumbnail_key), true));
ImageStrategy.setPreferredImageQuality(PreferredImageQuality.fromPreferenceKey(this,
prefs.getString(getString(R.string.image_quality_key),
getString(R.string.image_quality_default))));
PicassoHelper.setIndicatorsEnabled(MainActivity.DEBUG
&& prefs.getBoolean(getString(R.string.show_image_indicators_key), false));

View File

@@ -12,7 +12,6 @@ import androidx.fragment.app.FragmentManager;
import icepick.Icepick;
import icepick.State;
import leakcanary.AppWatcher;
public abstract class BaseFragment extends Fragment {
protected final String TAG = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
@@ -77,20 +76,33 @@ public abstract class BaseFragment extends Fragment {
protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) {
}
@Override
public void onDestroy() {
super.onDestroy();
AppWatcher.INSTANCE.getObjectWatcher().watch(this);
}
/*//////////////////////////////////////////////////////////////////////////
// Init
//////////////////////////////////////////////////////////////////////////*/
/**
* This method is called in {@link #onViewCreated(View, Bundle)} to initialize the views.
*
* <p>
* {@link #initListeners()} is called after this method to initialize the corresponding
* listeners.
* </p>
* @param rootView The inflated view for this fragment
* (provided by {@link #onViewCreated(View, Bundle)})
* @param savedInstanceState The saved state of this fragment
* (provided by {@link #onViewCreated(View, Bundle)})
*/
protected void initViews(final View rootView, final Bundle savedInstanceState) {
}
/**
* Initialize the listeners for this fragment.
*
* <p>
* This method is called after {@link #initViews(View, Bundle)}
* in {@link #onViewCreated(View, Bundle)}.
* </p>
*/
protected void initListeners() {
}
@@ -108,9 +120,20 @@ public abstract class BaseFragment extends Fragment {
}
}
/**
* Finds the root fragment by looping through all of the parent fragments. The root fragment
* is supposed to be {@link org.schabi.newpipe.fragments.MainFragment}, and is the fragment that
* handles keeping the backstack of opened fragments in NewPipe, and also the player bottom
* sheet. This function therefore returns the fragment manager of said fragment.
*
* @return the fragment manager of the root fragment, i.e.
* {@link org.schabi.newpipe.fragments.MainFragment}
*/
protected FragmentManager getFM() {
return getParentFragment() == null
? getFragmentManager()
: getParentFragment().getFragmentManager();
Fragment current = this;
while (current.getParentFragment() != null) {
current = current.getParentFragment();
}
return current.getFragmentManager();
}
}

View File

@@ -219,14 +219,14 @@ public class MainActivity extends AppCompatActivity {
final int currentServiceId = ServiceHelper.getSelectedServiceId(this);
final StreamingService service = NewPipe.getService(currentServiceId);
int kioskId = 0;
int kioskMenuItemId = 0;
for (final String ks : service.getKioskList().getAvailableKiosks()) {
drawerLayoutBinding.navigation.getMenu()
.add(R.id.menu_tabs_group, kioskId, 0, KioskTranslator
.add(R.id.menu_tabs_group, kioskMenuItemId, 0, KioskTranslator
.getTranslatedKioskName(ks, this))
.setIcon(KioskTranslator.getKioskIcon(ks));
kioskId++;
kioskMenuItemId++;
}
drawerLayoutBinding.navigation.getMenu()
@@ -306,20 +306,16 @@ public class MainActivity extends AppCompatActivity {
NavigationHelper.openStatisticFragment(getSupportFragmentManager());
break;
default:
final int currentServiceId = ServiceHelper.getSelectedServiceId(this);
final StreamingService service = NewPipe.getService(currentServiceId);
String serviceName = "";
int kioskId = 0;
for (final String ks : service.getKioskList().getAvailableKiosks()) {
if (kioskId == item.getItemId()) {
serviceName = ks;
final StreamingService currentService = ServiceHelper.getSelectedService(this);
int kioskMenuItemId = 0;
for (final String kioskId : currentService.getKioskList().getAvailableKiosks()) {
if (kioskMenuItemId == item.getItemId()) {
NavigationHelper.openKioskFragment(getSupportFragmentManager(),
currentService.getServiceId(), kioskId);
break;
}
kioskId++;
kioskMenuItemId++;
}
NavigationHelper.openKioskFragment(getSupportFragmentManager(), currentServiceId,
serviceName);
break;
}
}

View File

@@ -120,13 +120,13 @@ class NewVersionWorker(
// Parse the json from the response.
try {
val githubStableObject = JsonParser.`object`()
val newpipeVersionInfo = JsonParser.`object`()
.from(response.responseBody()).getObject("flavors")
.getObject("github").getObject("stable")
.getObject("newpipe")
val versionName = githubStableObject.getString("version")
val versionCode = githubStableObject.getInt("version_code")
val apkLocationUrl = githubStableObject.getString("apk")
val versionName = newpipeVersionInfo.getString("version")
val versionCode = newpipeVersionInfo.getInt("version_code")
val apkLocationUrl = newpipeVersionInfo.getString("apk")
compareAppVersionAndShowNotification(versionName, apkLocationUrl, versionCode)
} catch (e: JsonParserException) {
// Most likely something is wrong in data received from NEWPIPE_API_URL.

View File

@@ -75,7 +75,7 @@ public final class QueueItemMenuUtil {
return true;
case R.id.menu_item_share:
shareText(context, item.getTitle(), item.getUrl(),
item.getThumbnailUrl());
item.getThumbnails());
return true;
case R.id.menu_item_download:
fetchStreamInfoAndSaveToDatabase(context, item.getServiceId(), item.getUrl(),

View File

@@ -45,6 +45,7 @@ import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.databinding.ListRadioIconItemBinding;
import org.schabi.newpipe.databinding.SingleChoiceDialogViewBinding;
import org.schabi.newpipe.download.DownloadDialog;
import org.schabi.newpipe.download.LoadingDialog;
import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.ReCaptchaActivity;
@@ -64,6 +65,7 @@ import org.schabi.newpipe.extractor.exceptions.PrivateContentException;
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipe.extractor.exceptions.SoundCloudGoPlusContentException;
import org.schabi.newpipe.extractor.exceptions.YoutubeMusicPremiumContentException;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.ktx.ExceptionUtils;
@@ -71,10 +73,11 @@ import org.schabi.newpipe.local.dialog.PlaylistDialog;
import org.schabi.newpipe.player.PlayerType;
import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.player.helper.PlayerHolder;
import org.schabi.newpipe.player.playqueue.ChannelPlayQueue;
import org.schabi.newpipe.player.playqueue.ChannelTabPlayQueue;
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.util.ChannelTabHelper;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.ExtractorHelper;
@@ -789,10 +792,10 @@ public class RouterActivity extends AppCompatActivity {
}
}
}, () -> {
}, () ->
// this branch is executed if there is no activity context
inFlight(false);
});
inFlight(false)
);
}
<T> Single<T> pleaseWait(final Single<T> single) {
@@ -812,19 +815,24 @@ public class RouterActivity extends AppCompatActivity {
@SuppressLint("CheckResult")
private void openDownloadDialog(final int currentServiceId, final String currentUrl) {
inFlight(true);
final LoadingDialog loadingDialog = new LoadingDialog(R.string.loading_metadata_title);
loadingDialog.show(getParentFragmentManager(), "loadingDialog");
disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(this::pleaseWait)
.subscribe(result ->
runOnVisible(ctx -> {
loadingDialog.dismiss();
final FragmentManager fm = ctx.getSupportFragmentManager();
final DownloadDialog downloadDialog = new DownloadDialog(ctx, result);
// dismiss listener to be handled by FragmentManager
downloadDialog.show(fm, "downloadDialog");
}
), throwable -> runOnVisible(ctx ->
((RouterActivity) ctx).showUnsupportedUrlDialog(currentUrl))));
), throwable -> runOnVisible(ctx -> {
loadingDialog.dismiss();
((RouterActivity) ctx).showUnsupportedUrlDialog(currentUrl);
})));
}
private void openAddToPlaylistDialog(final int currentServiceId, final String currentUrl) {
@@ -1016,7 +1024,16 @@ public class RouterActivity extends AppCompatActivity {
}
playQueue = new SinglePlayQueue((StreamInfo) info);
} else if (info instanceof ChannelInfo) {
playQueue = new ChannelPlayQueue((ChannelInfo) info);
final Optional<ListLinkHandler> playableTab = ((ChannelInfo) info).getTabs()
.stream()
.filter(ChannelTabHelper::isStreamsTab)
.findFirst();
if (playableTab.isPresent()) {
playQueue = new ChannelTabPlayQueue(info.getServiceId(), playableTab.get());
} else {
return; // there is no playable tab
}
} else if (info instanceof PlaylistInfo) {
playQueue = new PlaylistPlayQueue((PlaylistInfo) info);
} else {

View File

@@ -1,28 +1,38 @@
package org.schabi.newpipe.about
import android.os.Bundle
import android.util.Base64
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.WebView
import androidx.appcompat.app.AlertDialog
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers
import org.schabi.newpipe.BuildConfig
import org.schabi.newpipe.R
import org.schabi.newpipe.databinding.FragmentLicensesBinding
import org.schabi.newpipe.databinding.ItemSoftwareComponentBinding
import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.external_communication.ShareUtils
/**
* Fragment containing the software licenses.
*/
class LicenseFragment : Fragment() {
private lateinit var softwareComponents: Array<SoftwareComponent>
private var activeLicense: License? = null
private var activeSoftwareComponent: SoftwareComponent? = null
private val compositeDisposable = CompositeDisposable()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
softwareComponents = arguments?.getParcelableArray(ARG_COMPONENTS) as Array<SoftwareComponent>
activeLicense = savedInstanceState?.getSerializable(LICENSE_KEY) as? License
activeSoftwareComponent = savedInstanceState?.getSerializable(SOFTWARE_COMPONENT_KEY) as? SoftwareComponent
// Sort components by name
softwareComponents.sortBy { it.name }
}
@@ -39,9 +49,8 @@ class LicenseFragment : Fragment() {
): View {
val binding = FragmentLicensesBinding.inflate(inflater, container, false)
binding.licensesAppReadLicense.setOnClickListener {
activeLicense = StandardLicenses.GPL3
compositeDisposable.add(
showLicense(activity, StandardLicenses.GPL3)
showLicense(NEWPIPE_SOFTWARE_COMPONENT)
)
}
for (component in softwareComponents) {
@@ -57,26 +66,70 @@ class LicenseFragment : Fragment() {
val root: View = componentBinding.root
root.tag = component
root.setOnClickListener {
activeLicense = component.license
compositeDisposable.add(
showLicense(activity, component)
showLicense(component)
)
}
binding.licensesSoftwareComponents.addView(root)
registerForContextMenu(root)
}
activeLicense?.let { compositeDisposable.add(showLicense(activity, it)) }
activeSoftwareComponent?.let { compositeDisposable.add(showLicense(it)) }
return binding.root
}
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
activeLicense?.let { savedInstanceState.putSerializable(LICENSE_KEY, it) }
activeSoftwareComponent?.let { savedInstanceState.putSerializable(SOFTWARE_COMPONENT_KEY, it) }
}
private fun showLicense(
softwareComponent: SoftwareComponent
): Disposable {
return if (context == null) {
Disposable.empty()
} else {
val context = requireContext()
activeSoftwareComponent = softwareComponent
Observable.fromCallable { getFormattedLicense(context, softwareComponent.license) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { formattedLicense ->
val webViewData = Base64.encodeToString(
formattedLicense.toByteArray(), Base64.NO_PADDING
)
val webView = WebView(context)
webView.loadData(webViewData, "text/html; charset=UTF-8", "base64")
Localization.assureCorrectAppLanguage(context)
val builder = AlertDialog.Builder(requireContext())
.setTitle(softwareComponent.name)
.setView(webView)
.setOnCancelListener { activeSoftwareComponent = null }
.setOnDismissListener { activeSoftwareComponent = null }
.setPositiveButton(R.string.done) { dialog, _ -> dialog.dismiss() }
if (softwareComponent != NEWPIPE_SOFTWARE_COMPONENT) {
builder.setNeutralButton(R.string.open_website_license) { _, _ ->
ShareUtils.openUrlInApp(requireContext(), softwareComponent.link)
}
}
builder.show()
}
}
}
companion object {
private const val ARG_COMPONENTS = "components"
private const val LICENSE_KEY = "ACTIVE_LICENSE"
private const val SOFTWARE_COMPONENT_KEY = "ACTIVE_SOFTWARE_COMPONENT"
private val NEWPIPE_SOFTWARE_COMPONENT = SoftwareComponent(
"NewPipe",
"2014-2023",
"Team NewPipe",
"https://newpipe.net/",
StandardLicenses.GPL3,
BuildConfig.VERSION_NAME
)
fun newInstance(softwareComponents: Array<SoftwareComponent>): LicenseFragment {
val fragment = LicenseFragment()
fragment.arguments = bundleOf(ARG_COMPONENTS to softwareComponents)

View File

@@ -1,17 +1,8 @@
package org.schabi.newpipe.about
import android.content.Context
import android.util.Base64
import android.webkit.WebView
import androidx.appcompat.app.AlertDialog
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers
import org.schabi.newpipe.R
import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.ThemeHelper
import org.schabi.newpipe.util.external_communication.ShareUtils
import java.io.IOException
/**
@@ -20,7 +11,7 @@ import java.io.IOException
* @return String which contains a HTML formatted license page
* styled according to the context's theme
*/
private fun getFormattedLicense(context: Context, license: License): String {
fun getFormattedLicense(context: Context, license: License): String {
try {
return context.assets.open(license.filename).bufferedReader().use { it.readText() }
// split the HTML file and insert the stylesheet into the HEAD of the file
@@ -34,7 +25,7 @@ private fun getFormattedLicense(context: Context, license: License): String {
* @param context the Android context
* @return String which is a CSS stylesheet according to the context's theme
*/
private fun getLicenseStylesheet(context: Context): String {
fun getLicenseStylesheet(context: Context): String {
val isLightTheme = ThemeHelper.isLightThemeSelected(context)
val licenseBackgroundColor = getHexRGBColor(
context, if (isLightTheme) R.color.light_license_background_color else R.color.dark_license_background_color
@@ -56,48 +47,6 @@ private fun getLicenseStylesheet(context: Context): String {
* @param color the color number from R.color
* @return a six characters long String with hexadecimal RGB values
*/
private fun getHexRGBColor(context: Context, color: Int): String {
fun getHexRGBColor(context: Context, color: Int): String {
return context.getString(color).substring(3)
}
fun showLicense(context: Context?, component: SoftwareComponent): Disposable {
return showLicense(context, component.license) {
setPositiveButton(R.string.dismiss) { dialog, _ ->
dialog.dismiss()
}
setNeutralButton(R.string.open_website_license) { _, _ ->
ShareUtils.openUrlInApp(context!!, component.link)
}
}
}
fun showLicense(context: Context?, license: License) = showLicense(context, license) {
setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() }
}
private fun showLicense(
context: Context?,
license: License,
block: AlertDialog.Builder.() -> AlertDialog.Builder
): Disposable {
return if (context == null) {
Disposable.empty()
} else {
Observable.fromCallable { getFormattedLicense(context, license) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { formattedLicense ->
val webViewData =
Base64.encodeToString(formattedLicense.toByteArray(), Base64.NO_PADDING)
val webView = WebView(context)
webView.loadData(webViewData, "text/html; charset=UTF-8", "base64")
Localization.assureCorrectAppLanguage(context)
AlertDialog.Builder(context)
.setTitle(license.name)
.setView(webView)
.block()
.show()
}
}
}

View File

@@ -2,6 +2,7 @@ package org.schabi.newpipe.about
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import java.io.Serializable
@Parcelize
class SoftwareComponent
@@ -13,4 +14,4 @@ constructor(
val link: String,
val license: License,
val version: String? = null
) : Parcelable
) : Parcelable, Serializable

View File

@@ -93,18 +93,30 @@ abstract class FeedDAO {
uploadDateBefore: OffsetDateTime?
): Maybe<List<StreamWithState>>
/**
* Remove links to streams that are older than the given date
* **but keep at least one stream per uploader**.
*
* One stream per uploader is kept because it is needed as reference
* when fetching new streams to check if they are new or not.
* @param offsetDateTime the newest date to keep, older streams are removed
*/
@Query(
"""
DELETE FROM feed WHERE
feed.stream_id IN (
SELECT s.uid FROM streams s
INNER JOIN feed f
ON s.uid = f.stream_id
WHERE s.upload_date < :offsetDateTime
)
DELETE FROM feed
WHERE feed.stream_id IN (SELECT uid from (
SELECT s.uid,
(SELECT MAX(upload_date)
FROM streams s1
INNER JOIN feed f1
ON s1.uid = f1.stream_id
WHERE f1.subscription_id = f.subscription_id) max_upload_date
FROM streams s
INNER JOIN feed f
ON s.uid = f.stream_id
WHERE s.upload_date < :offsetDateTime
AND s.upload_date <> max_upload_date))
"""
)
abstract fun unlinkStreamsOlderThan(offsetDateTime: OffsetDateTime)

View File

@@ -3,7 +3,6 @@ package org.schabi.newpipe.database.feed.model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.ForeignKey.CASCADE
import androidx.room.Index
import org.schabi.newpipe.database.feed.model.FeedGroupSubscriptionEntity.Companion.FEED_GROUP_SUBSCRIPTION_TABLE
import org.schabi.newpipe.database.feed.model.FeedGroupSubscriptionEntity.Companion.GROUP_ID
@@ -19,14 +18,14 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity
entity = FeedGroupEntity::class,
parentColumns = [FeedGroupEntity.ID],
childColumns = [GROUP_ID],
onDelete = CASCADE, onUpdate = CASCADE, deferred = true
onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE, deferred = true
),
ForeignKey(
entity = SubscriptionEntity::class,
parentColumns = [SubscriptionEntity.SUBSCRIPTION_UID],
childColumns = [SUBSCRIPTION_ID],
onDelete = CASCADE, onUpdate = CASCADE, deferred = true
onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE, deferred = true
)
]
)

View File

@@ -7,6 +7,7 @@ import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity
import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.database.stream.model.StreamStateEntity
import org.schabi.newpipe.extractor.stream.StreamInfoItem
import org.schabi.newpipe.util.image.ImageStrategy
data class PlaylistStreamEntry(
@Embedded
@@ -28,7 +29,7 @@ data class PlaylistStreamEntry(
item.duration = streamEntity.duration
item.uploaderName = streamEntity.uploader
item.uploaderUrl = streamEntity.uploaderUrl
item.thumbnailUrl = streamEntity.thumbnailUrl
item.thumbnails = ImageStrategy.dbUrlToImageList(streamEntity.thumbnailUrl)
return item
}

View File

@@ -11,6 +11,7 @@ import androidx.room.PrimaryKey;
import org.schabi.newpipe.database.playlist.PlaylistLocalItem;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.image.ImageStrategy;
import static org.schabi.newpipe.database.LocalItem.LocalItemType.PLAYLIST_REMOTE_ITEM;
import static org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity.REMOTE_PLAYLIST_NAME;
@@ -69,8 +70,9 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem {
@Ignore
public PlaylistRemoteEntity(final PlaylistInfo info) {
this(info.getServiceId(), info.getName(), info.getUrl(),
info.getThumbnailUrl() == null
? info.getUploaderAvatarUrl() : info.getThumbnailUrl(),
// use uploader avatar when no thumbnail is available
ImageStrategy.imageListToDbUrl(info.getThumbnails().isEmpty()
? info.getUploaderAvatars() : info.getThumbnails()),
info.getUploaderName(), info.getStreamCount());
}
@@ -84,7 +86,10 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem {
&& getStreamCount() == info.getStreamCount()
&& TextUtils.equals(getName(), info.getName())
&& TextUtils.equals(getUrl(), info.getUrl())
&& TextUtils.equals(getThumbnailUrl(), info.getThumbnailUrl())
// we want to update the local playlist data even when either the remote thumbnail
// URL changes, or the preferred image quality setting is changed by the user
&& TextUtils.equals(getThumbnailUrl(),
ImageStrategy.imageListToDbUrl(info.getThumbnails()))
&& TextUtils.equals(getUploader(), info.getUploaderName());
}

View File

@@ -7,6 +7,7 @@ import org.schabi.newpipe.database.history.model.StreamHistoryEntity
import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_MILLIS
import org.schabi.newpipe.extractor.stream.StreamInfoItem
import org.schabi.newpipe.util.image.ImageStrategy
import java.time.OffsetDateTime
class StreamStatisticsEntry(
@@ -30,7 +31,7 @@ class StreamStatisticsEntry(
item.duration = streamEntity.duration
item.uploaderName = streamEntity.uploader
item.uploaderUrl = streamEntity.uploaderUrl
item.thumbnailUrl = streamEntity.thumbnailUrl
item.thumbnails = ImageStrategy.dbUrlToImageList(streamEntity.thumbnailUrl)
return item
}

View File

@@ -13,6 +13,7 @@ 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 org.schabi.newpipe.util.image.ImageStrategy
import java.io.Serializable
import java.time.OffsetDateTime
@@ -67,7 +68,8 @@ data class StreamEntity(
constructor(item: StreamInfoItem) : this(
serviceId = item.serviceId, url = item.url, title = item.name,
streamType = item.streamType, duration = item.duration, uploader = item.uploaderName,
uploaderUrl = item.uploaderUrl, thumbnailUrl = item.thumbnailUrl, viewCount = item.viewCount,
uploaderUrl = item.uploaderUrl,
thumbnailUrl = ImageStrategy.imageListToDbUrl(item.thumbnails), viewCount = item.viewCount,
textualUploadDate = item.textualUploadDate, uploadDate = item.uploadDate?.offsetDateTime(),
isUploadDateApproximation = item.uploadDate?.isApproximation
)
@@ -76,7 +78,8 @@ data class StreamEntity(
constructor(info: StreamInfo) : this(
serviceId = info.serviceId, url = info.url, title = info.name,
streamType = info.streamType, duration = info.duration, uploader = info.uploaderName,
uploaderUrl = info.uploaderUrl, thumbnailUrl = info.thumbnailUrl, viewCount = info.viewCount,
uploaderUrl = info.uploaderUrl,
thumbnailUrl = ImageStrategy.imageListToDbUrl(info.thumbnails), viewCount = info.viewCount,
textualUploadDate = info.textualUploadDate, uploadDate = info.uploadDate?.offsetDateTime(),
isUploadDateApproximation = info.uploadDate?.isApproximation
)
@@ -85,7 +88,8 @@ data class StreamEntity(
constructor(item: PlayQueueItem) : this(
serviceId = item.serviceId, url = item.url, title = item.title,
streamType = item.streamType, duration = item.duration, uploader = item.uploader,
uploaderUrl = item.uploaderUrl, thumbnailUrl = item.thumbnailUrl
uploaderUrl = item.uploaderUrl,
thumbnailUrl = ImageStrategy.imageListToDbUrl(item.thumbnails)
)
fun toStreamInfoItem(): StreamInfoItem {
@@ -93,7 +97,7 @@ data class StreamEntity(
item.duration = duration
item.uploaderName = uploader
item.uploaderUrl = uploaderUrl
item.thumbnailUrl = thumbnailUrl
item.thumbnails = ImageStrategy.dbUrlToImageList(thumbnailUrl)
if (viewCount != null) item.viewCount = viewCount as Long
item.textualUploadDate = textualUploadDate

View File

@@ -10,6 +10,7 @@ import androidx.room.PrimaryKey;
import org.schabi.newpipe.extractor.channel.ChannelInfo;
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.image.ImageStrategy;
import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_SERVICE_ID;
import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_TABLE;
@@ -57,8 +58,8 @@ public class SubscriptionEntity {
final SubscriptionEntity result = new SubscriptionEntity();
result.setServiceId(info.getServiceId());
result.setUrl(info.getUrl());
result.setData(info.getName(), info.getAvatarUrl(), info.getDescription(),
info.getSubscriberCount());
result.setData(info.getName(), ImageStrategy.imageListToDbUrl(info.getAvatars()),
info.getDescription(), info.getSubscriberCount());
return result;
}
@@ -138,7 +139,7 @@ public class SubscriptionEntity {
@Ignore
public ChannelInfoItem toChannelInfoItem() {
final ChannelInfoItem item = new ChannelInfoItem(getServiceId(), getUrl(), getName());
item.setThumbnailUrl(getAvatarUrl());
item.setThumbnails(ImageStrategy.dbUrlToImageList(getAvatarUrl()));
item.setSubscriberCount(getSubscriberCount());
item.setDescription(getDescription());
return item;

View File

@@ -67,7 +67,7 @@ import org.schabi.newpipe.util.PermissionHelper;
import org.schabi.newpipe.util.SecondaryStreamHelper;
import org.schabi.newpipe.util.SimpleOnSeekBarChangeListener;
import org.schabi.newpipe.util.StreamItemAdapter;
import org.schabi.newpipe.util.StreamItemAdapter.StreamSizeWrapper;
import org.schabi.newpipe.util.StreamItemAdapter.StreamInfoWrapper;
import org.schabi.newpipe.util.AudioTrackAdapter;
import org.schabi.newpipe.util.AudioTrackAdapter.AudioTracksWrapper;
import org.schabi.newpipe.util.ThemeHelper;
@@ -97,9 +97,9 @@ public class DownloadDialog extends DialogFragment
@State
StreamInfo currentInfo;
@State
StreamSizeWrapper<VideoStream> wrappedVideoStreams;
StreamInfoWrapper<VideoStream> wrappedVideoStreams;
@State
StreamSizeWrapper<SubtitlesStream> wrappedSubtitleStreams;
StreamInfoWrapper<SubtitlesStream> wrappedSubtitleStreams;
@State
AudioTracksWrapper wrappedAudioTracks;
@State
@@ -187,8 +187,8 @@ public class DownloadDialog extends DialogFragment
wrappedAudioTracks.size() > 1
);
this.wrappedVideoStreams = new StreamSizeWrapper<>(videoStreams, context);
this.wrappedSubtitleStreams = new StreamSizeWrapper<>(
this.wrappedVideoStreams = new StreamInfoWrapper<>(videoStreams, context);
this.wrappedSubtitleStreams = new StreamInfoWrapper<>(
getStreamsOfSpecifiedDelivery(info.getSubtitles(), PROGRESSIVE_HTTP), context);
this.selectedVideoIndex = ListHelper.getDefaultResolutionIndex(context, videoStreams);
@@ -258,17 +258,17 @@ public class DownloadDialog extends DialogFragment
* Update the displayed video streams based on the selected audio track.
*/
private void updateSecondaryStreams() {
final StreamSizeWrapper<AudioStream> audioStreams = getWrappedAudioStreams();
final StreamInfoWrapper<AudioStream> audioStreams = getWrappedAudioStreams();
final var secondaryStreams = new SparseArrayCompat<SecondaryStreamHelper<AudioStream>>(4);
final List<VideoStream> videoStreams = wrappedVideoStreams.getStreamsList();
wrappedVideoStreams.resetSizes();
wrappedVideoStreams.resetInfo();
for (int i = 0; i < videoStreams.size(); i++) {
if (!videoStreams.get(i).isVideoOnly()) {
continue;
}
final AudioStream audioStream = SecondaryStreamHelper
.getAudioStreamFor(audioStreams.getStreamsList(), videoStreams.get(i));
final AudioStream audioStream = SecondaryStreamHelper.getAudioStreamFor(
context, audioStreams.getStreamsList(), videoStreams.get(i));
if (audioStream != null) {
secondaryStreams.append(i, new SecondaryStreamHelper<>(audioStreams, audioStream));
@@ -313,6 +313,7 @@ public class DownloadDialog extends DialogFragment
selectedSubtitleIndex = getSubtitleIndexBy(subtitleStreamsAdapter.getAll());
dialogBinding.qualitySpinner.setOnItemSelectedListener(this);
dialogBinding.audioStreamSpinner.setOnItemSelectedListener(this);
dialogBinding.audioTrackSpinner.setOnItemSelectedListener(this);
dialogBinding.videoAudioGroup.setOnCheckedChangeListener(this);
@@ -395,7 +396,7 @@ public class DownloadDialog extends DialogFragment
private void fetchStreamsSize() {
disposables.clear();
disposables.add(StreamSizeWrapper.fetchSizeForWrapper(wrappedVideoStreams)
disposables.add(StreamInfoWrapper.fetchMoreInfoForWrapper(wrappedVideoStreams)
.subscribe(result -> {
if (dialogBinding.videoAudioGroup.getCheckedRadioButtonId()
== R.id.video_button) {
@@ -405,7 +406,7 @@ public class DownloadDialog extends DialogFragment
new ErrorInfo(throwable, UserAction.DOWNLOAD_OPEN_DIALOG,
"Downloading video stream size",
currentInfo.getServiceId()))));
disposables.add(StreamSizeWrapper.fetchSizeForWrapper(getWrappedAudioStreams())
disposables.add(StreamInfoWrapper.fetchMoreInfoForWrapper(getWrappedAudioStreams())
.subscribe(result -> {
if (dialogBinding.videoAudioGroup.getCheckedRadioButtonId()
== R.id.audio_button) {
@@ -415,7 +416,7 @@ public class DownloadDialog extends DialogFragment
new ErrorInfo(throwable, UserAction.DOWNLOAD_OPEN_DIALOG,
"Downloading audio stream size",
currentInfo.getServiceId()))));
disposables.add(StreamSizeWrapper.fetchSizeForWrapper(wrappedSubtitleStreams)
disposables.add(StreamInfoWrapper.fetchMoreInfoForWrapper(wrappedSubtitleStreams)
.subscribe(result -> {
if (dialogBinding.videoAudioGroup.getCheckedRadioButtonId()
== R.id.subtitle_button) {
@@ -723,9 +724,9 @@ public class DownloadDialog extends DialogFragment
dialogBinding.subtitleButton.setEnabled(enabled);
}
private StreamSizeWrapper<AudioStream> getWrappedAudioStreams() {
private StreamInfoWrapper<AudioStream> getWrappedAudioStreams() {
if (selectedAudioTrackIndex < 0 || selectedAudioTrackIndex > wrappedAudioTracks.size()) {
return StreamSizeWrapper.empty();
return StreamInfoWrapper.empty();
}
return wrappedAudioTracks.getTracksList().get(selectedAudioTrackIndex);
}
@@ -765,7 +766,7 @@ public class DownloadDialog extends DialogFragment
}
private void showFailedDialog(@StringRes final int msg) {
assureCorrectAppLanguage(getContext());
assureCorrectAppLanguage(requireContext());
new AlertDialog.Builder(context)
.setTitle(R.string.general_error)
.setMessage(msg)
@@ -798,7 +799,7 @@ public class DownloadDialog extends DialogFragment
filenameTmp += "opus";
} else if (format != null) {
mimeTmp = format.mimeType;
filenameTmp += format.suffix;
filenameTmp += format.getSuffix();
}
break;
case R.id.video_button:
@@ -807,7 +808,7 @@ public class DownloadDialog extends DialogFragment
format = videoStreamsAdapter.getItem(selectedVideoIndex).getFormat();
if (format != null) {
mimeTmp = format.mimeType;
filenameTmp += format.suffix;
filenameTmp += format.getSuffix();
}
break;
case R.id.subtitle_button:
@@ -819,9 +820,9 @@ public class DownloadDialog extends DialogFragment
}
if (format == MediaFormat.TTML) {
filenameTmp += MediaFormat.SRT.suffix;
filenameTmp += MediaFormat.SRT.getSuffix();
} else if (format != null) {
filenameTmp += format.suffix;
filenameTmp += format.getSuffix();
}
break;
default:

View File

@@ -0,0 +1,87 @@
package org.schabi.newpipe.download;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.DialogFragment;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.databinding.DownloadLoadingDialogBinding;
/**
* This class contains a dialog which shows a loading indicator and has a customizable title.
*/
public class LoadingDialog extends DialogFragment {
private static final String TAG = "LoadingDialog";
private static final boolean DEBUG = MainActivity.DEBUG;
private DownloadLoadingDialogBinding dialogLoadingBinding;
private final @StringRes int title;
/**
* Create a new LoadingDialog.
*
* <p>
* The dialog contains a loading indicator and has a customizable title.
* <br/>
* Use {@code show()} to display the dialog to the user.
* </p>
*
* @param title an informative title shown in the dialog's toolbar
*/
public LoadingDialog(final @StringRes int title) {
this.title = title;
}
@Override
public void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (DEBUG) {
Log.d(TAG, "onCreate() called with: "
+ "savedInstanceState = [" + savedInstanceState + "]");
}
this.setCancelable(false);
}
@Override
public View onCreateView(
@NonNull final LayoutInflater inflater,
final ViewGroup container,
final Bundle savedInstanceState) {
if (DEBUG) {
Log.d(TAG, "onCreateView() called with: "
+ "inflater = [" + inflater + "], container = [" + container + "], "
+ "savedInstanceState = [" + savedInstanceState + "]");
}
return inflater.inflate(R.layout.download_loading_dialog, container);
}
@Override
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
dialogLoadingBinding = DownloadLoadingDialogBinding.bind(view);
initToolbar(dialogLoadingBinding.toolbarLayout.toolbar);
}
private void initToolbar(final Toolbar toolbar) {
if (DEBUG) {
Log.d(TAG, "initToolbar() called with: toolbar = [" + toolbar + "]");
}
toolbar.setTitle(requireContext().getString(title));
toolbar.setNavigationOnClickListener(v -> dismiss());
}
@Override
public void onDestroyView() {
dialogLoadingBinding = null;
super.onDestroyView();
}
}

View File

@@ -11,7 +11,6 @@ import org.schabi.newpipe.extractor.exceptions.AccountTerminatedException
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException
import org.schabi.newpipe.extractor.exceptions.ExtractionException
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor.DeobfuscateException
import org.schabi.newpipe.ktx.isNetworkRelated
import org.schabi.newpipe.util.ServiceHelper
@@ -96,7 +95,6 @@ class ErrorInfo(
throwable is ContentNotAvailableException -> R.string.content_not_available
throwable != null && throwable.isNetworkRelated -> R.string.network_error
throwable is ContentNotSupportedException -> R.string.content_not_supported
throwable is DeobfuscateException -> R.string.youtube_signature_deobfuscation_error
throwable is ExtractionException -> R.string.parsing_error
throwable is ExoPlaybackException -> {
when (throwable.type) {

View File

@@ -1,12 +1,16 @@
package org.schabi.newpipe.fragments;
import static org.schabi.newpipe.ktx.ViewUtils.animate;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import org.schabi.newpipe.BaseFragment;
@@ -20,15 +24,15 @@ import java.util.concurrent.atomic.AtomicBoolean;
import icepick.State;
import static org.schabi.newpipe.ktx.ViewUtils.animate;
public abstract class BaseStateFragment<I> extends BaseFragment implements ViewContract<I> {
@State
protected AtomicBoolean wasLoading = new AtomicBoolean();
protected AtomicBoolean isLoading = new AtomicBoolean();
@Nullable
private View emptyStateView;
protected View emptyStateView;
@Nullable
protected TextView emptyStateMessageView;
@Nullable
private ProgressBar loadingProgressBar;
@@ -65,6 +69,7 @@ public abstract class BaseStateFragment<I> extends BaseFragment implements ViewC
protected void initViews(final View rootView, final Bundle savedInstanceState) {
super.initViews(rootView, savedInstanceState);
emptyStateView = rootView.findViewById(R.id.empty_state_view);
emptyStateMessageView = rootView.findViewById(R.id.empty_state_message);
loadingProgressBar = rootView.findViewById(R.id.loading_progress_bar);
errorPanelHelper = new ErrorPanelHelper(this, rootView, this::onRetryButtonClicked);
}
@@ -75,6 +80,8 @@ public abstract class BaseStateFragment<I> extends BaseFragment implements ViewC
if (errorPanelHelper != null) {
errorPanelHelper.dispose();
}
emptyStateView = null;
emptyStateMessageView = null;
}
protected void onRetryButtonClicked() {
@@ -189,6 +196,12 @@ public abstract class BaseStateFragment<I> extends BaseFragment implements ViewC
errorPanelHelper.showTextError(errorString);
}
protected void setEmptyStateMessage(@StringRes final int text) {
if (emptyStateMessageView != null) {
emptyStateMessageView.setText(text);
}
}
public final void hideErrorPanel() {
errorPanelHelper.hide();
lastPanelError = null;

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