1
mirror of https://github.com/TeamNewPipe/NewPipe synced 2025-09-22 10:00:55 +02:00

Compare commits

...

80 Commits

Author SHA1 Message Date
TobiGr
600e156c4c Release 0.21.1 (967) 2021-04-10 11:19:48 +02:00
Tobi
464d0e50b0 Merge pull request #5871 from Stypox/release_0.21.0
Release 0.21.0
2021-03-26 08:31:59 +01:00
Stypox
7411c54f9e Release 0.21.0 (966) 2021-03-25 23:02:14 +01:00
TobiGr
7c74deb700 Update translations
Translated using Weblate (German)
Currently translated at 100.0% (638 of 638 strings)

Translated using Weblate (French)

Currently translated at 100.0% (638 of 638 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (638 of 638 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (638 of 638 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (638 of 638 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (638 of 638 strings)

Translated using Weblate (Hebrew)

Currently translated at 100.0% (638 of 638 strings)

Translated using Weblate (Croatian)

Currently translated at 100.0% (638 of 638 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (638 of 638 strings)

Translated using Weblate (German)

Currently translated at 48.9% (23 of 47 strings)

Translation: NewPipe/Metadata
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/de/

Translated using Weblate (Hebrew)

Currently translated at 40.4% (19 of 47 strings)

Translation: NewPipe/Metadata
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/he/

Translated using Weblate (Arabic)

Currently translated at 68.0% (32 of 47 strings)

Translation: NewPipe/Metadata
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ar/

Translated using Weblate (Somali)

Currently translated at 100.0% (638 of 638 strings)
2021-03-25 22:15:44 +01:00
TobiGr
e63165e80f Update extractor version to 0.21.0 2021-03-25 22:13:55 +01:00
XiangRongLin
e2bc9dfacd Merge pull request #5906 from TeamNewPipe/sonar
Disable sonar job
2021-03-25 19:39:21 +01:00
Stypox
48789dbab7 Add changelog for 0.21.0 (966) 2021-03-25 10:41:15 +01:00
TobiGr
196f0f0475 Update translations
Translated using Weblate (French)
Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Indonesian)

Currently translated at 23.9% (11 of 46 strings)

Translation: NewPipe/Metadata
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/id/
2021-03-25 10:29:55 +01:00
Stypox
085b59f2e1 Merge pull request #5907 from TeamNewPipe/B0pol-patch-1
Update strings.xml
2021-03-25 08:54:09 +01:00
Stypox
2fdc2664ff Merge pull request #5904 from TeamNewPipe/weblate-update
Update weblate and use BCP47 language codes
2021-03-25 08:13:03 +01:00
bopol
a33a5c5527 Update strings.xml
fix typo
2021-03-24 19:44:25 +01:00
Tobi
a7c0f37904 Disable sonar job
For some reason, sonar started to analyse very old PRs. This comments out the sonar job until further investigation is done.
2021-03-24 19:10:00 +01:00
TobiGr
4889ab3462 Use BCP47 language codes for fastlane
Closes #5750
2021-03-24 18:16:40 +01:00
TobiGr
3923deeaad Update translations
Translated using Weblate (German)
Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (German)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (German)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (German)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (German)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (German)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (German)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (German)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (French)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (French)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Slovenian)

Currently translated at 77.2% (489 of 633 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Polish)

Currently translated at 99.8% (632 of 633 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Sardinian)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Portuguese (Portugal))

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Santali)

Currently translated at 12.9% (82 of 633 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 13.5% (86 of 633 strings)

Translated using Weblate (Somali)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (German)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (French)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Japanese)

Currently translated at 99.5% (630 of 633 strings)

Translated using Weblate (Korean)

Currently translated at 82.9% (525 of 633 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Esperanto)

Currently translated at 87.0% (551 of 633 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Catalan)

Currently translated at 97.9% (620 of 633 strings)

Translated using Weblate (Dutch (Belgium))

Currently translated at 97.1% (615 of 633 strings)

Translated using Weblate (Malayalam)

Currently translated at 89.4% (566 of 633 strings)

Translated using Weblate (German)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (French)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Basque)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (633 of 633 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (633 of 633 strings)
2021-03-24 18:09:52 +01:00
Tobi
80d6fff0ca Merge pull request #5649 from FireMasterK/ff-ua
Change UA to privacy.resistFingerprinting.
2021-03-24 17:59:17 +01:00
Tobi
fe43b4da39 Merge pull request #5896 from Stypox/fix-error-panel
Fix error panel created in onViewCreated() but disposed in onDestroy()
2021-03-24 11:32:07 +01:00
Tobi
67afd05e22 Merge pull request #5899 from Stypox/fix-settings-theme
Fix settings switches are not red anymore
2021-03-24 11:24:27 +01:00
Stypox
0fcaf20221 Fix settings switches are not red anymore
Reverts part of 731c65cd59
2021-03-24 10:16:24 +01:00
Stypox
0277b94b37 Fix error panel created in onViewCreated() but disposed in onDestroy() 2021-03-24 09:27:17 +01:00
Stypox
c7efa8c4f1 Merge pull request #5519 from WoodyMats/release_0.20.9
Add toast to inform the user that download started.
2021-03-20 22:19:13 +01:00
Matskidis Giannis
bf6645e829 Show Toast when download starts
Add toast to inform the user that download started and add the right string in values.
2021-03-20 22:18:01 +01:00
XiangRongLin
ea1b42510c Merge pull request #5844 from TeamNewPipe/sonar_workflow
Sonar workflow
2021-03-20 18:22:28 +01:00
XiangRongLin
72818ffa42 Add sonar plugin and github actions file for sonar analysis
Copied from sonarcloud.io setup page with minor adjustments. Adjusted branch to 'dev' and updated versions
2021-03-20 13:58:17 +01:00
XiangRongLin
985308bf0c Set the whole configDir instead of only configFile for checkstyle 2021-03-20 13:58:17 +01:00
Stypox
86381696f4 Merge pull request #5457 from Redirion/exo123
Update to ExoPlayer 2.12.3
2021-03-18 18:59:56 +01:00
Robin
08b960cc6e Merge pull request #3632 from B0pol/device_theme
Add settings to match device's theme (dark & black)
2021-03-18 15:11:40 +01:00
Stypox
731c65cd59 Refactor ThemeHelper 2021-03-18 12:39:29 +01:00
bopol
a85e8a29ff Use a list for night themes
Also remove unused strings
2021-03-18 12:12:04 +01:00
bopol
22b2f52f8c Use a switch preference to follow device theme 2021-03-18 11:23:55 +01:00
bopol
a713ce2126 Add settings for device theme (dark & black)
fix bugs related to isLightThemeSelected not handling device themes
such as license having dark background when it should be white
2021-03-18 11:17:06 +01:00
Stypox
4fac3cf304 Merge pull request #5230 from Isira-Seneviratne/Update_prettytime
Update prettytime.
2021-03-18 08:59:40 +01:00
Isira Seneviratne
74e20a8c52 Use PrettyTime's new formatUnrounded(OffsetDateTime) method.
Also change the types of the relevant variables from Calendar to OffsetDateTime.
2021-03-18 06:38:12 +05:30
Isira Seneviratne
8cf4ba25f5 Update prettytime to 5.0.0.Final. 2021-03-18 06:38:12 +05:30
Stypox
feb65cf8f3 Merge pull request #5792 from TeamNewPipe/resize_mode
Fix last resize mode not being restored correctly
2021-03-17 09:07:44 +01:00
Stypox
93592d23f4 Merge pull request #5820 from TeamNewPipe/mini_player_title
Fix empty stream title in minimized player
2021-03-17 08:56:50 +01:00
Jeremiah Dicharry
338a4837bc Add Spanish README.md (#5829) 2021-03-16 23:38:10 +01:00
mhmdanas
8e19fe535c Re-add badgs to localized README's 2021-03-16 23:35:35 +01:00
TobiGr
2aeccc0c5c Translated using Weblate (Bengali (Bangladesh))
Currently translated at 62.8% (396 of 630 strings)

Translated using Weblate (Bengali)

Currently translated at 86.5% (545 of 630 strings)

Translated using Weblate (Bengali)

Currently translated at 19.5% (9 of 46 strings)

Translation: NewPipe/Metadata
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/bn/
2021-03-16 09:23:48 +01:00
TobiGr
8db1234a59 Update translations
Translated using Weblate (Chinese (Simplified))
Currently translated at 84.7% (39 of 46 strings)

Translation: NewPipe/Metadata
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 84.7% (39 of 46 strings)

Translation: NewPipe/Metadata
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/zh_Hans/

Translated using Weblate (Indonesian)

Currently translated at 99.0% (624 of 630 strings)

Translated using Weblate (Odia)

Currently translated at 0.0% (0 of 46 strings)

Translation: NewPipe/Metadata
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/or/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Sardinian)

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (French)

Currently translated at 99.6% (628 of 630 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Polish)

Currently translated at 99.6% (628 of 630 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Hebrew)

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Estonian)

Currently translated at 72.6% (458 of 630 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Danish)

Currently translated at 63.8% (402 of 630 strings)

Translated using Weblate (Portuguese (Portugal))

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 86.9% (40 of 46 strings)

Translation: NewPipe/Metadata
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/zh_Hans/

Translated using Weblate (Polish)

Currently translated at 99.6% (628 of 630 strings)

Translated using Weblate (Polish)

Currently translated at 99.6% (628 of 630 strings)

Translated using Weblate (German)

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (630 of 630 strings)

Translated using Weblate (Estonian)

Currently translated at 78.8% (497 of 630 strings)

Translated using Weblate (Malay)

Currently translated at 65.7% (414 of 630 strings)

Translated using Weblate (Indonesian)

Currently translated at 21.7% (10 of 46 strings)

Translation: NewPipe/Metadata
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/id/

Translated using Weblate (Portuguese (Portugal))

Currently translated at 56.5% (26 of 46 strings)

Translation: NewPipe/Metadata
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt_PT/
2021-03-16 09:23:48 +01:00
Tobi
80fb351ad3 Merge pull request #5830 from mhmdanas/remove-outdated-fdroid-version-note
Re-add F-Droid badge and remove outdated note
2021-03-15 08:43:51 +01:00
mhmdanas
523f85d4d1 Uncomment F-Droid badge and remove outdated note 2021-03-15 08:21:55 +03:00
Tobi
bfff500915 Merge pull request #5818 from TeamNewPipe/thumbnail_size
[background player] Fix very small thumbnails
2021-03-14 21:12:52 +01:00
Tobi
3e83bb0d95 Merge pull request #3741 from fynngodau/bandcamp
Bandcamp support
2021-03-14 20:00:40 +01:00
TobiGr
bdaee25e61 Use latest extractor version 2021-03-14 17:52:15 +01:00
TobiGr
71d3227791 Fix bottom controls being out of the screen
This was caused by too large end screen thumbnails enlarging the whole palyer. Fixed by scaling the thumbnail.

Ensure that the player does not use the whole screen height in detail fragment to keep the additional content like title, comments, etc. available.
2021-03-14 17:52:15 +01:00
TobiGr
a28aa6a8c4 Add Bandcamp to supported services section in README 2021-03-14 17:52:15 +01:00
TobiGr
292e103073 Ignore ContentNotSupportedException caused by Bandcamp fan pages 2021-03-14 17:52:15 +01:00
Fynn Godau
39a3f03e79 Bandcamp support 2021-03-14 17:52:15 +01:00
Tobi
404a6c12a6 Merge pull request #5148 from Stypox/error-panel
Show improved error panel instead of annoying snackbar or crashing
2021-03-14 17:41:27 +01:00
Tobi
8271409afe Merge pull request #5562 from mbarashkov/hardware_keyboard_space_shortcut_v2
Implement "pause/play" toggle on hardware keyboard space button.
2021-03-14 13:08:44 +01:00
TobiGr
985f659026 Fix empty stream title in minimized player 2021-03-13 20:12:57 +01:00
TobiGr
7c36cbffd0 [background player] Fix very small thumbnails 2021-03-13 18:17:30 +01:00
Stypox
285ea4e3fd Better handle url not supported in RouterActivity
Make sure the url not supported dialog is only shown when the url is really not supported, not on any ExtractionException
2021-03-12 23:21:54 +01:00
Stypox
8ce18647f1 Improve email subject for error reporting 2021-03-12 23:21:54 +01:00
Stypox
aee0478235 FeedFragment: fix view binding and show loading indicator correctly 2021-03-12 23:21:54 +01:00
Stypox
c3cf1d81c2 Fix error panel and search fragment state saving 2021-03-12 23:21:54 +01:00
Stypox
c2b6cec37d Hide meta info panel in search when starting a new search 2021-03-12 23:21:54 +01:00
Stypox
b265cabc22 Fix views not scrollable when showing error panel 2021-03-12 23:21:54 +01:00
Stypox
463dd8ea74 Completely remove return activity, now outdated 2021-03-12 23:21:54 +01:00
Stypox
0263125e11 Fix tests 2021-03-12 23:21:54 +01:00
Stypox
1fc8e4c148 Optimize imports and solve checkstyle issues 2021-03-12 23:21:53 +01:00
Stypox
c43bca6007 Add report/solve-recaptcha button in error panel
It will be shown even when nothing could be loaded not due to a network error, and the user can choose to ignore or report it.

Also improve error reporting arguments
Also completely refactor error activity
Also improve some code here and there
2021-03-12 23:21:49 +01:00
Tobi
4c31636d19 Merge pull request #5795 from TeamNewPipe/ci-only-on-master
Fix: CI only on dev
2021-03-09 11:50:47 +01:00
Poolitzer
3a61ab59f2 adding master to push trigger
Co-authored-by: Tobi <TobiGr@users.noreply.github.com>
2021-03-09 11:21:40 +01:00
Poolitzer
1db3c57ef0 change master to dev 2021-03-08 13:19:18 +01:00
Poolitzer
eeaf3496d5 Fix: CI only on master 2021-03-08 13:15:22 +01:00
Tobi
70f421b787 Add links to Matrix and IRC chat when opening new issues (#5764) 2021-03-08 09:43:05 +00:00
TobiGr
86fa629591 Fix last resize mode not being restored correctly
I think the settings key "last_resize_mode" is ambiguous. While it is used to get the recently used resize mode, someone thought while working on the resize mode switcher, that the old (to be replaced) resize mode should be stored. 
Fixes #5613
2021-03-08 09:46:33 +01:00
Stypox
553b80164b Move all error-related classes into error package 2021-03-07 17:49:28 +01:00
TobiGr
8518933ca8 Update translations
Translated using Weblate (Russian)
Currently translated at 100.0% (624 of 624 strings)

Translated using Weblate (French)

Currently translated at 100.0% (624 of 624 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (624 of 624 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (624 of 624 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (624 of 624 strings)
2021-03-07 16:53:38 +01:00
Tobi
ea53b7d4ad Merge pull request #5385 from TiA4f8R/soundcloud-error-improvements
Better error messages for SoundCloud and YouTube unavailable contents
2021-03-07 16:35:56 +01:00
TiA4f8R
37a96d063f Add different error messages for SoundCloud and YouTube unavailable contents
Add new error strings for the six new exceptions created in the extractor and catch these exceptions. Extractor is, of course, updated with this PR.
2021-03-07 15:33:25 +01:00
Tobi
b360920472 Merge pull request #5772 from iamthesenate1/dev
Add spcace after the comma, before Romanian in Readme.md.
2021-03-06 12:13:38 +01:00
iamthesenate1
9e1744f904 Add spcace after the comma, before Rommanian. 2021-03-06 12:20:01 +02:00
TobiGr
85a468bda9 Update translations: app
Translated using Weblate (French)
Currently translated at 100.0% (624 of 624 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (624 of 624 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (624 of 624 strings)

Translated using Weblate (Slovenian)

Currently translated at 75.1% (469 of 624 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (624 of 624 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (624 of 624 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (624 of 624 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (624 of 624 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (624 of 624 strings)

Translated using Weblate (Hebrew)

Currently translated at 100.0% (624 of 624 strings)

Translated using Weblate (Albanian)

Currently translated at 98.2% (613 of 624 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 96.4% (602 of 624 strings)

Translated using Weblate (Portuguese (Portugal))

Currently translated at 100.0% (624 of 624 strings)

Translated using Weblate (Kurdish (Northern))

Currently translated at 100.0% (624 of 624 strings)
2021-03-05 22:45:00 +01:00
FireMasterK
b236bb407b Change UA to privacy.resistFingerprinting. 2021-02-20 16:49:37 +05:30
Stypox
8978187c64 Improve code style and fix some warnings
Removed a textTrack null check on a now- NonNull method
Added a error type switch case (TIMEOUT)
2021-02-16 16:54:44 +01:00
Robin
eba0b07782 Update to ExoPlayer 2.12.3 2021-02-16 16:42:51 +01:00
Mikhail Barashkov
80161c36c6 Apply the space button shortcut to large screens as well 2021-02-12 12:17:46 +03:00
Mikhail Barashkov
aea912f499 Implement "pause/play" toggle on hardware keyboard space button. 2021-02-12 11:58:15 +03:00
318 changed files with 2769 additions and 1881 deletions

View File

@@ -1 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: 💬 IRC
url: https://webchat.freenode.net/#newpipe
about: Chat with us via IRC for quick Q/A
- name: 💬 Matrix
url: https://matrix.to/#/#freenode_#newpipe:matrix.org
about: Chat with us via Matrix for quick Q/A

View File

@@ -1,6 +1,13 @@
name: CI
on: [push, pull_request]
on:
pull_request:
branches:
- dev
push:
branches:
- dev
- master
jobs:
build-and-test:
@@ -33,3 +40,34 @@ jobs:
with:
name: app
path: app/build/outputs/apk/debug/*.apk
# sonar:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v2
# with:
# fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
# - name: Set up JDK 11
# uses: actions/setup-java@v1.4.3
# with:
# java-version: 11 # Sonar requires JDK 11
# - name: Cache SonarCloud packages
# uses: actions/cache@v2
# with:
# path: ~/.sonar/cache
# key: ${{ runner.os }}-sonar
# restore-keys: ${{ runner.os }}-sonar
# - name: Cache Gradle packages
# uses: actions/cache@v2
# with:
# path: ~/.gradle/caches
# key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
# restore-keys: ${{ runner.os }}-gradle
# - name: Build and analyze
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
# run: ./gradlew build sonarqube --info

140
README.es.md Normal file
View File

@@ -0,0 +1,140 @@
<p align="center"><a href="https://newpipe.net"><img src="assets/new_pipe_icon_5.png" width="150"></a></p>
<h2 align="center"><b>NewPipe</b></h2>
<h4 align="center">Una interfaz de streaming lijera y libre para Android.</h4>
<p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://f-droid.org/wiki/images/0/06/F-Droid-button_get-it-on.png"></a></p>
<p align="center">
<a href="https://github.com/TeamNewPipe/NewPipe/releases" alt="GitHub release"><img src="https://img.shields.io/badge/Lanzamiento-v0.20.11-blue.svg" ></a>
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="License: GPLv3"><img src="https://img.shields.io/badge/Licencia-GPL%20v3-blue.svg"></a>
<a href="https://github.com/TeamNewPipe/NewPipe/actions" alt="Build Status"><img src="https://github.com/TeamNewPipe/NewPipe/workflows/CI/badge.svg?branch=dev&event=push"></a>
<a href="https://hosted.weblate.org/engage/newpipe/es/" alt="Estado de la traducción"><img src="https://hosted.weblate.org/widgets/newpipe/es/svg-badge.svg"></a>
<a href="http://webchat.freenode.net/?channels=%23newpipe" alt="IRC channel: #newpipe"><img src="https://img.shields.io/badge/Canal%20de%20IRC%20-%23newpipe-brightgreen.svg"></a>
<a href="https://www.bountysource.com/teams/newpipe" alt="Bountysource bounties"><img src="https://img.shields.io/bountysource/team/newpipe/activity.svg?colorB=cd201f"></a>
</p>
<hr>
<p align="center"><a href="#capturas-de-pantalla">Capturas de pantalla</a> &bull; <a href="#descripción">Descripción</a> &bull; <a href="#características">Características</a> &bull; <a href="#installación-y-actualizaciones">Installación y actualizaciones</a> &bull; <a href="#contribución">Contribución</a> &bull; <a href="#donar">Donar</a> &bull; <a href="#licencias">Licencias</a></p>
<p align="center"><a href="https://newpipe.net">Sitio web</a> &bull; <a href="https://newpipe.net/blog/">Blog</a> &bull; <a href="https://newpipe.net/FAQ/">Preguntas Frecuentes</a> &bull; <a href="https://newpipe.net/press/">Prensa</a></p>
<hr>
*Lea esto en otros idiomas: [English](README.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt_BR.md), [日本語](README.ja.md), [Română](README.ro.md) .*
<b>AVISO: ESTA ES UNA VERSIÓN BETA, POR LO TANTO, PUEDE ENCONTRAR BUGS (ERRORES). SI ENCUENTRA UNO, ABRA UN ISSUE A TRAVÉS DE NUESTRO REPOSITORIO GITHUB.</b>
<b>COLOCAR NEWPIPE O CUALQUIER FORK (BIFURCACIÓN) REALIZADO DE ELLO EN GOOGLE PLAY STORE VIOLA SUS TÉRMINOS Y CONDICIONES.</b>
## Capturas de pantalla
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_01.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_01.png)
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_02.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_02.png)
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_03.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_03.png)
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_04.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_04.png)
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_05.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_05.png)
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_06.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_06.png)
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_07.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_07.png)
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_08.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_08.png)
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_09.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_09.png)
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/shot_10.png" width=160>](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_10.png)
[<img src="fastlane/metadata/android/en-US/images/tenInchScreenshots/shot_11.png" width=405>](fastlane/metadata/android/en-US/images/tenInchScreenshots/shot_11.png)
[<img src="fastlane/metadata/android/en-US/images/tenInchScreenshots/shot_12.png" width=405>](fastlane/metadata/android/en-US/images/tenInchScreenshots/shot_12.png)
## Descripción
NewPipe no usa ninguna librería de framework de Google, ni la API de YouTube. Los sitios web solamente se analizan para extraer la información requerida, asi que esta app se puede usar sin los servicios de Google instalados. Además, no se necesita una cuenta de YouTube para usar NewPipe, lo cual es un software libre de copyleft.
### Características
* Buscar videos
* Mostrar información general sobre videos
* Mirar videos de YouTube
* Escuchar audio de YouTube
* Modo popup (reproductor flotante)
* Elegir reproductor para mirar el video
* Descargar videos
* Descargar solamente audio
* Abrir video en Kodi
* Mostrar videos próximos/relacionados
* Buscar a través de YouTube en un idioma específico
* Mirar/Bloquear materiales restringidas por edad.
* Mostrar información general sobre canales
* Buscar canales
* Mirar videos de un canal
* Apoyo Orbot/Tor (todavía no directamente)
* Apoyo 1080p/2K/4K
* Ver historias
* Subscribirse a canales
* Buscar historias
* Buscar/mirar listas de reproducción
* Mirar listas de reproducción en fila
* Poner videos en fila
* Listas locales de reproducción
* Subtítulos
* Apoyo de medios en directo
* Mostrar comentarios
### Servicios apoyados
NewPipe apoya varios servicios. Nuestras [documentaciones](https://teamnewpipe.github.io/documentation/) proveen más información en como se puede agregar un servicio nuevo a la app y el extractor. Por favor contáctenos si pretende agregar uno nuevo. Actualmente los servicios apoyados son:
* YouTube
* SoundCloud \[beta\]
* media.ccc.de \[beta\]
* PeerTube instances \[beta\]
* Bandcamp \[beta\]
<!-- Brecha escondida para mantener compatibles los enlaces viejos. -->
<span id="actualizaciones"></span>
## Installación y actualizaciones
Se puede instalar NewPipe usando uno de los métodos siguientes:
1. Agregar nuestro repositorio personalizado a F-Droid e instalarlo desde allí. Las instrucciones están aquí: https://newpipe.schabi.org/FAQ/tutorials/install-add-fdroid-repo/
2. Descargar el archivo APK del enlace [Github Releases](https://github.com/TeamNewPipe/NewPipe/releases) e instalarlo.
3. Actualizar a través de F-Droid. Este es el método más lento para obtener la actualización, como F-Droid debe reconocer cambios, construir el APK aparte, firmarlo con una clave, y finalmente empujar la actualización a los usuarios.
4. Construir un APK de depuración por si mismo. Este es el modo más rápido para realizar nuevas características en su dispositivo, pero es mucho más complicado, asi que recomendamos uno de los otros métodos.
Recomendamos el método 1 para la mayoría de usuarios. Los APKs instalados usando método 1 o 2 son compatibles el uno con el otro, pero no con las instalaciones usando método 3. Esta es debida a la misma clave digital (la nuestra), siendo utilizado en los métodos 1 y 2, pero una clave digital diferente (la de F-Droid) siendo utilizado en el método 3. Construir un APK de depuración usando método 4 excluye una clave enteramente. Firmando con claves digitales ayuda a asegurar de que un
usuario no esté engañado para instalar una actualización maliciosa a una app.
Mientras tanto, si quiere cambiar los fuentes por alguna razón (por ejemplo, la funcionalidad del nucleo de NewPipe se rompe y F-Droid aun no tiene la actualización), recomendamos el siguiente procedimiento:
1. Repaldear sus datos a través de Ajustes > Contenido > Exporta base de datos para guardar su historia, subscripciones, y listas de reproducción
2. Desinstalar NewPipe
3. Descargar el APK del nuevo fuente e instalarlo.
4. Importar los datos del paso 1 a través de Ajustes > Contenido > Importa base de datos.
## Contribución
Si tiene ideas, traducciónes, cambios de diseño, limpieza de código, o cambios grandes de código, su ayuda es siempre bienvenida.
Cuanto más realizamos, mejor se pone la aplicación!
Si quiere involucrarse, fíjese en nuestras [notas de contribución](.github/CONTRIBUTING.md).
<a href="https://hosted.weblate.org/engage/newpipe/es/">
<img src="https://hosted.weblate.org/widgets/newpipe/es/287x66-grey.png" alt="Estado de la traducción" />
</a>
## Donar
Si le gusta el NewPipe estaremos felices con una donación. O puede enviar bitcoin o donar a través de Bountysource o Liberapay. Para obtener más información sobre como donar a NewPipe, por favor visita nuestro [sitio web](https://newpipe.net/donate).
<table>
<tr>
<td><img src="https://bitcoin.org/img/icons/logotop.svg" alt="Bitcoin"></td>
<td><img src="assets/bitcoin_qr_code.png" alt="Bitcoin QR code" width="100px"></td>
<td><samp>16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh</samp></td>
</tr>
<tr>
<td><a href="https://liberapay.com/TeamNewPipe/"><img src="https://upload.wikimedia.org/wikipedia/commons/2/27/Liberapay_logo_v2_white-on-yellow.svg" alt="Liberapay" width="80px" ></a></td>
<td><a href="https://liberapay.com/TeamNewPipe/"><img src="assets/liberapay_qr_code.png" alt="Visit NewPipe at liberapay.com" width="100px"></a></td>
<td><a href="https://liberapay.com/TeamNewPipe/donate"><img src="assets/liberapay_donate_button.svg" alt="Donate via Liberapay" height="35px"></a></td>
</tr>
<tr>
<td><a href="https://www.bountysource.com/teams/newpipe"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/22/Bountysource.png/320px-Bountysource.png" alt="Bountysource" width="190px"></a></td>
<td><a href="https://www.bountysource.com/teams/newpipe"><img src="assets/bountysource_qr_code.png" alt="Visit NewPipe at bountysource.com" width="100px"></a></td>
<td><a href="https://www.bountysource.com/teams/newpipe/issues"><img src="https://img.shields.io/bountysource/team/newpipe/activity.svg?colorB=cd201f" height="30px" alt="Check out how many bounties you can earn."></a></td>
</tr>
</table>
## Política de privacidad
El proyecto NewPipe tiene como objetivo proveer una experience privada y anónima para usar servicios de medios web.
Por lo tanto, la app no colecciona ningunos datos sin su consentimiento. La politica de privacidad de NewPipe explica en detalle los datos enviados y almacenados cuando envia un informe de error, o comentario en nuestro blog. Puede encontrar el documento [aqui](https://newpipe.net/legal/privacy/).
## Licencia
[![GNU GPLv3 Image](https://www.gnu.org/graphics/gplv3-127x51.png)](http://www.gnu.org/licenses/gpl-3.0.en.html)
NewPipe es Software Libre: Puede usar, estudiar, compartir, y mejorarlo a su voluntad. Especificamente puede redistribuir y/o modificarlo bajo los términos de la [GNU General Public License](https://www.gnu.org/licenses/gpl.html) como publicado por la Free Software Foundation, o versión 3 de la licencia, o (en su opción) cualquier versión posterior.

View File

@@ -2,8 +2,7 @@
<h2 align="center"><b>NewPipe</b></h2>
<h4 align="center">自由で軽量な Android 向けストリーミングフロントエンド</h4>
<!-- F-Droid is extremely out of date, so we hide this for now. -->
<!-- <p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://fdroid.gitlab.io/artwork/badge/get-it-on-ja.svg"></a></p> -->
<p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://fdroid.gitlab.io/artwork/badge/get-it-on-ja.svg"></a></p>
<p align="center">
<a href="https://github.com/TeamNewPipe/NewPipe/releases" alt="GitHub リリース"><img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe.svg"></a>
@@ -18,7 +17,7 @@
<p align="center"><a href="https://newpipe.net">ウェブサイト</a> &bull; <a href="https://newpipe.net/blog/">ブログ</a> &bull; <a href="https://newpipe.net/FAQ/">FAQ</a> &bull; <a href="https://newpipe.net/press/">ニュース</a></p>
<hr>
*他の言語で読む: [English](README.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt.br.md), [日本語](README.ja.md), [Română](README.ro.md) 。*
*他の言語で読む: [English](README.md), [Español](README.es.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt.br.md), [日本語](README.ja.md), [Română](README.ro.md) 。*
<b>注意: これはベータ版のため、バグが発生する可能性があります。もしバグが発生した場合、GitHub のリポジトリで Issue を開いてください。</b>
@@ -84,6 +83,7 @@ NewPipe は複数のサービスに対応しています。[ドキュメント](
* SoundCloud \[ベータ\]
* media.ccc.de \[ベータ\]
* PeerTube インスタンス \[ベータ\]
* Bandcamp \[ベータ\]
<!-- Hidden span to keep old links compatible. -->
<span id="updates"></span>

View File

@@ -1,7 +1,8 @@
<p align="center"><a href="https://newpipe.net"><img src="assets/new_pipe_icon_5.png" width="150"></a></p>
<h2 align="center"><b>NewPipe</b></h2>
<h4 align="center">A libre lightweight streaming frontend for Android.</h4>
<p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://f-droid.org/wiki/images/0/06/F-Droid-button_get-it-on.png"></a></p>
<p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://fdroid.gitlab.io/artwork/badge/get-it-on-ko.svg"></a></p>
<p align="center">
<a href="https://github.com/TeamNewPipe/NewPipe/releases" alt="GitHub release"><img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe.svg" ></a>
@@ -16,7 +17,7 @@
<p align="center"><a href="https://newpipe.net">Website</a> &bull; <a href="https://newpipe.net/blog/">Blog</a> &bull; <a href="https://newpipe.net/FAQ/">FAQ</a> &bull; <a href="https://newpipe.net/press/">Press</a></p>
<hr>
*Read this in other languages: [English](README.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt_BR.md), [日本語](README.ja.md), [Română](README.ro.md).*
*Read this in other languages: [English](README.md), [Español](README.es.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt_BR.md), [日本語](README.ja.md), [Română](README.ro.md).*
<b>경고: 이 버전은 베타 버전이므로, 버그가 발생할 수도 있습니다. 만약 버그가 발생하였다면, 우리의 GITHUB 저장소에서 ISSUE를 열람하여 주십시오.</b>
@@ -79,6 +80,7 @@ NewPipe는 여러가지 서비스를 지원합니다. 우리의 [문서](https:/
* SoundCloud \[beta\]
* media.ccc.de \[beta\]
* PeerTube instances \[beta\]
* Bandcamp \[beta\]
## Updates
NewPipe 코드의 변경이 있을 때(기능 추가 또는 버그 수정으로 인해), 결국 릴리즈가 발생할 것입니다. 이것들의 형식은 x.xx.x 입니다.

View File

@@ -2,8 +2,7 @@
<h2 align="center"><b>NewPipe</b></h2>
<h4 align="center">A libre lightweight streaming frontend for Android.</h4>
<!-- F-Droid is extremely out of date, so we hide this for now. -->
<!-- <p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://f-droid.org/wiki/images/0/06/F-Droid-button_get-it-on.png"></a></p> -->
<p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://f-droid.org/wiki/images/0/06/F-Droid-button_get-it-on.png"></a></p>
<p align="center">
<a href="https://github.com/TeamNewPipe/NewPipe/releases" alt="GitHub release"><img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe.svg" ></a>
@@ -18,7 +17,7 @@
<p align="center"><a href="https://newpipe.net">Website</a> &bull; <a href="https://newpipe.net/blog/">Blog</a> &bull; <a href="https://newpipe.net/FAQ/">FAQ</a> &bull; <a href="https://newpipe.net/press/">Press</a></p>
<hr>
*Read this in other languages: [English](README.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt_BR.md), [日本語](README.ja.md),[Română](README.ro.md) .*
*Read this in other languages: [English](README.md), [Español](README.es.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt_BR.md), [日本語](README.ja.md), [Română](README.ro.md) .*
<b>WARNING: THIS IS A BETA VERSION, THEREFORE YOU MAY ENCOUNTER BUGS. IF YOU DO, OPEN AN ISSUE VIA OUR GITHUB REPOSITORY.</b>
@@ -81,6 +80,7 @@ NewPipe supports multiple services. Our [docs](https://teamnewpipe.github.io/doc
* SoundCloud \[beta\]
* media.ccc.de \[beta\]
* PeerTube instances \[beta\]
* Bandcamp \[beta\]
<!-- Hidden span to keep old links compatible. -->
<span id="updates"></span>
@@ -89,7 +89,7 @@ NewPipe supports multiple services. Our [docs](https://teamnewpipe.github.io/doc
You can install NewPipe using one of the following methods:
1. Add our custom repo to F-Droid and install it from there. The instructions are here: https://newpipe.schabi.org/FAQ/tutorials/install-add-fdroid-repo/
2. Download the APK from [Github Releases](https://github.com/TeamNewPipe/NewPipe/releases) and install it.
3. Update via F-Droid. This is the slowest method of getting updates, as F-Droid must recognize changes, build the APK itself, sign it, then push the update to users. (**IMPORTANT**: as of the time of writing, an issue is preventing releases later than 0.20.1 from being published. Thus, till this issue is solved, if you want to use F-Droid, we recommend method 1.)
3. Update via F-Droid. This is the slowest method of getting updates, as F-Droid must recognize changes, build the APK itself, sign it, then push the update to users.
4. Build a debug APK yourself. This is the fastest way to get new features on your device, but is much more complicated, so we recommend using one of the other methods.
We recommend method 1 for most users. APKs installed using method 1 or 2 are compatible with each other, but not with those installed using method 3. This is due to the same signing key (ours) being used for 1 and 2, but a different signing key (F-Droid's) being used for 3. Building a debug APK using method 4 excludes a key entirely. Signing keys help ensure that a user isn't tricked into installing a malicious update to an app.

View File

@@ -1,7 +1,9 @@
<p align="center"><a href="https://newpipe.net"><img src="assets/new_pipe_icon_5.png" width="150"></a></p>
<h2 align="center"><b>NewPipe</b></h2>
<h4 align="center">Uma interface de streaming leve e gratuita para Android.</h4>
<p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://f-droid.org/wiki/images/0/06/F-Droid-button_get-it-on.png"></a></p>
<p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://fdroid.gitlab.io/artwork/badge/get-it-on-pt-br.svg"></a></p>
<p align="center">
<a href="https://github.com/TeamNewPipe/NewPipe/releases" alt="GitHub release"><img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe.svg" ></a>
@@ -16,7 +18,7 @@
<p align="center"><a href="https://newpipe.net">Site</a> &bull; <a href="https://newpipe.net/blog/">Blog</a> &bull; <a href="https://newpipe.net/FAQ/">FAQ</a> &bull; <a href="https://newpipe.net/press/">Press</a></p>
<hr>
*Read this in other languages: [English](README.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt_BR.md), [日本語](README.ja.md), [Română](README.ro.md).*
*Read this in other languages: [English](README.md), [Español](README.es.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt_BR.md), [日本語](README.ja.md), [Română](README.ro.md).*
<b>AVISO: ESTA É UMA VERSÃO BETA, PORTANTO, VOCÊ PODE ENCONTRAR BUGS. ENCONTROU ALGUM, ABRA UM ISSUE ATRAVÉS DO NOSSO REPOSITÓRIO GITHUB.</b>
@@ -79,6 +81,7 @@ O NewPipe suporta vários serviços. Nosso [documentação](https://teamnewpipe.
* SoundCloud \[beta\]
* media.ccc.de \[beta\]
* PeerTube instances \[beta\]
* Bandcamp \[beta\]
## Atualizações
Quando uma alteração no código NewPipe (devido à adição de recursos ou fixação de bugs), eventualmente ocorrerá uma versão. Estes estão no formato x.xx.x . A fim de obter esta nova versão, você pode:

View File

@@ -2,8 +2,7 @@
<h2 align="center"><b>NewPipe</b></h2>
<h4 align="center">Un front-end de streaming „uşor” liber, pentru Android.</h4>
<!-- F-Droid is extremely out of date, so we hide this for now. -->
<!-- <p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://f-droid.org/wiki/images/0/06/F-Droid-button_get-it-on.png"></a></p> -->
<p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://fdroid.gitlab.io/artwork/badge/get-it-on-ro.svg"></a></p>
<p align="center">
<a href="https://github.com/TeamNewPipe/NewPipe/releases" alt="GitHub release"><img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe.svg" ></a>
@@ -18,7 +17,7 @@
<p align="center"><a href="https://newpipe.net">Website</a> &bull; <a href="https://newpipe.net/blog/">Blog</a> &bull; <a href="https://newpipe.net/FAQ/">FAQ</a> &bull; <a href="https://newpipe.net/press/">Presă</a></p>
<hr>
*Citiţi în alte limbi: [English](README.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt_BR.md), [日本語](README.ja.md), [Română](README.ro.md)*
*Citiţi în alte limbi: [English](README.md), [Español](README.es.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt_BR.md), [日本語](README.ja.md), [Română](README.ro.md)*
<b>Atenţionare: ACEASTA ESTE O VERSIUNE BETA, AŞA CĂ S-AR PUTE SĂ ÎNTÂLNIŢI ERORI. DACĂ SE ÎNTÂMPLĂ ACEST LUCRU, DESCHIDEŢI UN ISSUE PRIN REPSITORY-UL NOSTRU GITHUB.</b>
@@ -81,6 +80,7 @@ NewPipe suportă servicii multiple. [Documentele](https://teamnewpipe.github.io/
* SoundCloud \[beta\]
* media.ccc.de \[beta\]
* Instanţe PeerTube \[beta\]
* Bandcamp \[beta\]
<!-- Hidden span to keep old links compatible. -->
<span id="updates"></span>

View File

@@ -1,7 +1,8 @@
<p align="center"><a href="https://newpipe.net"><img src="assets/new_pipe_icon_5.png" width="150"></a></p>
<h2 align="center"><b>NewPipe</b></h2>
<h4 align="center">App bilaash ah oo fudud looguna talagalay in Android-ka wax loogu daawado.</h4>
<p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://f-droid.org/wiki/images/0/06/F-Droid-button_get-it-on.png"></a></p>
<p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://fdroid.gitlab.io/artwork/badge/get-it-on-so.svg"></a></p>
<p align="center">
<a href="https://github.com/TeamNewPipe/NewPipe/releases" alt="Siidaynta GitHub "><img src="https://img.shields.io/github/release/TeamNewPipe/NewPipe.svg" ></a>
@@ -16,7 +17,7 @@
<p align="center"><a href="https://newpipe.net">Website-ka</a> &bull; <a href="https://newpipe.net/blog/">Maqaalada</a> &bull; <a href="https://newpipe.net/FAQ/">Su'aalaha Aalaa La-iswaydiiyo</a> &bull; <a href="https://newpipe.net/press/">Warbaahinta</a></p>
<hr>
*Ku akhri luuqad kale: [English](README.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt_BR.md), [日本語](README.ja.md), [Română](README.ro.md).*
*Ku akhri luuqad kale: [English](README.md), [Español](README.es.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt_BR.md), [日本語](README.ja.md), [Română](README.ro.md).*
<b>DIGNIIN: MIDKAN, NOOCA APP-KA EE HADDA WALI TIJAABO AYUU KU JIRAA, SIDAA DARTEED CILLADO AYAAD LA KULMI KARTAA. HADAAD LA KULANTO, KA FUR ARIN SHARAXAYA QAYBTANADA ARRIMAHA EE GITHUB-KA.</b>
@@ -79,6 +80,7 @@ NewPipe wuxuu taageeraa adeegyo badan. [warqadan](https://teamnewpipe.github.io/
* SoundCloud \[tijaabo\]
* media.ccc.de \[tijaabo\]
* PeerTube instances \[tijaabo\]
* Bandcamp \[tijaabo\]
## Kushubida iyo cusboonaysiinta
Marka koodhka NewPipe isbadal ku dhaco (wax cusub oo lagusoo kordhiyay ama cilad bixin), ugu dambayn waxaa lasii daayaa mid cusub (Siidayn). Siidaynta qaabkeedu waa x.xx.x . Si aad midka cusub u hesho, waxaad samayn kartaa:

View File

@@ -1,3 +1,7 @@
plugins {
id "org.sonarqube" version "3.1.1"
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
@@ -13,8 +17,8 @@ android {
resValue "string", "app_name", "NewPipe"
minSdkVersion 19
targetSdkVersion 29
versionCode 965
versionName "0.20.11"
versionCode 967
versionName "0.21.1"
multiDexEnabled true
@@ -96,7 +100,7 @@ ext {
checkstyleVersion = '8.38'
stethoVersion = '1.5.1'
leakCanaryVersion = '2.5'
exoPlayerVersion = '2.11.8'
exoPlayerVersion = '2.12.3'
androidxLifecycleVersion = '2.2.0'
androidxRoomVersion = '2.3.0-alpha03'
groupieVersion = '2.8.1'
@@ -111,7 +115,7 @@ configurations {
}
checkstyle {
configFile rootProject.file('checkstyle.xml')
configDir rootProject.file(".")
ignoreFailures false
showViolations true
toolVersion = checkstyleVersion
@@ -158,6 +162,14 @@ afterEvaluate {
preDebugBuild.dependsOn formatKtlint, runCheckstyle, runKtlint
}
sonarqube {
properties {
property "sonar.projectKey", "TeamNewPipe_NewPipe"
property "sonar.organization", "teamnewpipe"
property "sonar.host.url", "https://sonarcloud.io"
}
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1'
@@ -180,7 +192,7 @@ dependencies {
// NewPipe dependencies
// You can use a local version by uncommenting a few lines in settings.gradle
implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.20.11'
implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.21.1'
implementation "com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751"
implementation "org.jsoup:jsoup:1.13.1"
@@ -233,7 +245,7 @@ dependencies {
implementation "io.reactivex.rxjava3:rxandroid:3.0.0"
implementation "com.jakewharton.rxbinding4:rxbinding:4.0.0"
implementation "org.ocpsoft.prettytime:prettytime:4.0.6.Final"
implementation "org.ocpsoft.prettytime:prettytime:5.0.0.Final"
testImplementation 'junit:junit:4.13.1'
testImplementation "org.mockito:mockito-core:${mockitoVersion}"

View File

@@ -0,0 +1,46 @@
package org.schabi.newpipe.error;
import android.os.Parcel;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.ServiceList;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import java.util.Arrays;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Instrumented tests for {@link ErrorInfo}.
*/
@RunWith(AndroidJUnit4.class)
@LargeTest
public class ErrorInfoTest {
@Test
public void errorInfoTestParcelable() {
final ErrorInfo info = new ErrorInfo(new ParsingException("Hello"),
UserAction.USER_REPORT, "request", ServiceList.YouTube.getServiceId());
// Obtain a Parcel object and write the parcelable object to it:
final Parcel parcel = Parcel.obtain();
info.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
final ErrorInfo infoFromParcel = (ErrorInfo) ErrorInfo.CREATOR.createFromParcel(parcel);
assertTrue(Arrays.toString(infoFromParcel.getStackTraces())
.contains(ErrorInfoTest.class.getSimpleName()));
assertEquals(UserAction.USER_REPORT, infoFromParcel.getUserAction());
assertEquals(ServiceList.YouTube.getServiceInfo().getName(),
infoFromParcel.getServiceName());
assertEquals("request", infoFromParcel.getRequest());
assertEquals(R.string.parsing_error, infoFromParcel.getMessageStringId());
parcel.recycle();
}
}

View File

@@ -1,38 +0,0 @@
package org.schabi.newpipe.report;
import android.os.Parcel;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.schabi.newpipe.R;
import static org.junit.Assert.assertEquals;
/**
* Instrumented tests for {@link ErrorInfo}.
*/
@RunWith(AndroidJUnit4.class)
@LargeTest
public class ErrorInfoTest {
@Test
public void errorInfoTestParcelable() {
final ErrorInfo info = ErrorInfo.make(UserAction.USER_REPORT, "youtube", "request",
R.string.general_error);
// Obtain a Parcel object and write the parcelable object to it:
final Parcel parcel = Parcel.obtain();
info.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
final ErrorInfo infoFromParcel = ErrorInfo.CREATOR.createFromParcel(parcel);
assertEquals(UserAction.USER_REPORT, infoFromParcel.getUserAction());
assertEquals("youtube", infoFromParcel.getServiceName());
assertEquals("request", infoFromParcel.getRequest());
assertEquals(R.string.general_error, infoFromParcel.getMessage());
parcel.recycle();
}
}

View File

@@ -85,7 +85,7 @@
android:name=".ExitActivity"
android:label="@string/general_error"
android:theme="@android:style/Theme.NoDisplay" />
<activity android:name=".report.ErrorActivity" />
<activity android:name=".error.ErrorActivity" />
<!-- giga get related -->
<activity
@@ -106,7 +106,7 @@
</activity>
<activity
android:name=".ReCaptchaActivity"
android:name=".error.ReCaptchaActivity"
android:label="@string/recaptcha" />
<provider
@@ -317,6 +317,22 @@
<data android:pathPrefix="/accounts/" />
<data android:pathPrefix="/video-channels/" />
</intent-filter>
<!-- Bandcamp filter -->
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http"/>
<data android:scheme="https"/>
<data android:host="bandcamp.com"/>
<data android:host="*.bandcamp.com"/>
<data android:pathPrefix="/"/>
</intent-filter>
</activity>
<service
android:name=".RouterActivity$FetcherService"

View File

@@ -1,47 +0,0 @@
package org.schabi.newpipe;
/*
* Created by Christian Schabesberger on 24.12.15.
*
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
* ActivityCommunicator.java is part of NewPipe.
*
* NewPipe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NewPipe is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Singleton:
* Used to send data between certain Activity/Services within the same process.
* This can be considered as an ugly hack inside the Android universe.
**/
public class ActivityCommunicator {
private static ActivityCommunicator activityCommunicator;
private volatile Class returnActivity;
public static ActivityCommunicator getCommunicator() {
if (activityCommunicator == null) {
activityCommunicator = new ActivityCommunicator();
}
return activityCommunicator;
}
public Class getReturnActivity() {
return returnActivity;
}
public void setReturnActivity(final Class returnActivity) {
this.returnActivity = returnActivity;
}
}

View File

@@ -20,12 +20,13 @@ import org.acra.ACRA;
import org.acra.config.ACRAConfigurationException;
import org.acra.config.CoreConfiguration;
import org.acra.config.CoreConfigurationBuilder;
import org.schabi.newpipe.error.ErrorActivity;
import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.ReCaptchaActivity;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.ktx.ExceptionUtils;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.ErrorInfo;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.settings.SettingsActivity;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.ServiceHelper;
@@ -224,14 +225,10 @@ public class App extends MultiDexApplication {
.setBuildConfigClass(BuildConfig.class)
.build();
ACRA.init(this, acraConfig);
} catch (final ACRAConfigurationException ace) {
ace.printStackTrace();
ErrorActivity.reportError(this,
ace,
null,
null,
ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
"Could not initialize ACRA crash report", R.string.app_ui_crash));
} catch (final ACRAConfigurationException exception) {
exception.printStackTrace();
ErrorActivity.reportError(this, new ErrorInfo(exception,
UserAction.SOMETHING_ELSE, "Could not initialize ACRA crash report"));
}
}

View File

@@ -10,19 +10,22 @@ import android.content.pm.Signature;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat;
import androidx.preference.PreferenceManager;
import com.grack.nanojson.JsonObject;
import com.grack.nanojson.JsonParser;
import com.grack.nanojson.JsonParserException;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Maybe;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
import org.schabi.newpipe.error.ErrorActivity;
import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.UserAction;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.MessageDigest;
@@ -31,9 +34,11 @@ import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.ErrorInfo;
import org.schabi.newpipe.report.UserAction;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Maybe;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
public final class CheckForNewAppVersion {
private CheckForNewAppVersion() { }
@@ -58,9 +63,8 @@ public final class CheckForNewAppVersion {
packageInfo = application.getPackageManager().getPackageInfo(
application.getPackageName(), PackageManager.GET_SIGNATURES);
} catch (final PackageManager.NameNotFoundException e) {
ErrorActivity.reportError(application, e, null, null,
ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
"Could not find package info", R.string.app_ui_crash));
ErrorActivity.reportError(application, new ErrorInfo(e,
UserAction.CHECK_FOR_NEW_APP_VERSION, "Could not find package info"));
return "";
}
@@ -72,9 +76,8 @@ public final class CheckForNewAppVersion {
final CertificateFactory cf = CertificateFactory.getInstance("X509");
c = (X509Certificate) cf.generateCertificate(input);
} catch (final CertificateException e) {
ErrorActivity.reportError(application, e, null, null,
ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
"Certificate error", R.string.app_ui_crash));
ErrorActivity.reportError(application, new ErrorInfo(e,
UserAction.CHECK_FOR_NEW_APP_VERSION, "Certificate error"));
return "";
}
@@ -83,9 +86,8 @@ public final class CheckForNewAppVersion {
final byte[] publicKey = md.digest(c.getEncoded());
return byte2HexFormatted(publicKey);
} catch (NoSuchAlgorithmException | CertificateEncodingException e) {
ErrorActivity.reportError(application, e, null, null,
ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
"Could not retrieve SHA1 key", R.string.app_ui_crash));
ErrorActivity.reportError(application, new ErrorInfo(e,
UserAction.CHECK_FOR_NEW_APP_VERSION, "Could not retrieve SHA1 key"));
return "";
}
}

View File

@@ -7,6 +7,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceManager;
import org.schabi.newpipe.error.ReCaptchaActivity;
import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.extractor.downloader.Request;
import org.schabi.newpipe.extractor.downloader.Response;
@@ -43,7 +44,7 @@ import static org.schabi.newpipe.MainActivity.DEBUG;
public final class DownloaderImpl extends Downloader {
public static final String USER_AGENT
= "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Firefox/68.0";
= "Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0";
public static final String YOUTUBE_RESTRICTED_MODE_COOKIE_KEY
= "youtube_restricted_mode_key";
public static final String YOUTUBE_RESTRICTED_MODE_COOKIE = "PREF=f2=8000000";

View File

@@ -60,6 +60,7 @@ import org.schabi.newpipe.databinding.DrawerHeaderBinding;
import org.schabi.newpipe.databinding.DrawerLayoutBinding;
import org.schabi.newpipe.databinding.InstanceSpinnerLayoutBinding;
import org.schabi.newpipe.databinding.ToolbarLayoutBinding;
import org.schabi.newpipe.error.ErrorActivity;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
@@ -72,7 +73,6 @@ import org.schabi.newpipe.player.Player;
import org.schabi.newpipe.player.event.OnKeyDownListener;
import org.schabi.newpipe.player.helper.PlayerHolder;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.KioskTranslator;
@@ -153,7 +153,7 @@ public class MainActivity extends AppCompatActivity {
try {
setupDrawer();
} catch (final Exception e) {
ErrorActivity.reportUiError(this, e);
ErrorActivity.reportUiErrorInSnackbar(this, "Setting up drawer", e);
}
if (DeviceUtils.isTv(this)) {
@@ -238,7 +238,7 @@ public class MainActivity extends AppCompatActivity {
try {
tabSelected(item);
} catch (final Exception e) {
ErrorActivity.reportUiError(this, e);
ErrorActivity.reportUiErrorInSnackbar(this, "Selecting main page tab", e);
}
break;
case R.id.menu_options_about_group:
@@ -340,7 +340,7 @@ public class MainActivity extends AppCompatActivity {
try {
showTabs();
} catch (final Exception e) {
ErrorActivity.reportUiError(this, e);
ErrorActivity.reportUiErrorInSnackbar(this, "Showing main page tabs", e);
}
}
}
@@ -487,7 +487,7 @@ public class MainActivity extends AppCompatActivity {
drawerHeaderBinding.drawerHeaderActionButton.setContentDescription(
getString(R.string.drawer_header_description) + selectedServiceName);
} catch (final Exception e) {
ErrorActivity.reportUiError(this, e);
ErrorActivity.reportUiErrorInSnackbar(this, "Setting up service toggle", e);
}
final SharedPreferences sharedPreferences
@@ -679,19 +679,16 @@ public class MainActivity extends AppCompatActivity {
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
public boolean onOptionsItemSelected(@NonNull final MenuItem item) {
if (DEBUG) {
Log.d(TAG, "onOptionsItemSelected() called with: item = [" + item + "]");
}
final int id = item.getItemId();
switch (id) {
case android.R.id.home:
onHomeButtonPressed();
return true;
default:
return super.onOptionsItemSelected(item);
if (item.getItemId() == android.R.id.home) {
onHomeButtonPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
/*//////////////////////////////////////////////////////////////////////////
@@ -799,7 +796,7 @@ public class MainActivity extends AppCompatActivity {
NavigationHelper.gotoMainFragment(getSupportFragmentManager());
}
} catch (final Exception e) {
ErrorActivity.reportUiError(this, e);
ErrorActivity.reportUiErrorInSnackbar(this, "Handling intent", e);
}
}

View File

@@ -33,15 +33,29 @@ import androidx.preference.PreferenceManager;
import org.schabi.newpipe.databinding.ListRadioIconItemBinding;
import org.schabi.newpipe.databinding.SingleChoiceDialogViewBinding;
import org.schabi.newpipe.download.DownloadDialog;
import org.schabi.newpipe.error.ErrorActivity;
import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.ReCaptchaActivity;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.extractor.Info;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.StreamingService.LinkType;
import org.schabi.newpipe.extractor.channel.ChannelInfo;
import org.schabi.newpipe.extractor.exceptions.AgeRestrictedContentException;
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.exceptions.GeographicRestrictionException;
import org.schabi.newpipe.extractor.exceptions.PaidContentException;
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.playlist.PlaylistInfo;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.ktx.ExceptionUtils;
import org.schabi.newpipe.player.MainPlayer;
import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.player.helper.PlayerHolder;
@@ -49,7 +63,6 @@ import org.schabi.newpipe.player.playqueue.ChannelPlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.ExtractorHelper;
@@ -84,13 +97,6 @@ import static org.schabi.newpipe.util.ThemeHelper.resolveResourceIdFromAttr;
* Get the url from the intent and open it in the chosen preferred player.
*/
public class RouterActivity extends AppCompatActivity {
public static final String INTERNAL_ROUTE_KEY = "internalRoute";
/**
* Removes invisible separators (\p{Z}) and punctuation characters including
* brackets (\p{P}). See http://www.regular-expressions.info/unicode.html for
* more details.
*/
private static final String REGEX_REMOVE_FROM_URL = "[\\p{Z}\\p{P}]";
protected final CompositeDisposable disposables = new CompositeDisposable();
@State
protected int currentServiceId = -1;
@@ -100,7 +106,6 @@ public class RouterActivity extends AppCompatActivity {
protected int selectedRadioPosition = -1;
protected int selectedPreviously = -1;
protected String currentUrl;
protected boolean internalRoute = false;
private StreamingService currentService;
private boolean selectionIsDownload = false;
@@ -123,7 +128,7 @@ public class RouterActivity extends AppCompatActivity {
}
@Override
protected void onSaveInstanceState(final Bundle outState) {
protected void onSaveInstanceState(@NonNull final Bundle outState) {
super.onSaveInstanceState(outState);
Icepick.saveInstanceState(this, outState);
}
@@ -145,37 +150,79 @@ public class RouterActivity extends AppCompatActivity {
private void handleUrl(final String url) {
disposables.add(Observable
.fromCallable(() -> {
if (currentServiceId == -1) {
currentService = NewPipe.getServiceByUrl(url);
currentServiceId = currentService.getServiceId();
currentLinkType = currentService.getLinkTypeByUrl(url);
currentUrl = url;
} else {
currentService = NewPipe.getService(currentServiceId);
}
try {
if (currentServiceId == -1) {
currentService = NewPipe.getServiceByUrl(url);
currentServiceId = currentService.getServiceId();
currentLinkType = currentService.getLinkTypeByUrl(url);
currentUrl = url;
} else {
currentService = NewPipe.getService(currentServiceId);
}
return currentLinkType != LinkType.NONE;
// return whether the url was found to be supported or not
return currentLinkType != LinkType.NONE;
} catch (final ExtractionException e) {
// this can be reached only when the url is completely unsupported
return false;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
if (result) {
.subscribe(isUrlSupported -> {
if (isUrlSupported) {
onSuccess();
} else {
showUnsupportedUrlDialog(url);
}
}, throwable -> handleError(throwable, url)));
}, throwable -> handleError(this, new ErrorInfo(throwable,
UserAction.SHARE_TO_NEWPIPE, "Getting service from url: " + url))));
}
private void handleError(final Throwable throwable, final String url) {
throwable.printStackTrace();
/**
* @param context the context. It will be {@code finish()}ed at the end of the handling if it is
* an instance of {@link RouterActivity}.
* @param errorInfo the error information
*/
private static void handleError(final Context context, final ErrorInfo errorInfo) {
if (errorInfo.getThrowable() != null) {
errorInfo.getThrowable().printStackTrace();
}
if (throwable instanceof ExtractionException) {
showUnsupportedUrlDialog(url);
if (errorInfo.getThrowable() instanceof ReCaptchaException) {
Toast.makeText(context, R.string.recaptcha_request_toast, Toast.LENGTH_LONG).show();
// Starting ReCaptcha Challenge Activity
final Intent intent = new Intent(context, ReCaptchaActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} else if (errorInfo.getThrowable() != null
&& ExceptionUtils.isNetworkRelated(errorInfo.getThrowable())) {
Toast.makeText(context, R.string.network_error, Toast.LENGTH_LONG).show();
} else if (errorInfo.getThrowable() instanceof AgeRestrictedContentException) {
Toast.makeText(context, R.string.restricted_video_no_stream,
Toast.LENGTH_LONG).show();
} else if (errorInfo.getThrowable() instanceof GeographicRestrictionException) {
Toast.makeText(context, R.string.georestricted_content, Toast.LENGTH_LONG).show();
} else if (errorInfo.getThrowable() instanceof PaidContentException) {
Toast.makeText(context, R.string.paid_content, Toast.LENGTH_LONG).show();
} else if (errorInfo.getThrowable() instanceof PrivateContentException) {
Toast.makeText(context, R.string.private_content, Toast.LENGTH_LONG).show();
} else if (errorInfo.getThrowable() instanceof SoundCloudGoPlusContentException) {
Toast.makeText(context, R.string.soundcloud_go_plus_content,
Toast.LENGTH_LONG).show();
} else if (errorInfo.getThrowable() instanceof YoutubeMusicPremiumContentException) {
Toast.makeText(context, R.string.youtube_music_premium_content,
Toast.LENGTH_LONG).show();
} else if (errorInfo.getThrowable() instanceof ContentNotAvailableException) {
Toast.makeText(context, R.string.content_not_available, Toast.LENGTH_LONG).show();
} else if (errorInfo.getThrowable() instanceof ContentNotSupportedException) {
Toast.makeText(context, R.string.content_not_supported, Toast.LENGTH_LONG).show();
} else {
ExtractorHelper.handleGeneralException(this, -1, url, throwable,
UserAction.SOMETHING_ELSE, null);
finish();
ErrorActivity.reportError(context, errorInfo);
}
if (context instanceof RouterActivity) {
((RouterActivity) context).finish();
}
}
@@ -500,7 +547,8 @@ public class RouterActivity extends AppCompatActivity {
.subscribe(intent -> {
startActivity(intent);
finish();
}, throwable -> handleError(throwable, currentUrl))
}, throwable -> handleError(this, new ErrorInfo(throwable,
UserAction.SHARE_TO_NEWPIPE, "Starting info activity: " + currentUrl)))
);
return;
}
@@ -580,6 +628,7 @@ public class RouterActivity extends AppCompatActivity {
this.playerChoice = playerChoice;
}
@NonNull
@Override
public String toString() {
return serviceId + ":" + url + " > " + linkType + " ::: " + playerChoice;
@@ -646,9 +695,9 @@ public class RouterActivity extends AppCompatActivity {
if (fetcher != null) {
fetcher.dispose();
}
}, throwable -> ExtractorHelper.handleGeneralException(this,
choice.serviceId, choice.url, throwable, finalUserAction,
", opened with " + choice.playerChoice));
}, throwable -> handleError(this, new ErrorInfo(throwable, finalUserAction,
choice.url + " opened with " + choice.playerChoice,
choice.serviceId)));
}
}

View File

@@ -7,7 +7,6 @@ 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 kotlin.jvm.Throws
data class PlaylistStreamEntry(
@Embedded

View File

@@ -37,6 +37,9 @@ import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.RouterActivity;
import org.schabi.newpipe.databinding.DownloadDialogBinding;
import org.schabi.newpipe.error.ErrorActivity;
import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.extractor.MediaFormat;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.localization.Localization;
@@ -45,9 +48,6 @@ import org.schabi.newpipe.extractor.stream.Stream;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.SubtitlesStream;
import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.ErrorInfo;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.settings.NewPipeSettings;
import org.schabi.newpipe.util.FilePickerActivityHelper;
import org.schabi.newpipe.util.FilenameUtils;
@@ -61,7 +61,6 @@ import org.schabi.newpipe.util.ThemeHelper;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
@@ -591,17 +590,6 @@ public class DownloadDialog extends DialogFragment
.show();
}
private void showErrorActivity(final Exception e) {
ErrorActivity.reportError(
context,
Collections.singletonList(e),
null,
null,
ErrorInfo
.make(UserAction.SOMETHING_ELSE, "-", "-", R.string.general_error)
);
}
private void prepareSelectedDownload() {
final StoredDirectoryHelper mainStorage;
final MediaFormat format;
@@ -684,6 +672,9 @@ public class DownloadDialog extends DialogFragment
prefs.edit()
.putString(getString(R.string.last_used_download_type), selectedMediaType)
.apply();
Toast.makeText(context, getString(R.string.download_has_started),
Toast.LENGTH_SHORT).show();
}
private void checkSelectedDownload(final StoredDirectoryHelper mainStorage,
@@ -705,7 +696,8 @@ public class DownloadDialog extends DialogFragment
mainStorage.getTag());
}
} catch (final Exception e) {
showErrorActivity(e);
ErrorActivity.reportErrorInSnackbar(this,
new ErrorInfo(e, UserAction.DOWNLOAD_FAILED, "Getting storage"));
return;
}

View File

@@ -1,9 +1,10 @@
package org.schabi.newpipe.report;
package org.schabi.newpipe.error;
import android.content.Context;
import androidx.annotation.NonNull;
import org.acra.ReportField;
import org.acra.data.CrashReportData;
import org.acra.sender.ReportSender;
import org.schabi.newpipe.R;
@@ -32,8 +33,12 @@ public class AcraReportSender implements ReportSender {
@Override
public void send(@NonNull final Context context, @NonNull final CrashReportData report) {
ErrorActivity.reportError(context, report,
ErrorInfo.make(UserAction.UI_ERROR, "none",
"App crash, UI failure", R.string.app_ui_crash));
ErrorActivity.reportError(context, new ErrorInfo(
new String[]{report.getString(ReportField.STACK_TRACE)},
UserAction.UI_ERROR,
ErrorInfo.SERVICE_NONE,
"ACRA report",
R.string.app_ui_crash,
null));
}
}

View File

@@ -1,4 +1,4 @@
package org.schabi.newpipe.report;
package org.schabi.newpipe.error;
import android.content.Context;

View File

@@ -0,0 +1,113 @@
package org.schabi.newpipe.error
import android.os.Parcelable
import androidx.annotation.StringRes
import kotlinx.android.parcel.Parcelize
import org.schabi.newpipe.R
import org.schabi.newpipe.extractor.Info
import org.schabi.newpipe.extractor.NewPipe
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 java.io.PrintWriter
import java.io.StringWriter
@Parcelize
class ErrorInfo(
val stackTraces: Array<String>,
val userAction: UserAction,
val serviceName: String,
val request: String,
val messageStringId: Int,
@Transient // no need to store throwable, all data for report is in other variables
var throwable: Throwable? = null
) : Parcelable {
private constructor(
throwable: Throwable,
userAction: UserAction,
serviceName: String,
request: String
) : this(
throwableToStringList(throwable),
userAction,
serviceName,
request,
getMessageStringId(throwable, userAction),
throwable
)
private constructor(
throwable: List<Throwable>,
userAction: UserAction,
serviceName: String,
request: String
) : this(
throwableListToStringList(throwable),
userAction,
serviceName,
request,
getMessageStringId(throwable.firstOrNull(), userAction),
throwable.firstOrNull()
)
// constructors with single throwable
constructor(throwable: Throwable, userAction: UserAction, request: String) :
this(throwable, userAction, SERVICE_NONE, request)
constructor(throwable: Throwable, userAction: UserAction, request: String, serviceId: Int) :
this(throwable, userAction, NewPipe.getNameOfService(serviceId), request)
constructor(throwable: Throwable, userAction: UserAction, request: String, info: Info?) :
this(throwable, userAction, getInfoServiceName(info), request)
// constructors with list of throwables
constructor(throwable: List<Throwable>, userAction: UserAction, request: String) :
this(throwable, userAction, SERVICE_NONE, request)
constructor(throwable: List<Throwable>, userAction: UserAction, request: String, serviceId: Int) :
this(throwable, userAction, NewPipe.getNameOfService(serviceId), request)
constructor(throwable: List<Throwable>, userAction: UserAction, request: String, info: Info?) :
this(throwable, userAction, getInfoServiceName(info), request)
companion object {
const val SERVICE_NONE = "none"
private fun getStackTrace(throwable: Throwable): String {
StringWriter().use { stringWriter ->
PrintWriter(stringWriter, true).use { printWriter ->
throwable.printStackTrace(printWriter)
return stringWriter.buffer.toString()
}
}
}
fun throwableToStringList(throwable: Throwable) = arrayOf(getStackTrace(throwable))
fun throwableListToStringList(throwable: List<Throwable>) =
Array(throwable.size) { i -> getStackTrace(throwable[i]) }
private fun getInfoServiceName(info: Info?) =
if (info == null) SERVICE_NONE else NewPipe.getNameOfService(info.serviceId)
@StringRes
private fun getMessageStringId(
throwable: Throwable?,
action: UserAction
): Int {
return when {
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
action == UserAction.UI_ERROR -> R.string.app_ui_crash
action == UserAction.REQUESTED_COMMENTS -> R.string.error_unable_to_load_comments
action == UserAction.SUBSCRIPTION_CHANGE -> R.string.subscription_change_failed
action == UserAction.SUBSCRIPTION_UPDATE -> R.string.subscription_update_failed
action == UserAction.LOAD_IMAGE -> R.string.could_not_load_thumbnails
action == UserAction.DOWNLOAD_OPEN_DIALOG -> R.string.could_not_setup_download_menu
else -> R.string.general_error
}
}
}
}

View File

@@ -0,0 +1,132 @@
package org.schabi.newpipe.error
import android.content.Context
import android.content.Intent
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import com.jakewharton.rxbinding4.view.clicks
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.Disposable
import org.schabi.newpipe.MainActivity
import org.schabi.newpipe.R
import org.schabi.newpipe.extractor.exceptions.AgeRestrictedContentException
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException
import org.schabi.newpipe.extractor.exceptions.GeographicRestrictionException
import org.schabi.newpipe.extractor.exceptions.PaidContentException
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.ktx.animate
import org.schabi.newpipe.ktx.isInterruptedCaused
import org.schabi.newpipe.ktx.isNetworkRelated
import java.util.concurrent.TimeUnit
class ErrorPanelHelper(
private val fragment: Fragment,
rootView: View,
onRetry: Runnable
) {
private val context: Context = rootView.context!!
private val errorPanelRoot: View = rootView.findViewById(R.id.error_panel)
private val errorTextView: TextView = errorPanelRoot.findViewById(R.id.error_message_view)
private val errorButtonAction: Button = errorPanelRoot.findViewById(R.id.error_button_action)
private val errorButtonRetry: Button = errorPanelRoot.findViewById(R.id.error_button_retry)
private var errorDisposable: Disposable? = null
init {
errorDisposable = errorButtonRetry.clicks()
.debounce(300, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe { onRetry.run() }
}
fun showError(errorInfo: ErrorInfo) {
if (errorInfo.throwable != null && errorInfo.throwable!!.isInterruptedCaused) {
if (DEBUG) {
Log.w(TAG, "onError() isInterruptedCaused! = [$errorInfo.throwable]")
}
return
}
errorButtonAction.isVisible = true
if (errorInfo.throwable is ReCaptchaException) {
errorButtonAction.setText(R.string.recaptcha_solve)
errorButtonAction.setOnClickListener {
// Starting ReCaptcha Challenge Activity
val intent = Intent(context, ReCaptchaActivity::class.java)
intent.putExtra(
ReCaptchaActivity.RECAPTCHA_URL_EXTRA,
(errorInfo.throwable as ReCaptchaException).url
)
fragment.startActivityForResult(intent, ReCaptchaActivity.RECAPTCHA_REQUEST)
errorButtonAction.setOnClickListener(null)
}
errorTextView.setText(R.string.recaptcha_request_toast)
errorButtonRetry.isVisible = true
} else {
errorButtonAction.setText(R.string.error_snackbar_action)
errorButtonAction.setOnClickListener {
ErrorActivity.reportError(context, errorInfo)
}
// hide retry button by default, then show only if not unavailable/unsupported content
errorButtonRetry.isVisible = false
errorTextView.setText(
when (errorInfo.throwable) {
is AgeRestrictedContentException -> R.string.restricted_video_no_stream
is GeographicRestrictionException -> R.string.georestricted_content
is PaidContentException -> R.string.paid_content
is PrivateContentException -> R.string.private_content
is SoundCloudGoPlusContentException -> R.string.soundcloud_go_plus_content
is YoutubeMusicPremiumContentException -> R.string.youtube_music_premium_content
is ContentNotAvailableException -> R.string.content_not_available
is ContentNotSupportedException -> R.string.content_not_supported
else -> {
// show retry button only for content which is not unavailable or unsupported
errorButtonRetry.isVisible = true
if (errorInfo.throwable != null && errorInfo.throwable!!.isNetworkRelated) {
R.string.network_error
} else {
R.string.error_snackbar_message
}
}
}
)
}
errorPanelRoot.animate(true, 300)
}
fun showTextError(errorString: String) {
errorButtonAction.isVisible = false
errorButtonRetry.isVisible = false
errorTextView.text = errorString
}
fun hide() {
errorButtonAction.setOnClickListener(null)
errorPanelRoot.animate(false, 150)
}
fun isVisible(): Boolean {
return errorPanelRoot.isVisible
}
fun dispose() {
errorButtonAction.setOnClickListener(null)
errorButtonRetry.setOnClickListener(null)
errorDisposable?.dispose()
}
companion object {
val TAG: String = ErrorPanelHelper::class.simpleName!!
val DEBUG: Boolean = MainActivity.DEBUG
}
}

View File

@@ -1,4 +1,4 @@
package org.schabi.newpipe;
package org.schabi.newpipe.error;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -20,6 +20,9 @@ import androidx.preference.PreferenceManager;
import androidx.webkit.WebViewClientCompat;
import org.schabi.newpipe.databinding.ActivityRecaptchaBinding;
import org.schabi.newpipe.DownloaderImpl;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.util.ThemeHelper;
import java.io.UnsupportedEncodingException;

View File

@@ -1,4 +1,4 @@
package org.schabi.newpipe.report;
package org.schabi.newpipe.error;
/**
* The user actions that can cause an error.
@@ -6,9 +6,12 @@ package org.schabi.newpipe.report;
public enum UserAction {
USER_REPORT("user report"),
UI_ERROR("ui error"),
SUBSCRIPTION("subscription"),
SUBSCRIPTION_CHANGE("subscription change"),
SUBSCRIPTION_UPDATE("subscription update"),
SUBSCRIPTION_GET("get subscription"),
SUBSCRIPTION_IMPORT_EXPORT("subscription import or export"),
LOAD_IMAGE("load image"),
SOMETHING_ELSE("something"),
SOMETHING_ELSE("something else"),
SEARCHED("searched"),
GET_SUGGESTIONS("get suggestions"),
REQUESTED_STREAM("requested stream"),
@@ -17,11 +20,15 @@ public enum UserAction {
REQUESTED_KIOSK("requested kiosk"),
REQUESTED_COMMENTS("requested comments"),
REQUESTED_FEED("requested feed"),
REQUESTED_BOOKMARK("bookmark"),
DELETE_FROM_HISTORY("delete from history"),
PLAY_STREAM("Play stream"),
PLAY_STREAM("play stream"),
DOWNLOAD_OPEN_DIALOG("download open dialog"),
DOWNLOAD_POSTPROCESSING("download post-processing"),
DOWNLOAD_FAILED("download failed"),
PREFERENCES_MIGRATION("migration of preferences");
PREFERENCES_MIGRATION("migration of preferences"),
SHARE_TO_NEWPIPE("share to newpipe"),
CHECK_FOR_NEW_APP_VERSION("check for new app version");
private final String message;

View File

@@ -11,9 +11,18 @@ import org.schabi.newpipe.BaseFragment;
import org.schabi.newpipe.R;
public class EmptyFragment extends BaseFragment {
final boolean showMessage;
public EmptyFragment(final boolean showMessage) {
this.showMessage = showMessage;
}
@Override
public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container,
final Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_empty, container, false);
final View view = inflater.inflate(R.layout.fragment_empty, container, false);
view.findViewById(R.id.empty_state_view).setVisibility(
showMessage ? View.VISIBLE : View.GONE);
return view;
}
}

View File

@@ -14,7 +14,6 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapterMenuWorkaround;
@@ -25,10 +24,8 @@ import com.google.android.material.tabs.TabLayout;
import org.schabi.newpipe.BaseFragment;
import org.schabi.newpipe.R;
import org.schabi.newpipe.databinding.FragmentMainBinding;
import org.schabi.newpipe.error.ErrorActivity;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.ErrorInfo;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.settings.tabs.Tab;
import org.schabi.newpipe.settings.tabs.TabsManager;
import org.schabi.newpipe.util.NavigationHelper;
@@ -128,7 +125,8 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
//////////////////////////////////////////////////////////////////////////*/
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
public void onCreateOptionsMenu(@NonNull final Menu menu,
@NonNull final MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
if (DEBUG) {
Log.d(TAG, "onCreateOptionsMenu() called with: "
@@ -144,15 +142,14 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.action_search:
try {
NavigationHelper.openSearchFragment(getFM(),
ServiceHelper.getSelectedServiceId(activity), "");
} catch (final Exception e) {
ErrorActivity.reportUiError((AppCompatActivity) getActivity(), e);
}
return true;
if (item.getItemId() == R.id.action_search) {
try {
NavigationHelper.openSearchFragment(getFM(),
ServiceHelper.getSelectedServiceId(activity), "");
} catch (final Exception e) {
ErrorActivity.reportUiErrorInSnackbar(this, "Opening search fragment", e);
}
return true;
}
return super.onOptionsItemSelected(item);
}
@@ -241,8 +238,7 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
}
if (throwable != null) {
ErrorActivity.reportError(context, throwable, null, null, ErrorInfo
.make(UserAction.UI_ERROR, "none", "", R.string.app_ui_crash));
ErrorActivity.reportUiErrorInSnackbar(context, "Getting fragment item", throwable);
return new BlankFragment();
}
@@ -254,7 +250,7 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
}
@Override
public int getItemPosition(final Object object) {
public int getItemPosition(@NonNull final Object object) {
// Causes adapter to reload all Fragments when
// notifyDataSetChanged is called
return POSITION_NONE;

View File

@@ -7,7 +7,7 @@ public interface ViewContract<I> {
void showEmptyState();
void showError(String message, boolean showRetryButton);
void handleResult(I result);
void handleError();
}

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