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

Compare commits

...

291 Commits

Author SHA1 Message Date
Christian Schabesberger
748f70ba87 fix subscriber count 2019-09-18 15:31:06 +02:00
TobiGr
ec4757d6de Move on to 0.17.3 2019-09-12 22:52:40 +02:00
TobiGr
6447af8541 Update extractor version to fix live streams 2019-09-12 22:43:07 +02:00
Christian Schabesberger
209c1f8bc2 merge master back into dev 2019-09-12 13:22:24 +02:00
Tobias Groza
6a37dfc35f Merge pull request #2488 from 2secslater/patch-1
Add all (HTTP(S)) Invidious instances
2019-09-12 09:29:25 +02:00
Tobias Groza
5e101a4d32 Merge branch 'dev' into patch-1 2019-09-12 09:23:30 +02:00
Christian Schabesberger
c29ea4693d Merge pull request #2617 from TeamNewPipe/hotfix_stream_fmt
add fixed extractor and move on to version 0.17.2
2019-09-11 22:36:17 +02:00
Christian Schabesberger
7d0df7aa80 add fixed extractor and move on to version 0.17.2 2019-09-11 22:30:41 +02:00
Tobias Groza
1275d9a185 Merge pull request #2592 from kapodamy/android-pie-workarrounds
Fix performance problem in android pie
2019-09-09 20:08:41 +02:00
Tobias Groza
75f2ced937 Merge branch 'dev' into android-pie-workarrounds 2019-09-09 18:59:59 +02:00
Tobias Groza
cd2ac25ff6 Merge pull request #2533 from jimbo1qaz/remove-dead-code
Remove commented-out code in VideoDetailFragment
2019-09-09 18:43:47 +02:00
Tobias Groza
cbf9ec0901 Merge branch 'dev' into remove-dead-code 2019-09-04 22:59:18 +02:00
Tobias Groza
ede18ded40 Merge pull request #2591 from kapodamy/allow-pick-hidden-folders
show hidden directories in the file picker
2019-09-04 22:56:05 +02:00
kapodamy
a446313119 add warning after toggle the SAF option 2019-09-01 18:53:12 -03:00
kapodamy
1a643126de Changes for Android 9 (Pie)
* validate the stored file before start the mission
* add warning on StoredFileHelper.java
* simplify the communication between MissionAdapter and DownloadManagerService.java since shares the same looper
* simplify setVisible() "start/pause all downloads" buttons logic
2019-09-01 18:37:06 -03:00
kapodamy
6fa72e4a52 add @NotNull 2019-09-01 18:07:14 -03:00
kapodamy
7f127ba52a show hidden directories in the file picker 2019-09-01 17:35:42 -03:00
Tobias Groza
85d1888ba7 Merge pull request #2550 from TeamNewPipe/clear_playback_states
Clear playback states
2019-08-28 21:07:26 +02:00
TobiGr
2a15f5fb51 Make export_data and import_data settings keys untranslatable 2019-08-22 21:51:59 +02:00
TobiGr
7cd5af5e72 Add option in history settings to delete playback positions 2019-08-22 21:49:33 +02:00
TobiGr
cbdfb15117 Merge remote-tracking branch 'newpipe/master' into dev 2019-08-22 21:46:42 +02:00
Christian Schabesberger
7ba71e3b37 use newerextractor 2019-08-22 11:39:32 +02:00
Christian Schabesberger
670a95a01d Merge pull request #2530 from TeamNewPipe/release_v0.17.1
Release v0.17.1
2019-08-22 11:21:06 +02:00
Tobias Groza
acea26717c Fix another %s in translation 2019-08-21 14:35:39 +02:00
TobiGr
e6bcb4628a Fix Portuguese minimize_on_exit_summary
Fix #2522
2019-08-21 14:35:39 +02:00
TobiGr
c4f08d541d Add changelog for 0.17.1 (760) 2019-08-21 14:35:39 +02:00
TobiGr
58546751dd Merge remote-tracking branch 'Weblate/dev' into dev 2019-08-21 14:35:31 +02:00
Hosted Weblate
5470c9a002 Merge branch 'origin/dev' into Weblate. 2019-08-19 20:23:29 +02:00
Xiang Xu
8885b45259 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (471 of 471 strings)
2019-08-19 20:23:28 +02:00
Westminboy
85632b24fc Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (471 of 471 strings)
2019-08-19 20:23:27 +02:00
Yaron Shahrabani
96802c7b5c Translated using Weblate (Hebrew)
Currently translated at 100.0% (471 of 471 strings)
2019-08-19 20:23:27 +02:00
ssantos
e5207f8b42 Translated using Weblate (Portuguese)
Currently translated at 100.0% (471 of 471 strings)
2019-08-19 20:23:25 +02:00
naofum
9d573e1b1d Translated using Weblate (Japanese)
Currently translated at 100.0% (471 of 471 strings)
2019-08-19 20:23:24 +02:00
Yaron Shahrabani
dd276aabc1 Translated using Weblate (English)
Currently translated at 100.0% (471 of 471 strings)
2019-08-19 20:23:22 +02:00
Eduardo Caron
e4d0635ae1 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (471 of 471 strings)
2019-08-19 20:23:21 +02:00
TobiGr
60f534d7a1 Merge remote-tracking branch 'Weblate/dev' into dev 2019-08-18 11:30:04 +02:00
jimbo1qaz
942e042933 remove dead code 2019-08-17 23:21:06 -07:00
Allan Nordhøy
223ddaa9bf Translated using Weblate (Norwegian Bokmål)
Currently translated at 96.8% (456 of 471 strings)
2019-08-18 07:09:54 +02:00
Westminboy
1d6c722c28 Translated using Weblate (Chinese (Simplified))
Currently translated at 99.8% (470 of 471 strings)
2019-08-18 07:09:53 +02:00
Florian
9c9dd6c7bf Translated using Weblate (French)
Currently translated at 98.3% (463 of 471 strings)
2019-08-18 07:09:51 +02:00
zmni
7ff48a6d84 Translated using Weblate (Indonesian)
Currently translated at 99.2% (467 of 471 strings)
2019-08-18 07:09:50 +02:00
thami simo
645e16fd90 Translated using Weblate (Arabic)
Currently translated at 99.6% (469 of 471 strings)
2019-08-18 07:09:49 +02:00
Trần Lê Nhật Huy
1bb58a10e2 Translated using Weblate (Vietnamese)
Currently translated at 99.6% (469 of 471 strings)
2019-08-18 07:09:47 +02:00
ΜŜβ
118788436e Translated using Weblate (Punjabi)
Currently translated at 99.6% (469 of 471 strings)
2019-08-18 07:09:45 +02:00
Marc Riera
0b0f7919a2 Translated using Weblate (Catalan)
Currently translated at 95.8% (451 of 471 strings)
2019-08-18 07:09:12 +02:00
uievawkejf
c8e23fb6ce Translated using Weblate (Ukrainian)
Currently translated at 99.4% (468 of 471 strings)
2019-08-18 07:09:11 +02:00
Osoitz
bc10717f61 Translated using Weblate (Basque)
Currently translated at 99.4% (468 of 471 strings)
2019-08-18 07:09:10 +02:00
Westminboy
e621dd3b28 Translated using Weblate (English)
Currently translated at 100.0% (471 of 471 strings)
2019-08-18 07:09:08 +02:00
Tobias Groza
20208be556 Translated using Weblate (German)
Currently translated at 99.4% (468 of 471 strings)
2019-08-18 07:09:06 +02:00
Kowith Singkornkeeree
9074733aab Translated using Weblate (Thai)
Currently translated at 54.8% (258 of 471 strings)
2019-08-18 07:09:06 +02:00
Westminboy
ae0ee61e7d Translated using Weblate (English)
Currently translated at 100.0% (471 of 471 strings)
2019-08-18 07:09:03 +02:00
Allan Nordhøy
ac797196f5 Translated using Weblate (English)
Currently translated at 100.0% (471 of 471 strings)
2019-08-18 07:09:03 +02:00
Christian Schabesberger
30aa64e9c6 Merge branch 'dev' of github.com:teamnewpipe/newpipe into dev 2019-08-18 01:01:43 +02:00
Christian Schabesberger
b992add77b move on to version 0.17.1 2019-08-18 01:00:54 +02:00
TobiGr
88ebd963f7 Merge remote-tracking branch 'Weblate/dev' into dev 2019-08-18 00:51:52 +02:00
Christian Schabesberger
96baa2978d Merge pull request #2521 from kapodamy/saf-workarround
Downloads: add switch for saf/legacy file picker
2019-08-18 00:42:59 +02:00
Christian Schabesberger
c01609b858 Merge branch 'dev' into saf-workarround 2019-08-18 00:40:43 +02:00
Christian Schabesberger
c89f0e5547 Merge pull request #2527 from Stypox/recaptcha-with-url
Fix ReCaptchaActivity
2019-08-18 00:39:30 +02:00
kapodamy
10dfcbf0b9 add manual switch in download setting fragment
switch for:
* Java I/O Api
* Storage Access Framework
2019-08-17 13:38:33 -03:00
Stypox
43446d56c5 Load the url from the exception in the ReCaptchaActivity
Sometimes YouTube introduces recaptchas only on some pages. By loading the url inside the ReCaptchaException into ReCaptchaActivity's webview, the page that originally caused the problem is shown. The user can then solve the page-specific recaptcha.
2019-08-17 09:33:51 +02:00
Stypox
e66f2ab36b Fix ReCaptchaActivity layout crash due to hidden EditText
Closes #2484
2019-08-17 09:33:20 +02:00
Stypox
63def07a0e Add url to recaptcha exceptions, after update in extractor 2019-08-17 09:25:49 +02:00
kapodamy
1ba7710af8 Merge remote-tracking branch 'origin/saf-workarround' into saf-workarround 2019-08-15 21:49:21 -03:00
kapodamy
8f13a7ec97 check if the if the content provider is disabled (the app itself) 2019-08-15 21:48:07 -03:00
Christian Schabesberger
93dff5cf7a Merge branch 'dev' into saf-workarround 2019-08-15 14:37:19 +02:00
Christian Schabesberger
6a0450b9f6 Merge pull request #2516 from rogersachan/patch-1
Add GitHub sponsors button to feature liberapay
2019-08-15 14:36:58 +02:00
nautilusx
fffeadd8ea Translated using Weblate (German)
Currently translated at 100.0% (471 of 471 strings)
2019-08-15 09:51:19 +02:00
Hosted Weblate
b697e058d9 Merge branch 'origin/dev' into Weblate. 2019-08-15 06:23:56 +02:00
thami simo
14db8b1283 Translated using Weblate (Arabic)
Currently translated at 100.0% (451 of 451 strings)
2019-08-15 06:23:54 +02:00
Kowith Singkornkeeree
45ad8621cf Translated using Weblate (Thai)
Currently translated at 59.4% (268 of 451 strings)
2019-08-15 06:23:54 +02:00
kapodamy
dee3a18ea8 misc changes
* restore permission request popup previously removed in #2486
* use legacy file picker in cases where saf file picker is not available
* fix missing file check logic in prepareSelectedDownload method (DownloadDialog.java)
2019-08-15 01:09:36 -03:00
kapodamy
950cf714d9 use legacy file picker in those cases where saf is not available 2019-08-14 22:15:42 -03:00
kapodamy
652184506b check for Storage Access Framework features
* creating files though saf
* picking folder though saf
2019-08-14 21:54:26 -03:00
Andrew
89f2cd6ec0 Merge branch 'dev' into patch-1 2019-08-14 17:39:57 +01:00
Roger
6457cac797 Merge branch 'dev' into patch-1 2019-08-14 11:42:46 -04:00
Christian Schabesberger
f66c2ba171 Merge pull request #2518 from Stypox/playlist-play-from-here
Customize "start here" actions in playlist item views
2019-08-14 15:01:37 +02:00
Christian Schabesberger
6133c97f45 Merge branch 'dev' into playlist-play-from-here 2019-08-14 14:53:06 +02:00
Christian Schabesberger
0dc71ce37a Merge pull request #2517 from Stypox/list-slowdown-fix
List slowdown fix
2019-08-14 14:51:18 +02:00
Stypox
c96a05a8f9 Customize "start here" actions in playlist item views
Now those actions start playing the whole playlist from the chosen stream, instead of playing only the chosen stream.
2019-08-14 14:17:05 +02:00
Stypox
c190dc4792 Fix annotation warnings in modified files 2019-08-14 13:11:44 +02:00
Stypox
ebf91d27c7 Clean up code for addItems() on ItemListAdapters. 2019-08-14 13:11:16 +02:00
Stypox
63301ee771 Remove "Trollolo" logs
They were probably left behind by accident after a debugging session.
2019-08-14 12:57:04 +02:00
Stypox
7da827a06a Fix annotation warnings 2019-08-14 12:55:17 +02:00
Stypox
00fc5217f5 Fix potential disposable leak in PlaylistAppendDialog 2019-08-14 12:54:17 +02:00
Stypox
04e725bb50 Fix some inspection warnings in modified files 2019-08-14 11:49:37 +02:00
Stypox
e6617ff8e8 Fix slowdowns in stream list views
Now the playback state of a stream is loaded only when needed (i.e. when the stream is visible), just as it is done with thumbnails.
Removed `StateObjectsListAdapter.java`, which used to load the state of every stream at list instantiation, generating slowdowns and freezes.
2019-08-14 11:42:39 +02:00
Roger
1b0a958436 Create FUNDING.yml 2019-08-13 22:10:04 -04:00
TobiGr
5053d470f6 Do not save playback position when watch history is disabled 2019-08-13 14:39:57 +02:00
TobiGr
8de5c53485 Fix typo in HistorySettinsFragment
Rename viewsHistroyClearKey to viewsHistoryClearKey
2019-08-13 14:25:47 +02:00
TobiGr
ec3ae7c7b8 Clean up string resources 2019-08-12 17:35:36 +02:00
TobiGr
c46af7d194 Merge branch 'weblate' into dev 2019-08-12 17:25:10 +02:00
Kowith Singkornkeeree
5254e85840 Added translation using Weblate (Thai) 2019-08-12 15:02:32 +02:00
Tobias Groza
5883f6e763 Merge pull request #2487 from kapodamy/buttons-hiding-fix-on-screen-off
fixup for #2149 (missing buttons)
2019-08-12 14:16:03 +02:00
Tobias Groza
c02383d7d9 Merge branch 'dev' into buttons-hiding-fix-on-screen-off 2019-08-12 13:57:02 +02:00
Christian Schabesberger
f98e5cc22d Merge pull request #2502 from Stypox/fix-player-resume
Fix player resume
2019-08-12 10:47:21 +02:00
Christian Schabesberger
9fbb61a744 make fastlane description better suted for fdroid 2019-08-11 23:18:56 +02:00
Stypox
5191907af0 Fix player resume 2019-08-11 22:10:05 +02:00
kapodamy
35a69b4b1d update download_menu.xml
use "ifRoom" and "always" in cases where is possible
2019-08-10 15:56:59 -03:00
Andrew
f947856a61 Revert last commit 2019-08-08 01:13:34 +00:00
Andrew
c4967532e4 Use commit from extractor pr 2019-08-08 01:07:51 +00:00
Andrew
7dc560e1f2 Merge branch 'dev' into patch-1 2019-08-08 00:29:16 +00:00
Andrew
ab03198ba6 Add debugging domain for main instance 2019-08-08 00:22:40 +00:00
yausername
a64f520644 fix item addition to list 2019-08-07 22:27:58 +05:30
yausername
5aced46345 remove controls animation/flicker 2019-08-07 22:27:58 +05:30
TobiGr
3cd485069d Fix playback position not being deleted on clearing watch history 2019-08-07 14:34:49 +02:00
Christian Schabesberger
fabb07bb28 fix import settings not working 2019-08-04 17:27:56 +02:00
kapodamy
2328ea6d07 dont hardcode the buttons 2019-08-03 12:44:55 -03:00
kapodamy
0375194e7d fix start/pause buttons disappear when screen goes off
* fix start/pause buttons disappear, issued by RecyclerView re-draw
* show start/pause buttons in pair to avoid confusions
2019-08-03 12:28:58 -03:00
kapodamy
5a6a6bcc78 clean-up: remove unused method 2019-08-03 12:28:58 -03:00
TobiGr
c8f475bba1 Add changelog for 0.17.0 2019-08-03 00:35:45 +02:00
TobiGr
31f3757880 Move on to version 0.17.0 (750) 2019-08-03 00:35:45 +02:00
Igor Nedoboy
a60a9bb144 Translated using Weblate (Russian)
Currently translated at 100.0% (451 of 451 strings)
2019-08-02 23:07:42 +02:00
Tobias Groza
21a90bb7ee Merge pull request #2486 from kapodamy/32k-issue-fix
Fix slow download speed
2019-08-02 22:23:34 +02:00
Andrew
6a8e38476f Add all (HTTP(S)) Invidious instances
Public Invidious instances from https://github.com/omarroth/invidious/wiki/invidious-instances have been added to the AndroidManifest.xml to allow opening of the public Invidious (not just `invidio.us`) links in NewPipe.
2019-08-02 18:26:13 +00:00
kapodamy
2f66913813 drop unused popup storage permission request 2019-08-02 01:07:37 -03:00
kapodamy
d9b042d9e3 socket leak fix
* fix socket leak in "DownloadRunnable"
* in "DownloadInitializer" close the HTTP body after doing range-request checks
* in "DownloadRunnableFallback" fix typo in comment
* in "DownloadDialog" fix regression, using one thread for audios instead of subtitles
2019-08-01 22:41:09 -03:00
Marc Riera
ef9044d933 Translated using Weblate (Catalan)
Currently translated at 98.4% (444 of 451 strings)
2019-08-01 19:47:13 +02:00
Bas Conrads
12c9dbf1bf Translated using Weblate (Esperanto)
Currently translated at 18.6% (84 of 451 strings)
2019-08-01 19:47:12 +02:00
Nenad
8cc8aa8693 Translated using Weblate (Serbian)
Currently translated at 50.1% (226 of 451 strings)
2019-08-01 19:47:09 +02:00
TobiGr
e529b16956 Merge branch 'weblate' into release_v0.17.0 2019-08-01 01:44:25 +02:00
TobiGr
ffe8d4b689 Update extractor version to fix video duration parsing failure 2019-07-31 18:35:46 +02:00
Tobias Groza
4e5a20ec45 Merge pull request #2368 from Stypox/menu-consistency
Make long-press menu consistent across views
2019-07-31 13:37:49 +02:00
Stypox
7c9ef58acd Fix crash when closing a not-yet-loaded popup. 2019-07-25 12:32:56 +02:00
Stypox
d076fe72cd Optimize imports in edited files 2019-07-25 11:47:38 +02:00
Stypox
25fbbfaf94 Rename action to defaultAction in StreamDialogEntry
To improve readability
2019-07-25 01:07:51 +02:00
Stypox
9df27f43de Ensure default actions cannot be overwritten permanently in StreamDialogEntry 2019-07-25 00:53:13 +02:00
Stypox
759e9846ad Remove ugly if-else-cascade in
Common actions and labels are now in a unique enum: StreamDialogEntry
If an action is not common to every long-press menu (e.g. delete) a custom action has to be provided using e.g. delete.setAction(...)
2019-07-25 00:44:12 +02:00
Stypox
3aeba7ca8a Merge branch 'dev' into menu-consistency 2019-07-24 17:21:45 +02:00
hatsunearu
2a44a091c8 Translated using Weblate (Korean)
Currently translated at 100.0% (451 of 451 strings)
2019-07-23 03:18:37 +02:00
JS Ahn
4c92aebc3c Translated using Weblate (Korean)
Currently translated at 100.0% (451 of 451 strings)
2019-07-23 03:16:54 +02:00
JS Ahn
d4ecd0dfab Translated using Weblate (Korean)
Currently translated at 100.0% (451 of 451 strings)
2019-07-23 03:15:50 +02:00
bluepencil
3f790d01fa Translated using Weblate (Korean)
Currently translated at 100.0% (451 of 451 strings)
2019-07-23 03:15:49 +02:00
Christian Schabesberger
e7b068ed8e Merge pull request #2203 from yausername/defaultTrending
added default kiosk
2019-07-22 23:31:14 +02:00
Christian Schabesberger
bd485937c4 Merge branch 'dev' into defaultTrending 2019-07-22 22:39:47 +02:00
Stypox
8edc332a4e Fix showing popup options with audio-only streams 2019-07-22 11:58:01 +02:00
Stypox
bb5028364b Complete merge after #2288: add resumePlayback to player calls.
`resumePlayback`'s value is `false` when the video is enqueued, `true` otherwise.
Also make the use of getContext() and getActivity() more consistant.
2019-07-22 10:28:53 +02:00
Stypox
ef070a4e0e Merge branch 'dev' into menu-consistency 2019-07-22 09:10:25 +02:00
Christian Schabesberger
6787d0224c Merge pull request #2453 from m0n1ker/issue-2240
Update play queue metadata
2019-07-21 16:14:02 +02:00
Christian Schabesberger
8a43e24095 Merge branch 'dev' into issue-2240 2019-07-21 16:07:32 +02:00
Christian Schabesberger
f879f549e4 Merge pull request #2440 from kapodamy/dl-bux-fix
fix downloads stuck at 99.9%
2019-07-21 16:04:52 +02:00
Christian Schabesberger
db55484163 Merge branch 'dev' into dl-bux-fix 2019-07-21 15:38:39 +02:00
Christian Schabesberger
4d8f66f28e Merge pull request #2444 from moneytoo/rotate
Handle (auto)rotation changes during activity lifecycle
2019-07-21 15:37:55 +02:00
Christian Schabesberger
7a44061fa3 Merge branch 'dev' into rotate 2019-07-21 15:12:41 +02:00
Christian Schabesberger
5d4bb42e39 Merge branch 'dev' into dl-bux-fix 2019-07-21 15:10:57 +02:00
Christian Schabesberger
3a6c22da5c update to latest dev extractor 2019-07-21 15:08:17 +02:00
Stypox
064f0e414a Merge branch 'dev' into menu-consistency 2019-07-21 11:11:06 +02:00
Mostafa Ahangarha
77db3cb6fa Translated using Weblate (Persian)
Currently translated at 70.7% (319 of 451 strings)
2019-07-18 18:05:12 +02:00
bluepencil
b83a1fd102 Translated using Weblate (Korean)
Currently translated at 100.0% (451 of 451 strings)
2019-07-16 08:03:42 +02:00
Igor Nedoboy
99c519c065 Translated using Weblate (Russian)
Currently translated at 100.0% (451 of 451 strings)
2019-07-13 21:00:45 +02:00
Allan Nordhøy
632e52b38d Translated using Weblate (Norwegian Bokmål)
Currently translated at 97.6% (440 of 451 strings)
2019-07-11 21:01:06 +02:00
Syver Stensholt
1b66ffac6c Translated using Weblate (Norwegian Bokmål)
Currently translated at 97.6% (440 of 451 strings)
2019-07-11 21:01:04 +02:00
Alan Nelson
ee9052ad3d Add title to additional metadata object 2019-07-11 00:48:28 -05:00
John Doe
550c74da77 Translated using Weblate (Croatian)
Currently translated at 100.0% (451 of 451 strings)
2019-07-10 13:01:11 +02:00
Alan Nelson
ccdd450283 Add current and total track numbers to metadata 2019-07-09 22:37:03 -05:00
Alan Nelson
224a607bc3 Fix Bluetooth AVRCP duration metadata 2019-07-09 22:34:18 -05:00
random r
8fcd23663c Translated using Weblate (Italian)
Currently translated at 100.0% (451 of 451 strings)
2019-07-09 11:00:59 +02:00
Tobias Groza
ad79a71fbd Merge pull request #2423 from Redirion/patch-2
Silence CheckForNewAppVersionTask
2019-07-07 21:08:01 +02:00
Tobias Groza
d862a59349 Merge branch 'dev' into patch-2 2019-07-07 20:39:26 +02:00
D D
2d6362dddb Translated using Weblate (Bulgarian)
Currently translated at 85.4% (385 of 451 strings)
2019-07-06 21:01:14 +02:00
Flo - Fan
ee3ec3a4ea Translated using Weblate (French)
Currently translated at 100.0% (451 of 451 strings)
2019-07-05 17:01:08 +02:00
THANOS SIOURDAKIS
daecfd97c2 Translated using Weblate (Greek)
Currently translated at 100.0% (451 of 451 strings)
2019-07-05 17:01:07 +02:00
Khaleel Jageer
200a81d536 Translated using Weblate (Tamil)
Currently translated at 33.7% (152 of 451 strings)
2019-07-05 17:01:07 +02:00
Marcel Dopita
8059ac89d3 Handle (auto)rotation changes during activity lifecycle
Fixes #1156
2019-07-04 07:30:01 +02:00
kapodamy
60f5f07dd6 commit (3 changes)
* re-write download segmenting logic (issue #).
* clean-up download threads handling.
* fix race-condition if "pause" option in download context menu was selected, in the transition from "pending" to "finished" state.
2019-07-02 21:07:21 -03:00
Osoitz
372d5ce413 Translated using Weblate (Basque)
Currently translated at 100.0% (451 of 451 strings)
2019-07-02 12:01:06 +02:00
Mehmetali
6f97819ca7 Translated using Weblate (Turkish)
Currently translated at 100.0% (451 of 451 strings)
2019-07-02 12:01:03 +02:00
JoC
2b2ee56712 Translated using Weblate (Spanish)
Currently translated at 100.0% (451 of 451 strings)
2019-06-28 10:01:02 +02:00
thami simo
3715326034 Translated using Weblate (Arabic)
Currently translated at 100.0% (451 of 451 strings)
2019-06-28 10:01:00 +02:00
Cenk YILDIZLI
6cbb8b1753 Translated using Weblate (Turkish)
Currently translated at 99.1% (447 of 451 strings)
2019-06-28 10:00:57 +02:00
Christian Schabesberger
806896ea05 Merge pull request #2295 from sherlockbeard/removeextra
removed the gema strings.
2019-06-27 14:29:42 +02:00
Redirion
fc8746e077 Update CheckForNewAppVersionTask.java 2019-06-26 18:37:04 +02:00
Christian Schabesberger
e11df5bb49 Merge branch 'dev' into removeextra 2019-06-26 15:42:47 +02:00
Redirion
37a9e98ebc Update CheckForNewAppVersionTask.java 2019-06-25 13:53:23 +02:00
Redirion
80b4975188 Update CheckForNewAppVersionTask.java 2019-06-25 13:47:16 +02:00
Redirion
c4ef40f4dc Removed tabs 2019-06-25 13:41:08 +02:00
Redirion
6a4bb6e3e1 Update CheckForNewAppVersionTask.java 2019-06-25 13:39:47 +02:00
Redirion
05ef926a7f Update CheckForNewAppVersionTask.java 2019-06-25 13:31:26 +02:00
Redirion
0007451735 Update CheckForNewAppVersionTask.java 2019-06-25 13:22:40 +02:00
Redirion
e599de038a Silence CheckForNewAppVersionTask
Closes #2421
2019-06-25 11:49:59 +02:00
Tobias Groza
61472a995f Merge pull request #2288 from nv95/playback_state_list
Playback positions in lists
2019-06-23 19:44:13 +02:00
Vasily
2a41802f36 Merge branch 'dev' into playback_state_list 2019-06-23 20:23:29 +03:00
gkhnblt
1d1cee17c3 Translated using Weblate (Turkish)
Currently translated at 98.0% (442 of 451 strings)
2019-06-23 19:00:19 +02:00
Michael Moroni
e99266f9d8 Translated using Weblate (Italian)
Currently translated at 100.0% (451 of 451 strings)
2019-06-21 14:00:36 +02:00
Eduardo Caron
1f2cd064f7 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (451 of 451 strings)
2019-06-21 14:00:35 +02:00
minsk21
9c2cf9eef7 Translated using Weblate (Belarusian)
Currently translated at 73.4% (331 of 451 strings)
2019-06-18 21:02:47 +02:00
Tobias Groza
38b0b79644 Merge pull request #2149 from kapodamy/ps-branch
Downloader fixes
2019-06-17 22:53:11 +02:00
JoC
5252834075 Translated using Weblate (Spanish)
Currently translated at 100.0% (451 of 451 strings)
2019-06-15 19:53:20 +02:00
kapodamy
162df5eb6c Merge branch 'dev' into ps-branch 2019-06-14 12:55:49 -03:00
kapodamy
ac5e2e0532 bugs fixes
* fix storage warning dialogs created on invalid contexts
* implement mkdirs in StoredDirectoryHelper
2019-06-14 12:19:50 -03:00
Stypox
f0ba6afbdf Merge branch 'dev' into menu-consistency 2019-06-14 09:40:40 +02:00
Hosted Weblate
04a5f43472 Merge branch 'origin/dev' into Weblate. 2019-06-13 14:30:35 +02:00
Allan Nordhøy
a15ef4b7ce Translated using Weblate (Norwegian Bokmål)
Currently translated at 94.9% (428 of 451 strings)
2019-06-13 14:30:34 +02:00
Jeff Huang
f1f9147433 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (451 of 451 strings)
2019-06-13 14:30:33 +02:00
Nathan Follens
3c0d7de377 Translated using Weblate (Flemish)
Currently translated at 100.0% (451 of 451 strings)
2019-06-13 14:30:31 +02:00
Arnaud Jacquemin
2a57d74f1a Translated using Weblate (French)
Currently translated at 100.0% (451 of 451 strings)
2019-06-13 14:30:29 +02:00
Florian
79717859b3 Translated using Weblate (French)
Currently translated at 100.0% (451 of 451 strings)
2019-06-13 14:30:28 +02:00
Prashant Shahi
be423939ed Translated using Weblate (Nepali)
Currently translated at 6.0% (27 of 451 strings)
2019-06-13 14:30:27 +02:00
Nathan Follens
086cceb271 Translated using Weblate (Dutch)
Currently translated at 100.0% (451 of 451 strings)
2019-06-13 14:30:21 +02:00
zmni
a14033afb7 Translated using Weblate (Indonesian)
Currently translated at 99.8% (450 of 451 strings)
2019-06-13 14:30:20 +02:00
Rex_sa
cc89a342ed Translated using Weblate (Arabic)
Currently translated at 100.0% (451 of 451 strings)
2019-06-13 14:30:18 +02:00
ButterflyOfFire
25c3669564 Translated using Weblate (Arabic)
Currently translated at 100.0% (451 of 451 strings)
2019-06-13 14:30:17 +02:00
Michael Moroni
21eff0b2ec Translated using Weblate (Italian)
Currently translated at 98.2% (443 of 451 strings)
2019-06-13 14:30:16 +02:00
pjammo
472fd72c82 Translated using Weblate (Italian)
Currently translated at 98.2% (443 of 451 strings)
2019-06-13 14:30:15 +02:00
WaldiS
429a9a42d3 Translated using Weblate (Polish)
Currently translated at 100.0% (451 of 451 strings)
2019-06-13 14:30:13 +02:00
Yaron Shahrabani
90c525e99a Translated using Weblate (Hebrew)
Currently translated at 100.0% (451 of 451 strings)
2019-06-13 14:30:12 +02:00
Stjepan
196117998a Translated using Weblate (Croatian)
Currently translated at 99.3% (448 of 451 strings)
2019-06-13 14:30:10 +02:00
ssantos
630cbc77a8 Translated using Weblate (Portuguese)
Currently translated at 100.0% (451 of 451 strings)
2019-06-13 14:30:09 +02:00
Marc Riera
b6e4afe321 Translated using Weblate (Catalan)
Currently translated at 97.1% (438 of 451 strings)
2019-06-13 14:30:06 +02:00
naofum
59085ff8c8 Translated using Weblate (Japanese)
Currently translated at 100.0% (451 of 451 strings)
2019-06-13 14:30:04 +02:00
AB
a4274c6301 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (451 of 451 strings)
2019-06-13 14:30:02 +02:00
THANOS SIOURDAKIS
b4ef44b343 Translated using Weblate (Greek)
Currently translated at 100.0% (451 of 451 strings)
2019-06-13 14:30:01 +02:00
postsorino
08bc97582b Translated using Weblate (Greek)
Currently translated at 100.0% (451 of 451 strings)
2019-06-13 14:30:00 +02:00
gabriellluz
3952c88510 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (451 of 451 strings)
2019-06-13 14:29:59 +02:00
Lucas Ayala
b1f27b9da7 Translated using Weblate (Spanish)
Currently translated at 100.0% (451 of 451 strings)
2019-06-13 14:29:55 +02:00
Tobias Groza
171b258d5c Merge pull request #2394 from Redirion/patch-1
Fixed selected subtitle track name not being shown
2019-06-12 22:50:34 +02:00
Redirion
af971b6a19 Fixed selected subtitle stream not being shown
closes #2393
this ammends my obviously incomplete fix in PR #2311.

This is just an UI issue. Subtitle track selection works, it just shows "No Captions" unfortunately.
2019-06-12 14:44:36 +02:00
Karel S
7ca026393b Translated using Weblate (Czech)
Currently translated at 100.0% (451 of 451 strings)
2019-06-12 10:52:28 +02:00
Vojtěch Šamla
f8784ae3c7 Translated using Weblate (Czech)
Currently translated at 100.0% (451 of 451 strings)
2019-06-12 10:52:27 +02:00
ssantos
3ddc3acf4c Translated using Weblate (German)
Currently translated at 100.0% (451 of 451 strings)
2019-06-06 08:57:12 +02:00
nautilusx
ff430f5e33 Translated using Weblate (German)
Currently translated at 100.0% (451 of 451 strings)
2019-06-06 08:57:12 +02:00
Prashant Shahi
daf2890161 Added translation using Weblate (Nepali) 2019-06-05 17:16:25 +02:00
Igor Nedoboy
4ca639323d Translated using Weblate (Russian)
Currently translated at 100.0% (451 of 451 strings)
2019-06-05 00:59:48 +02:00
Igor Nedoboy
a92bf155a3 Translated using Weblate (Russian)
Currently translated at 100.0% (451 of 451 strings)
2019-06-05 00:48:25 +02:00
Igor Nedoboy
d153772eb2 Translated using Weblate (Russian)
Currently translated at 100.0% (451 of 451 strings)
2019-06-05 00:37:18 +02:00
kapodamy
cdc8fe86ce amend rebase
resolve inconsistency in string.xml files
2019-06-04 15:45:28 -03:00
Hosted Weblate
4844037ce9 Merge branch 'origin/dev' into Weblate. 2019-06-04 13:40:03 +02:00
Jeff Huang
691c1e1a37 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (443 of 443 strings)
2019-06-04 13:40:03 +02:00
Jazz
bd55b91a86 Translated using Weblate (French)
Currently translated at 99.8% (442 of 443 strings)
2019-06-04 13:40:02 +02:00
Eduardo Serra
8842f53696 Translated using Weblate (Spanish)
Currently translated at 100.0% (443 of 443 strings)
2019-06-04 13:40:02 +02:00
ButterflyOfFire
ffed9f6116 Translated using Weblate (Arabic)
Currently translated at 100.0% (443 of 443 strings)
2019-06-04 13:40:01 +02:00
pjammo
50e8f45601 Translated using Weblate (Italian)
Currently translated at 100.0% (443 of 443 strings)
2019-06-04 13:40:00 +02:00
WaldiS
8cbfe9e6cf Translated using Weblate (Polish)
Currently translated at 100.0% (443 of 443 strings)
2019-06-04 13:40:00 +02:00
Karel S
99ad3dc292 Translated using Weblate (Czech)
Currently translated at 99.8% (442 of 443 strings)
2019-06-04 13:40:00 +02:00
monolifed
6908355d38 Translated using Weblate (Turkish)
Currently translated at 100.0% (443 of 443 strings)
2019-06-04 13:39:56 +02:00
kapodamy
7b948f83c3 Space reserving tweaks for huge video resolutions
* improve space reserving, allows write better 4K/8K video data
* do not use cache dirs in the muxers, Android can force close NewPipe if the device is running out of storage. Is a aggressive cache cleaning >:/
* (for devs) webm & mkv are the same thing
* calculate the final file size inside of the mission, instead getting from the UI
* simplify ps algorithms constructors
* [missing old commit message] simplify the loading of pending downloads
2019-06-03 18:26:26 -03:00
kapodamy
34b2b96158 Simplify the storage APIs use
* use Java I/O (classic way) on older android versions
* use Storage Access Framework on newer android versions (Android Lollipop or later)
* both changes have the external SD Card write permission
* add option to ask the save path on each download
* warn the user if the save paths are not defined, this only happens on the first NewPipe run (Android Lollipop or later)
2019-06-03 18:26:24 -03:00
kapodamy
d1573a0a6e misc changes
* implement socket timeout error
* use 128k buffer size for copy
* use NewPipe HTTP user agent in the downloads
* automatically recover downloads with network errors that are queued
2019-06-03 18:25:43 -03:00
kapodamy
16d6bda85d Webm muxer fixes and strings.xml changes
* replace "In queue" to "Pending" in the downloads header to avoid confusions (all languages)
* use 29bits Clusters size to support huge video resolutions (fixes #2291) (WebmWriter.java)
* add missing changes to WebmMuxer.java (i forget select the audio track)
2019-06-03 18:24:49 -03:00
kapodamy
4b3eb2ece5 Forget the download save path if the storage API is changed 2019-06-03 18:19:20 -03:00
kapodamy
1089de6321 Add confirm dialog before clear the finished download list 2019-06-03 18:19:18 -03:00
kapodamy
d00dc798f4 more SAF implementation
* full support for Directory API (Android Lollipop or later)
* best effort to handle any kind errors (missing file, revoked permissions, etc) and recover the download
* implemented directory choosing
* fix download database version upgrading
* misc. cleanup
* do not release permission on the old save path (if the user change the download directory) under SAF api
2019-06-03 18:18:20 -03:00
kapodamy
f6b32823ba Implement Storage Access Framework
* re-work finished mission database
* re-work DownloadMission and bump it Serializable version
* keep the classic Java IO API
* SAF Tree API support on Android Lollipop or higher
* add wrapper for SAF stream opening
* implement Closeable in SharpStream to replace the dispose() method

* do required changes for this API:
** remove any file creation logic from DownloadInitializer
** make PostProcessing Serializable and reduce the number of iterations
** update all strings.xml files
** storage helpers: StoredDirectoryHelper & StoredFileHelper
** best effort to handle any kind of SAF errors/exceptions
2019-06-03 18:16:41 -03:00
kapodamy
9e34fee58c New MP4 muxer + Queue changes + Storage fixes
Main changes:
* correctly check the available space (CircularFile.java)
* misc cleanup (CircularFile.java)
* use the "Error Reporter" for non-http errors
* rewrite network state checking and add better support for API 21 (Lollipop) or higher
* implement "metered networks"
* add buttons in "Downloads" activity to start/pause all pending downloads, ignoring the queue flag or if the network is "metered"
* add workaround for VPN connections and/or network switching. Example: switching WiFi to 3G
* rewrite DataReader ¡Webm muxer is now 57% more faster!
* rewrite CircularFile, use file buffers instead of memory buffers. Less troubles in low-end devices
* fix missing offset for KaxCluster (WebMWriter.java), manifested as no thumbnails on file explorers

Download queue:
* remember queue status, unless the user pause the download (un-queue)
* semi-automatic downloads, between networks. Effective if the user create a new download or the downloads activity is starts
* allow enqueue failed downloads
* new option, queue limit, enabled by default. Used to allow one or multiple downloads at same time

Miscellaneous:
* fix crash while selecting details/error menu (mistake on MissionFragment.java)
* misc serialize changes (DownloadMission.java)
* minor UI tweaks
* allow overwrite paused downloads
* fix wrong icons for grid/list button in downloads
* add share option
* implement #2006
* correct misspelled word in strings.xml (es) (cmn)
* fix MissionAdapter crash during device shutdown

New Mp4Muxer + required changes:
* new mp4 muxer (from dash only) with this, muxing on Android 7 is possible now!!!
* re-work in SharpStream
* drop mp4 dash muxer
* misc changes: add warning in SecondaryStreamHelper.java,
* strip m4a DASH files to normal m4a format (youtube only)

Fix storage issues:
* warn to the user if is choosing a "read only" download directory (for external SD Cards), useless is rooted :)
* "write proof" allow post-processing resuming only if the device ran out of space
* implement "insufficient storage" error for downloads
2019-06-03 18:09:43 -03:00
Tobias Groza
1684a2110c Update Extractor 2019-06-03 22:06:58 +02:00
Tobias Groza
5e00e34552 Merge remote-tracking branch 'Weblate/dev' into dev 2019-06-03 22:04:36 +02:00
Yaron Shahrabani
ce204eba62 Translated using Weblate (Hebrew)
Currently translated at 100.0% (443 of 443 strings)
2019-06-02 12:48:16 +02:00
Yaron Shahrabani
c7cb652322 Translated using Weblate (Hebrew)
Currently translated at 99.8% (442 of 443 strings)
2019-06-02 12:44:09 +02:00
Yaron Shahrabani
f8ccc3128e Translated using Weblate (Hebrew)
Currently translated at 99.8% (442 of 443 strings)
2019-06-02 12:44:08 +02:00
bob mar
4a8baaef45 Translated using Weblate (Hebrew)
Currently translated at 99.8% (442 of 443 strings)
2019-06-02 12:44:08 +02:00
artik banana
a9f3939c83 Translated using Weblate (Hebrew)
Currently translated at 99.8% (442 of 443 strings)
2019-06-02 12:27:18 +02:00
Joseph Kim
d8cb950248 Translated using Weblate (Korean)
Currently translated at 100.0% (443 of 443 strings)
2019-06-02 12:27:07 +02:00
AB
aefc51db4b Translated using Weblate (Ukrainian)
Currently translated at 100.0% (443 of 443 strings)
2019-06-02 12:27:00 +02:00
artik banana
fb18ea7ff8 Translated using Weblate (Hebrew)
Currently translated at 99.8% (442 of 443 strings)
2019-06-02 12:26:58 +02:00
bob mar
407c61e212 Translated using Weblate (Hebrew)
Currently translated at 99.8% (442 of 443 strings)
2019-06-02 12:26:58 +02:00
ssantos
d8e6ad48ca Translated using Weblate (Portuguese)
Currently translated at 100.0% (443 of 443 strings)
2019-06-02 02:18:34 +02:00
yunna
bd42f4188f Translated using Weblate (Japanese)
Currently translated at 99.8% (442 of 443 strings)
2019-06-02 02:18:34 +02:00
yunna
f766f383ea Translated using Weblate (English)
Currently translated at 100.0% (443 of 443 strings)
2019-06-02 02:18:28 +02:00
ssantos
1a9922d790 Translated using Weblate (German)
Currently translated at 100.0% (443 of 443 strings)
2019-06-02 02:18:24 +02:00
Tobias Groza
6213623431 Merge pull request #2235 from TeamNewPipe/readme-services
Add supported services section to readme
2019-06-02 02:03:14 +02:00
Tobias Groza
2809ee7a3e Merge branch 'dev' into readme-services 2019-06-02 02:02:44 +02:00
Tobias Groza
281cae7a18 Merge branch 'master' into dev 2019-05-31 23:46:28 +02:00
mohammadmdp
e1ead9d2ef Translated using Weblate (Persian)
Currently translated at 58.9% (261 of 443 strings)
2019-05-31 11:24:47 +02:00
Karel S
359a9a96d6 Translated using Weblate (Czech)
Currently translated at 99.8% (442 of 443 strings)
2019-05-31 11:24:44 +02:00
Stypox
b6cfb8a3dc Remove dupliacte direct_on_background string
start_here_on_background has the same meaning

start_here_on_main is now unused, but I left it there so that if it ever becomes useful again, it is ready to be used.
2019-05-30 15:30:13 +02:00
Stypox
6f028ecb19 Remove unused imports from modified files 2019-05-29 20:45:05 +02:00
Stypox
8695466690 Make subscription long-press menu consistant in local sub list
Inverted unsubscribe with share, since share has always been put after content-specific actions.
2019-05-29 20:39:17 +02:00
Stypox
bdb1be9967 Remove useless overrides of showStreamDialog
They were exactly the same as the base class function
2019-05-29 20:25:44 +02:00
Cipisek Rumcajsu
9395df4cc3 Translated using Weblate (Czech)
Currently translated at 90.3% (400 of 443 strings)
2019-05-29 18:08:08 +02:00
Karel S
93edb333d4 Translated using Weblate (Czech)
Currently translated at 90.3% (400 of 443 strings)
2019-05-29 18:08:08 +02:00
Stypox
30eeef46c2 Removed unused showStreamDialog from VideoDetailFragment
VideoDetailFragment already borrows a consistant menu from the stream list it holds.
2019-05-29 16:25:23 +02:00
Stypox
8b584f3922 Make long-press menu consistent across views: fix #2354
Also made the code that creates the menus consistent across files.
2019-05-29 16:22:01 +02:00
sherlockbeard
43b859f778 Merge branch 'dev' into removeextra 2019-05-07 13:59:32 +05:30
sherlockbeard
d1bd7f695f Update strings.xml 2019-05-07 13:57:31 +05:30
Vasiliy
312e1378d3 Fix tablet ui 2019-05-06 19:16:39 +03:00
Vasiliy
93f2518159 Animate states changed 2019-04-27 22:27:08 +03:00
Vasiliy
273f731dd5 Refactor adapter 2019-04-27 21:23:52 +03:00
Vasiliy
c7cd9e86ac Option to disable states indicators 2019-04-27 19:04:13 +03:00
Vasiliy
41fb6f5464 Update states in lists 2019-04-27 18:12:00 +03:00
Vasiliy
03b1a8bd41 Merge branch 'dev' into playback_state_list 2019-04-27 17:37:43 +03:00
sherlock
1edfa78a05 removed the gena strings. 2019-04-17 16:45:40 +05:30
Vasiliy
f47c5e53b1 Merge branch 'playback_resume_v2' into playback_state_list 2019-04-15 22:19:54 +03:00
Vasiliy
a48cbc6971 Show streams states for local lists 2019-04-15 22:18:24 +03:00
Vasiliy
73be8cf074 Base implementation of showing playback positions in lists 2019-04-15 21:37:36 +03:00
Vasiliy
002a1412cb Fix scrolling details 2019-04-15 21:22:31 +03:00
Vasiliy
4e1423d224 Implement playback state management 2019-04-13 13:34:36 +03:00
TobiGr
9bcccc87e6 Update README
Add supported services section
Move comment support
2019-03-26 23:36:12 +01:00
Ritvik Saraf
76f7165462 Merge remote-tracking branch 'upstream/dev' into defaultTrending 2019-03-12 06:17:21 +05:30
Ritvik Saraf
fdf0d8e9c8 fixed memory leak 2019-03-12 06:07:56 +05:30
Ritvik Saraf
369fd95e2b skip tests, fix later 2019-03-11 06:27:18 +05:30
Ritvik Saraf
e242adec66 updated extractor 2019-03-11 03:16:17 +05:30
Ritvik Saraf
58e562f7d4 added default kiosk 2019-03-11 03:08:30 +05:30
205 changed files with 10550 additions and 6044 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
liberapay: TeamNewPipe

View File

@@ -66,15 +66,22 @@ NewPipe does not use any Google framework libraries, nor the YouTube API. Websit
* Enqueue videos
* Local playlists
* Subtitles
* Multi-service support (e.g. SoundCloud \[beta\])
* Livestream support
* Show comments
### Coming Features
* Cast to UPnP and Cast
* Show comments
* … and many more
### Supported Services
NewPipe supports multiple services. Our [docs](https://teamnewpipe.github.io/documentation/) provide more info on how a new service can be added to the app and the extractor. Please get in touch with us if you intend to add a new one. Currently supported services are:
* YouTube
* SoundCloud \[beta\]
* media.ccc.de \[beta\]
## Updates
When a change to the NewPipe code occurs (due to either adding features or bug fixing), eventually a release will occur. These are in the format x.xx.x . In order to get this new version, you can:
* 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.

View File

@@ -8,8 +8,8 @@ android {
applicationId "org.schabi.newpipe"
minSdkVersion 19
targetSdkVersion 28
versionCode 740
versionName "0.16.2"
versionCode 780
versionName "0.17.3"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
@@ -57,8 +57,7 @@ dependencies {
exclude module: 'support-annotations'
})
implementation 'com.github.TeamNewPipe:NewPipeExtractor:2ac713e'
implementation 'com.github.teamnewpipe:NewPipeExtractor:6d504e08836b0b'
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.23.0'

View File

@@ -228,7 +228,20 @@
<data android:scheme="http"/>
<data android:scheme="https"/>
<data android:host="invidio.us"/>
<data android:host="dev.invidio.us"/>
<data android:host="www.invidio.us"/>
<data android:host="invidious.snopyta.org"/>
<data android:host="de.invidious.snopyta.org"/>
<data android:host="fi.invidious.snopyta.org"/>
<data android:host="vid.wxzm.sx"/>
<data android:host="invidious.kabi.tk"/>
<data android:host="invidiou.sh"/>
<data android:host="www.invidiou.sh"/>
<data android:host="no.invidiou.sh"/>
<data android:host="invidious.enkirton.net"/>
<data android:host="tube.poal.co"/>
<data android:host="invidious.13ad.de"/>
<data android:host="yt.elukerio.org"/>
<!-- video prefix -->
<data android:pathPrefix="/embed/"/>
<data android:pathPrefix="/watch"/>

View File

@@ -14,6 +14,7 @@ import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
@@ -47,6 +48,8 @@ import okhttp3.Response;
*/
public class CheckForNewAppVersionTask extends AsyncTask<Void, Void, String> {
private static final boolean DEBUG = MainActivity.DEBUG;
private static final String TAG = CheckForNewAppVersionTask.class.getSimpleName();
private static final Application app = App.getApp();
private static final String GITHUB_APK_SHA1 = "B0:2E:90:7C:1C:D6:FC:57:C3:35:F0:88:D0:8F:50:5F:94:E4:D2:15";
private static final String newPipeApiUrl = "https://newpipe.schabi.org/api/data.json";
@@ -90,9 +93,8 @@ public class CheckForNewAppVersionTask extends AsyncTask<Void, Void, String> {
Response response = client.newCall(request).execute();
return response.body().string();
} catch (IOException ex) {
ErrorActivity.reportError(app, ex, null, null,
ErrorActivity.ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
"app update API fail", R.string.app_ui_crash));
// connectivity problems, do not alarm user and fail silently
if (DEBUG) Log.w(TAG, Log.getStackTraceString(ex));
}
return null;
@@ -117,9 +119,8 @@ public class CheckForNewAppVersionTask extends AsyncTask<Void, Void, String> {
compareAppVersionAndShowNotification(versionName, apkLocationUrl, versionCode);
} catch (JSONException ex) {
ErrorActivity.reportError(app, ex, null, null,
ErrorActivity.ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
"could not parse app update JSON data", R.string.app_ui_crash));
// connectivity problems, do not alarm user and fail silently
if (DEBUG) Log.w(TAG, Log.getStackTraceString(ex));
}
}
}

View File

@@ -164,7 +164,7 @@ public class Downloader implements org.schabi.newpipe.extractor.Downloader {
final ResponseBody body = response.body();
if (response.code() == 429) {
throw new ReCaptchaException("reCaptcha Challenge requested");
throw new ReCaptchaException("reCaptcha Challenge requested", siteUrl);
}
if (body == null) {
@@ -214,7 +214,7 @@ public class Downloader implements org.schabi.newpipe.extractor.Downloader {
final ResponseBody body = response.body();
if (response.code() == 429) {
throw new ReCaptchaException("reCaptcha Challenge requested");
throw new ReCaptchaException("reCaptcha Challenge requested", siteUrl);
}
if (body == null) {
@@ -268,7 +268,7 @@ public class Downloader implements org.schabi.newpipe.extractor.Downloader {
final ResponseBody body = response.body();
if (response.code() == 429) {
throw new ReCaptchaException("reCaptcha Challenge requested");
throw new ReCaptchaException("reCaptcha Challenge requested", siteUrl);
}
if (body == null) {

View File

@@ -37,15 +37,24 @@ import android.webkit.WebViewClient;
*/
public class ReCaptchaActivity extends AppCompatActivity {
public static final int RECAPTCHA_REQUEST = 10;
public static final String RECAPTCHA_URL_EXTRA = "recaptcha_url_extra";
public static final String TAG = ReCaptchaActivity.class.toString();
public static final String YT_URL = "https://www.youtube.com";
private String url;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recaptcha);
url = getIntent().getStringExtra(RECAPTCHA_URL_EXTRA);
if (url == null || url.isEmpty()) {
url = YT_URL;
}
// Set return to Cancel by default
setResult(RESULT_CANCELED);
@@ -73,15 +82,12 @@ public class ReCaptchaActivity extends AppCompatActivity {
myWebView.clearHistory();
android.webkit.CookieManager cookieManager = CookieManager.getInstance();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
cookieManager.removeAllCookies(new ValueCallback<Boolean>() {
@Override
public void onReceiveValue(Boolean aBoolean) {}
});
cookieManager.removeAllCookies(aBoolean -> {});
} else {
cookieManager.removeAllCookie();
}
myWebView.loadUrl(YT_URL);
myWebView.loadUrl(url);
}
private class ReCaptchaWebViewClient extends WebViewClient {

View File

@@ -74,10 +74,13 @@ import static org.schabi.newpipe.util.ThemeHelper.resolveResourceIdFromAttr;
*/
public class RouterActivity extends AppCompatActivity {
@State protected int currentServiceId = -1;
@State
protected int currentServiceId = -1;
private StreamingService currentService;
@State protected LinkType currentLinkType;
@State protected int selectedRadioPosition = -1;
@State
protected LinkType currentLinkType;
@State
protected int selectedRadioPosition = -1;
protected int selectedPreviously = -1;
protected String currentUrl;
@@ -257,7 +260,7 @@ public class RouterActivity extends AppCompatActivity {
.setNegativeButton(R.string.just_once, dialogButtonsClickListener)
.setPositiveButton(R.string.always, dialogButtonsClickListener)
.setOnDismissListener((dialog) -> {
if(!selectionIsDownload) finish();
if (!selectionIsDownload) finish();
})
.create();
@@ -358,13 +361,13 @@ public class RouterActivity extends AppCompatActivity {
positiveButton.setEnabled(state);
}
private void handleText(){
private void handleText() {
String searchString = getIntent().getStringExtra(Intent.EXTRA_TEXT);
int serviceId = getIntent().getIntExtra(Constants.KEY_SERVICE_ID, 0);
Intent intent = new Intent(getThemeWrapperContext(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
NavigationHelper.openSearch(getThemeWrapperContext(),serviceId,searchString);
NavigationHelper.openSearch(getThemeWrapperContext(), serviceId, searchString);
}
private void handleChoice(final String selectedChoiceKey) {
@@ -397,7 +400,7 @@ public class RouterActivity extends AppCompatActivity {
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(intent -> {
if(!internalRoute){
if (!internalRoute) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
}
@@ -447,8 +450,8 @@ public class RouterActivity extends AppCompatActivity {
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
for (int i: grantResults){
if (i == PackageManager.PERMISSION_DENIED){
for (int i : grantResults) {
if (i == PackageManager.PERMISSION_DENIED) {
finish();
return;
}
@@ -460,7 +463,8 @@ public class RouterActivity extends AppCompatActivity {
private static class AdapterChoiceItem {
final String description, key;
@DrawableRes final int icon;
@DrawableRes
final int icon;
AdapterChoiceItem(String key, String description, int icon) {
this.description = description;
@@ -558,7 +562,8 @@ public class RouterActivity extends AppCompatActivity {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean isExtVideoEnabled = preferences.getBoolean(getString(R.string.use_external_video_player_key), false);
boolean isExtAudioEnabled = preferences.getBoolean(getString(R.string.use_external_audio_player_key), false);;
boolean isExtAudioEnabled = preferences.getBoolean(getString(R.string.use_external_audio_player_key), false);
;
PlayQueue playQueue;
String playerChoice = choice.playerChoice;
@@ -574,7 +579,7 @@ public class RouterActivity extends AppCompatActivity {
playQueue = new SinglePlayQueue((StreamInfo) info);
if (playerChoice.equals(videoPlayerKey)) {
NavigationHelper.playOnMainPlayer(this, playQueue);
NavigationHelper.playOnMainPlayer(this, playQueue, true);
} else if (playerChoice.equals(backgroundPlayerKey)) {
NavigationHelper.enqueueOnBackgroundPlayer(this, playQueue, true);
} else if (playerChoice.equals(popupPlayerKey)) {
@@ -587,11 +592,11 @@ public class RouterActivity extends AppCompatActivity {
playQueue = info instanceof ChannelInfo ? new ChannelPlayQueue((ChannelInfo) info) : new PlaylistPlayQueue((PlaylistInfo) info);
if (playerChoice.equals(videoPlayerKey)) {
NavigationHelper.playOnMainPlayer(this, playQueue);
NavigationHelper.playOnMainPlayer(this, playQueue, true);
} else if (playerChoice.equals(backgroundPlayerKey)) {
NavigationHelper.playOnBackgroundPlayer(this, playQueue);
NavigationHelper.playOnBackgroundPlayer(this, playQueue, true);
} else if (playerChoice.equals(popupPlayerKey)) {
NavigationHelper.playOnPopupPlayer(this, playQueue);
NavigationHelper.playOnPopupPlayer(this, playQueue, true);
}
}
};

View File

@@ -3,15 +3,24 @@ package org.schabi.newpipe.database;
import android.arch.persistence.db.SupportSQLiteDatabase;
import android.arch.persistence.room.migration.Migration;
import android.support.annotation.NonNull;
import android.util.Log;
import org.schabi.newpipe.BuildConfig;
public class Migrations {
public static final int DB_VER_11_0 = 1;
public static final int DB_VER_12_0 = 2;
public static final boolean DEBUG = !BuildConfig.BUILD_TYPE.equals("release");
private static final String TAG = Migrations.class.getName();
public static final Migration MIGRATION_11_12 = new Migration(DB_VER_11_0, DB_VER_12_0) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
if(DEBUG) {
Log.d(TAG, "Start migrating database");
}
/*
* Unfortunately these queries must be hardcoded due to the possibility of
* schema and names changing at a later date, thus invalidating the older migration
@@ -56,6 +65,10 @@ public class Migrations {
"ORDER BY creation_date DESC");
database.execSQL("DROP TABLE IF EXISTS watch_history");
if(DEBUG) {
Log.d(TAG, "Stop migrating database");
}
}
};
}

View File

@@ -50,6 +50,11 @@ public abstract class StreamHistoryDAO implements HistoryDAO<StreamHistoryEntity
" ORDER BY " + STREAM_ACCESS_DATE + " DESC")
public abstract Flowable<List<StreamHistoryEntry>> getHistory();
@Query("SELECT * FROM " + STREAM_HISTORY_TABLE + " WHERE " + JOIN_STREAM_ID +
" = :streamId ORDER BY " + STREAM_ACCESS_DATE + " DESC LIMIT 1")
@Nullable
public abstract StreamHistoryEntity getLatestEntry(final long streamId);
@Query("DELETE FROM " + STREAM_HISTORY_TABLE + " WHERE " + JOIN_STREAM_ID + " = :streamId")
public abstract int deleteStreamHistory(final long streamId);

View File

@@ -4,6 +4,9 @@ package org.schabi.newpipe.database.stream.model;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.ForeignKey;
import android.support.annotation.Nullable;
import java.util.concurrent.TimeUnit;
import static android.arch.persistence.room.ForeignKey.CASCADE;
import static org.schabi.newpipe.database.stream.model.StreamStateEntity.JOIN_STREAM_ID;
@@ -22,6 +25,12 @@ public class StreamStateEntity {
final public static String JOIN_STREAM_ID = "stream_id";
final public static String STREAM_PROGRESS_TIME = "progress_time";
/** Playback state will not be saved, if playback time less than this threshold */
private static final int PLAYBACK_SAVE_THRESHOLD_START_SECONDS = 5;
/** Playback state will not be saved, if time left less than this threshold */
private static final int PLAYBACK_SAVE_THRESHOLD_END_SECONDS = 10;
@ColumnInfo(name = JOIN_STREAM_ID)
private long streamUid;
@@ -48,4 +57,18 @@ public class StreamStateEntity {
public void setProgressTime(long progressTime) {
this.progressTime = progressTime;
}
public boolean isValid(int durationInSeconds) {
final int seconds = (int) TimeUnit.MILLISECONDS.toSeconds(progressTime);
return seconds > PLAYBACK_SAVE_THRESHOLD_START_SECONDS
&& seconds < durationInSeconds - PLAYBACK_SAVE_THRESHOLD_END_SECONDS;
}
@Override
public boolean equals(@Nullable Object obj) {
if (obj instanceof StreamStateEntity) {
return ((StreamStateEntity) obj).streamUid == streamUid
&& ((StreamStateEntity) obj).progressTime == progressTime;
} else return false;
}
}

View File

@@ -55,12 +55,13 @@ public class DownloadActivity extends AppCompatActivity {
private void updateFragments() {
MissionsFragment fragment = new MissionsFragment();
getFragmentManager().beginTransaction()
getSupportFragmentManager().beginTransaction()
.replace(R.id.frame, fragment, MISSIONS_FRAGMENT_TAG)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
@@ -86,9 +87,4 @@ public class DownloadActivity extends AppCompatActivity {
return super.onOptionsItemSelected(item);
}
}
@Override
public void onRestoreInstanceState(Bundle inState){
super.onRestoreInstanceState(inState);
}
}

View File

@@ -180,7 +180,7 @@ public abstract class BaseStateFragment<I> extends BaseFragment implements ViewC
}
if (exception instanceof ReCaptchaException) {
onReCaptchaException();
onReCaptchaException((ReCaptchaException) exception);
return true;
} else if (exception instanceof IOException) {
showError(getString(R.string.network_error), true);
@@ -190,11 +190,13 @@ public abstract class BaseStateFragment<I> extends BaseFragment implements ViewC
return false;
}
public void onReCaptchaException() {
public void onReCaptchaException(ReCaptchaException exception) {
if (DEBUG) Log.d(TAG, "onReCaptchaException() called");
Toast.makeText(activity, R.string.recaptcha_request_toast, Toast.LENGTH_LONG).show();
// Starting ReCaptcha Challenge Activity
startActivityForResult(new Intent(activity, ReCaptchaActivity.class), ReCaptchaActivity.RECAPTCHA_REQUEST);
Intent intent = new Intent(activity, ReCaptchaActivity.class);
intent.putExtra(ReCaptchaActivity.RECAPTCHA_URL_EXTRA, exception.getUrl());
startActivityForResult(intent, ReCaptchaActivity.RECAPTCHA_REQUEST);
showError(getString(R.string.recaptcha_request_toast), false);
}

View File

@@ -50,6 +50,8 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
destroyOldFragments();
tabsManager = TabsManager.getManager(activity);
tabsManager.setSavedTabsListener(() -> {
if (DEBUG) {
@@ -63,6 +65,17 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
});
}
private void destroyOldFragments() {
for (Fragment fragment : getChildFragmentManager().getFragments()) {
if (fragment != null) {
getChildFragmentManager()
.beginTransaction()
.remove(fragment)
.commitNowAllowingStateLoss();
}
}
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false);
@@ -98,6 +111,8 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
public void onDestroy() {
super.onDestroy();
tabsManager.unsetSavedTabsListener();
pagerAdapter = null;
viewPager.setAdapter(pagerAdapter);
}
/*//////////////////////////////////////////////////////////////////////////
@@ -177,6 +192,7 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
}
private class SelectedTabsPagerAdapter extends FragmentPagerAdapter {
private SelectedTabsPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}

View File

@@ -2,7 +2,6 @@ package org.schabi.newpipe.fragments.list;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -25,19 +24,17 @@ import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.fragments.BaseStateFragment;
import org.schabi.newpipe.fragments.OnScrollBelowItemsListener;
import org.schabi.newpipe.info_list.InfoItemDialog;
import org.schabi.newpipe.info_list.InfoListAdapter;
import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.OnClickGesture;
import org.schabi.newpipe.util.ShareUtils;
import org.schabi.newpipe.util.StateSaver;
import org.schabi.newpipe.util.StreamDialogEntry;
import java.util.Collections;
import java.util.List;
import java.util.Queue;
@@ -65,6 +62,11 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
infoListAdapter = new InfoListAdapter(activity);
}
@Override
public void onDetach() {
super.onDetach();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -250,45 +252,32 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
}
}
protected void showStreamDialog(final StreamInfoItem item) {
final Context context = getContext();
final Activity activity = getActivity();
if (context == null || context.getResources() == null || getActivity() == null) return;
if (context == null || context.getResources() == null || activity == null) return;
final String[] commands = new String[]{
context.getResources().getString(R.string.direct_on_background),
context.getResources().getString(R.string.enqueue_on_background),
context.getResources().getString(R.string.enqueue_on_popup),
context.getResources().getString(R.string.append_playlist),
context.getResources().getString(R.string.share)
};
if (item.getStreamType() == StreamType.AUDIO_STREAM) {
StreamDialogEntry.setEnabledEntries(
StreamDialogEntry.enqueue_on_background,
StreamDialogEntry.start_here_on_background,
StreamDialogEntry.append_playlist,
StreamDialogEntry.share);
} else {
StreamDialogEntry.setEnabledEntries(
StreamDialogEntry.enqueue_on_background,
StreamDialogEntry.enqueue_on_popup,
StreamDialogEntry.start_here_on_background,
StreamDialogEntry.start_here_on_popup,
StreamDialogEntry.append_playlist,
StreamDialogEntry.share);
}
final DialogInterface.OnClickListener actions = (dialogInterface, i) -> {
switch (i) {
case 0:
NavigationHelper.playOnBackgroundPlayer(context, new SinglePlayQueue(item));
break;
case 1:
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
break;
case 2:
NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item));
break;
case 3:
if (getFragmentManager() != null) {
PlaylistAppendDialog.fromStreamInfoItems(Collections.singletonList(item))
.show(getFragmentManager(), TAG);
}
break;
case 4:
ShareUtils.shareUrl(this.getContext(), item.getName(), item.getUrl());
break;
default:
break;
}
};
new InfoItemDialog(getActivity(), item, commands, actions).show();
new InfoItemDialog(activity, item, StreamDialogEntry.getCommands(context), (dialog, which) ->
StreamDialogEntry.clickOn(which, this, item)).show();
}
/*//////////////////////////////////////////////////////////////////////////

View File

@@ -1,8 +1,6 @@
package org.schabi.newpipe.fragments.list.channel;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
@@ -34,12 +32,9 @@ import org.schabi.newpipe.extractor.channel.ChannelInfo;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
import org.schabi.newpipe.info_list.InfoItemDialog;
import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
import org.schabi.newpipe.local.subscription.SubscriptionService;
import org.schabi.newpipe.player.playqueue.ChannelPlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.AnimationUtils;
import org.schabi.newpipe.util.ExtractorHelper;
@@ -49,7 +44,6 @@ import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.ShareUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -150,56 +144,6 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
return headerRootLayout;
}
@Override
protected void showStreamDialog(final StreamInfoItem item) {
final Activity activity = getActivity();
final Context context = getContext();
if (context == null || context.getResources() == null || getActivity() == null) return;
final String[] commands = new String[]{
context.getResources().getString(R.string.enqueue_on_background),
context.getResources().getString(R.string.enqueue_on_popup),
context.getResources().getString(R.string.start_here_on_main),
context.getResources().getString(R.string.start_here_on_background),
context.getResources().getString(R.string.start_here_on_popup),
context.getResources().getString(R.string.append_playlist),
context.getResources().getString(R.string.share)
};
final DialogInterface.OnClickListener actions = (DialogInterface dialogInterface, int i) -> {
final int index = Math.max(infoListAdapter.getItemsList().indexOf(item), 0);
switch (i) {
case 0:
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
break;
case 1:
NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item));
break;
case 2:
NavigationHelper.playOnMainPlayer(context, getPlayQueue(index));
break;
case 3:
NavigationHelper.playOnBackgroundPlayer(context, getPlayQueue(index));
break;
case 4:
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(index));
break;
case 5:
if (getFragmentManager() != null) {
PlaylistAppendDialog.fromStreamInfoItems(Collections.singletonList(item))
.show(getFragmentManager(), TAG);
}
break;
case 6:
ShareUtils.shareUrl(this.getContext(), item.getName(), item.getUrl());
break;
default:
break;
}
};
new InfoItemDialog(getActivity(), item, commands, actions).show();
}
/*//////////////////////////////////////////////////////////////////////////
// Menu
//////////////////////////////////////////////////////////////////////////*/
@@ -440,11 +384,11 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
monitorSubscription(result);
headerPlayAllButton.setOnClickListener(
view -> NavigationHelper.playOnMainPlayer(activity, getPlayQueue()));
view -> NavigationHelper.playOnMainPlayer(activity, getPlayQueue(), false));
headerPopupButton.setOnClickListener(
view -> NavigationHelper.playOnPopupPlayer(activity, getPlayQueue()));
view -> NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false));
headerBackgroundButton.setOnClickListener(
view -> NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue()));
view -> NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue(), false));
}
private PlayQueue getPlayQueue() {

View File

@@ -1,7 +1,6 @@
package org.schabi.newpipe.fragments.list.kiosk;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
@@ -155,9 +154,7 @@ public class KioskFragment extends BaseListInfoFragment<KioskInfo> {
super.handleResult(result);
name = kioskTranslatedName;
if(!useAsFrontPage) {
setTitle(kioskTranslatedName);
}
setTitle(kioskTranslatedName);
if (!result.getErrors().isEmpty()) {
showSnackBarError(result.getErrors(),

View File

@@ -2,10 +2,10 @@ package org.schabi.newpipe.fragments.list.playlist;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
@@ -29,18 +29,19 @@ import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
import org.schabi.newpipe.info_list.InfoItemDialog;
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
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.ErrorActivity;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.ImageDisplayConstants;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.ShareUtils;
import org.schabi.newpipe.util.StreamDialogEntry;
import org.schabi.newpipe.util.ThemeHelper;
import java.util.ArrayList;
@@ -135,48 +136,40 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
infoListAdapter.useMiniItemVariants(true);
}
private PlayQueue getPlayQueueStartingAt(StreamInfoItem infoItem) {
return getPlayQueue(Math.max(infoListAdapter.getItemsList().indexOf(infoItem), 0));
}
@Override
protected void showStreamDialog(final StreamInfoItem item) {
protected void showStreamDialog(StreamInfoItem item) {
final Context context = getContext();
final Activity activity = getActivity();
if (context == null || context.getResources() == null || getActivity() == null) return;
if (context == null || context.getResources() == null || activity == null) return;
final String[] commands = new String[]{
context.getResources().getString(R.string.enqueue_on_background),
context.getResources().getString(R.string.enqueue_on_popup),
context.getResources().getString(R.string.start_here_on_main),
context.getResources().getString(R.string.start_here_on_background),
context.getResources().getString(R.string.start_here_on_popup),
context.getResources().getString(R.string.share)
};
if (item.getStreamType() == StreamType.AUDIO_STREAM) {
StreamDialogEntry.setEnabledEntries(
StreamDialogEntry.enqueue_on_background,
StreamDialogEntry.start_here_on_background,
StreamDialogEntry.append_playlist,
StreamDialogEntry.share);
} else {
StreamDialogEntry.setEnabledEntries(
StreamDialogEntry.enqueue_on_background,
StreamDialogEntry.enqueue_on_popup,
StreamDialogEntry.start_here_on_background,
StreamDialogEntry.start_here_on_popup,
StreamDialogEntry.append_playlist,
StreamDialogEntry.share);
final DialogInterface.OnClickListener actions = (dialogInterface, i) -> {
final int index = Math.max(infoListAdapter.getItemsList().indexOf(item), 0);
switch (i) {
case 0:
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
break;
case 1:
NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item));
break;
case 2:
NavigationHelper.playOnMainPlayer(context, getPlayQueue(index));
break;
case 3:
NavigationHelper.playOnBackgroundPlayer(context, getPlayQueue(index));
break;
case 4:
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(index));
break;
case 5:
ShareUtils.shareUrl(this.getContext(), item.getName(), item.getUrl());
break;
default:
break;
}
};
StreamDialogEntry.start_here_on_popup.setCustomAction(
(fragment, infoItem) -> NavigationHelper.playOnPopupPlayer(context, getPlayQueueStartingAt(infoItem), true));
}
new InfoItemDialog(getActivity(), item, commands, actions).show();
StreamDialogEntry.start_here_on_background.setCustomAction(
(fragment, infoItem) -> NavigationHelper.playOnBackgroundPlayer(context, getPlayQueueStartingAt(infoItem), true));
new InfoItemDialog(activity, item, StreamDialogEntry.getCommands(context), (dialog, which) ->
StreamDialogEntry.clickOn(which, this, item)).show();
}
@Override
@@ -301,19 +294,19 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
.subscribe(getPlaylistBookmarkSubscriber());
headerPlayAllButton.setOnClickListener(view ->
NavigationHelper.playOnMainPlayer(activity, getPlayQueue()));
NavigationHelper.playOnMainPlayer(activity, getPlayQueue(), false));
headerPopupButton.setOnClickListener(view ->
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue()));
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false));
headerBackgroundButton.setOnClickListener(view ->
NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue()));
NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue(), false));
headerPopupButton.setOnLongClickListener(view -> {
NavigationHelper.enqueueOnPopupPlayer(activity, getPlayQueue());
NavigationHelper.enqueueOnPopupPlayer(activity, getPlayQueue(), true);
return true;
});
headerBackgroundButton.setOnLongClickListener(view -> {
NavigationHelper.enqueueOnBackgroundPlayer(activity, getPlayQueue());
NavigationHelper.enqueueOnBackgroundPlayer(activity, getPlayQueue(), true);
return true;
});
}

View File

@@ -2,7 +2,6 @@ package org.schabi.newpipe.info_list;
import android.content.Context;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
@@ -22,6 +21,7 @@ import org.schabi.newpipe.info_list.holder.PlaylistInfoItemHolder;
import org.schabi.newpipe.info_list.holder.PlaylistMiniInfoItemHolder;
import org.schabi.newpipe.info_list.holder.StreamInfoItemHolder;
import org.schabi.newpipe.info_list.holder.StreamMiniInfoItemHolder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.OnClickGesture;
/*
@@ -59,13 +59,14 @@ public class InfoItemBuilder {
this.context = context;
}
public View buildView(@NonNull ViewGroup parent, @NonNull final InfoItem infoItem) {
return buildView(parent, infoItem, false);
public View buildView(@NonNull ViewGroup parent, @NonNull final InfoItem infoItem, final HistoryRecordManager historyRecordManager) {
return buildView(parent, infoItem, historyRecordManager, false);
}
public View buildView(@NonNull ViewGroup parent, @NonNull final InfoItem infoItem, boolean useMiniVariant) {
public View buildView(@NonNull ViewGroup parent, @NonNull final InfoItem infoItem,
final HistoryRecordManager historyRecordManager, boolean useMiniVariant) {
InfoItemHolder holder = holderFromInfoType(parent, infoItem.getInfoType(), useMiniVariant);
holder.updateFromItem(infoItem);
holder.updateFromItem(infoItem, historyRecordManager);
return holder.itemView;
}
@@ -80,7 +81,6 @@ public class InfoItemBuilder {
case COMMENT:
return useMiniVariant ? new CommentsMiniInfoItemHolder(this, parent) : new CommentsInfoItemHolder(this, parent);
default:
Log.e(TAG, "Trollolo");
throw new RuntimeException("InfoType not expected = " + infoType.name());
}
}

View File

@@ -1,22 +1,25 @@
package org.schabi.newpipe.info_list;
import android.app.Activity;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.info_list.holder.ChannelGridInfoItemHolder;
import org.schabi.newpipe.info_list.holder.ChannelInfoItemHolder;
import org.schabi.newpipe.info_list.holder.ChannelMiniInfoItemHolder;
import org.schabi.newpipe.info_list.holder.CommentsInfoItemHolder;
import org.schabi.newpipe.info_list.holder.CommentsMiniInfoItemHolder;
import org.schabi.newpipe.info_list.holder.ChannelGridInfoItemHolder;
import org.schabi.newpipe.info_list.holder.InfoItemHolder;
import org.schabi.newpipe.info_list.holder.PlaylistGridInfoItemHolder;
import org.schabi.newpipe.info_list.holder.PlaylistInfoItemHolder;
@@ -24,6 +27,7 @@ import org.schabi.newpipe.info_list.holder.PlaylistMiniInfoItemHolder;
import org.schabi.newpipe.info_list.holder.StreamGridInfoItemHolder;
import org.schabi.newpipe.info_list.holder.StreamInfoItemHolder;
import org.schabi.newpipe.info_list.holder.StreamMiniInfoItemHolder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.FallbackViewHolder;
import org.schabi.newpipe.util.OnClickGesture;
@@ -71,6 +75,8 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
private final InfoItemBuilder infoItemBuilder;
private final ArrayList<InfoItem> infoItemList;
private final HistoryRecordManager recordManager;
private boolean useMiniVariant = false;
private boolean useGridVariant = false;
private boolean showFooter = false;
@@ -86,8 +92,9 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
}
}
public InfoListAdapter(Activity a) {
infoItemBuilder = new InfoItemBuilder(a);
public InfoListAdapter(Context context) {
this.recordManager = new HistoryRecordManager(context);
infoItemBuilder = new InfoItemBuilder(context);
infoItemList = new ArrayList<>();
}
@@ -115,50 +122,53 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
this.useGridVariant = useGridVariant;
}
public void addInfoItemList(List<InfoItem> data) {
if (data != null) {
if (DEBUG) {
Log.d(TAG, "addInfoItemList() before > infoItemList.size() = " + infoItemList.size() + ", data.size() = " + data.size());
}
public void addInfoItemList(@Nullable final List<InfoItem> data) {
if (data == null) {
return;
}
if (DEBUG) Log.d(TAG, "addInfoItemList() before > infoItemList.size() = " +
infoItemList.size() + ", data.size() = " + data.size());
int offsetStart = sizeConsideringHeaderOffset();
infoItemList.addAll(data);
int offsetStart = sizeConsideringHeaderOffset();
infoItemList.addAll(data);
if (DEBUG) {
Log.d(TAG, "addInfoItemList() after > offsetStart = " + offsetStart + ", infoItemList.size() = " + infoItemList.size() + ", header = " + header + ", footer = " + footer + ", showFooter = " + showFooter);
}
if (DEBUG) Log.d(TAG, "addInfoItemList() after > offsetStart = " + offsetStart +
", infoItemList.size() = " + infoItemList.size() +
", header = " + header + ", footer = " + footer +
", showFooter = " + showFooter);
notifyItemRangeInserted(offsetStart, data.size());
notifyItemRangeInserted(offsetStart, data.size());
if (footer != null && showFooter) {
int footerNow = sizeConsideringHeaderOffset();
notifyItemMoved(offsetStart, footerNow);
if (footer != null && showFooter) {
int footerNow = sizeConsideringHeaderOffset();
notifyItemMoved(offsetStart, footerNow);
if (DEBUG) Log.d(TAG, "addInfoItemList() footer from " + offsetStart + " to " + footerNow);
}
if (DEBUG) Log.d(TAG, "addInfoItemList() footer from " + offsetStart +
" to " + footerNow);
}
}
public void addInfoItem(InfoItem data) {
if (data != null) {
if (DEBUG) {
Log.d(TAG, "addInfoItem() before > infoItemList.size() = " + infoItemList.size() + ", thread = " + Thread.currentThread());
}
public void addInfoItem(@Nullable InfoItem data) {
if (data == null) {
return;
}
if (DEBUG) Log.d(TAG, "addInfoItem() before > infoItemList.size() = " +
infoItemList.size() + ", thread = " + Thread.currentThread());
int positionInserted = sizeConsideringHeaderOffset();
infoItemList.add(data);
int positionInserted = sizeConsideringHeaderOffset();
infoItemList.add(data);
if (DEBUG) {
Log.d(TAG, "addInfoItem() after > position = " + positionInserted + ", infoItemList.size() = " + infoItemList.size() + ", header = " + header + ", footer = " + footer + ", showFooter = " + showFooter);
}
notifyItemInserted(positionInserted);
if (DEBUG) Log.d(TAG, "addInfoItem() after > position = " + positionInserted +
", infoItemList.size() = " + infoItemList.size() +
", header = " + header + ", footer = " + footer +
", showFooter = " + showFooter);
notifyItemInserted(positionInserted);
if (footer != null && showFooter) {
int footerNow = sizeConsideringHeaderOffset();
notifyItemMoved(positionInserted, footerNow);
if (footer != null && showFooter) {
int footerNow = sizeConsideringHeaderOffset();
notifyItemMoved(positionInserted, footerNow);
if (DEBUG) Log.d(TAG, "addInfoItem() footer from " + positionInserted + " to " + footerNow);
}
if (DEBUG) Log.d(TAG, "addInfoItem() footer from " + positionInserted +
" to " + footerNow);
}
}
@@ -235,13 +245,13 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
case COMMENT:
return useMiniVariant ? MINI_COMMENT_HOLDER_TYPE : COMMENT_HOLDER_TYPE;
default:
Log.e(TAG, "Trollolo");
return -1;
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int type) {
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int type) {
if (DEBUG)
Log.d(TAG, "onCreateViewHolder() called with: parent = [" + parent + "], type = [" + type + "]");
switch (type) {
@@ -272,19 +282,18 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
case COMMENT_HOLDER_TYPE:
return new CommentsInfoItemHolder(infoItemBuilder, parent);
default:
Log.e(TAG, "Trollolo");
return new FallbackViewHolder(new View(parent.getContext()));
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (DEBUG) Log.d(TAG, "onBindViewHolder() called with: holder = [" + holder.getClass().getSimpleName() + "], position = [" + position + "]");
if (holder instanceof InfoItemHolder) {
// If header isn't null, offset the items by -1
if (header != null) position--;
((InfoItemHolder) holder).updateFromItem(infoItemList.get(position));
((InfoItemHolder) holder).updateFromItem(infoItemList.get(position), recordManager);
} else if (holder instanceof HFHolder && position == 0 && header != null) {
((HFHolder) holder).view = header;
} else if (holder instanceof HFHolder && position == sizeConsideringHeaderOffset() && footer != null && showFooter) {
@@ -292,6 +301,21 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List<Object> payloads) {
if (!payloads.isEmpty() && holder instanceof InfoItemHolder) {
for (Object payload : payloads) {
if (payload instanceof StreamStateEntity) {
((InfoItemHolder) holder).updateState(infoItemList.get(header == null ? position : position - 1), recordManager);
} else if (payload instanceof Boolean) {
((InfoItemHolder) holder).updateState(infoItemList.get(header == null ? position : position - 1), recordManager);
}
}
} else {
onBindViewHolder(holder, position);
}
}
public GridLayoutManager.SpanSizeLookup getSpanSizeLookup(final int spanCount) {
return new GridLayoutManager.SpanSizeLookup() {
@Override

View File

@@ -7,6 +7,7 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.Localization;
/*
@@ -38,8 +39,8 @@ public class ChannelInfoItemHolder extends ChannelMiniInfoItemHolder {
}
@Override
public void updateFromItem(final InfoItem infoItem) {
super.updateFromItem(infoItem);
public void updateFromItem(final InfoItem infoItem, final HistoryRecordManager historyRecordManager) {
super.updateFromItem(infoItem, historyRecordManager);
if (!(infoItem instanceof ChannelInfoItem)) return;
final ChannelInfoItem item = (ChannelInfoItem) infoItem;

View File

@@ -7,6 +7,7 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.ImageDisplayConstants;
import org.schabi.newpipe.util.Localization;
@@ -30,7 +31,7 @@ public class ChannelMiniInfoItemHolder extends InfoItemHolder {
}
@Override
public void updateFromItem(final InfoItem infoItem) {
public void updateFromItem(final InfoItem infoItem, final HistoryRecordManager historyRecordManager) {
if (!(infoItem instanceof ChannelInfoItem)) return;
final ChannelInfoItem item = (ChannelInfoItem) infoItem;

View File

@@ -5,10 +5,9 @@ import android.widget.TextView;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.local.history.HistoryRecordManager;
/*
* Created by Christian Schabesberger on 12.02.17.
@@ -41,8 +40,8 @@ public class CommentsInfoItemHolder extends CommentsMiniInfoItemHolder {
}
@Override
public void updateFromItem(final InfoItem infoItem) {
super.updateFromItem(infoItem);
public void updateFromItem(final InfoItem infoItem, final HistoryRecordManager historyRecordManager) {
super.updateFromItem(infoItem, historyRecordManager);
if (!(infoItem instanceof CommentsInfoItem)) return;
final CommentsInfoItem item = (CommentsInfoItem) infoItem;

View File

@@ -2,7 +2,6 @@ package org.schabi.newpipe.info_list.holder;
import android.support.v7.app.AppCompatActivity;
import android.text.util.Linkify;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
@@ -11,6 +10,7 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.util.CommentTextOnTouchListener;
import org.schabi.newpipe.util.ImageDisplayConstants;
@@ -46,7 +46,7 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
if(hours != null) timestamp += (Integer.parseInt(hours.replace(":", ""))*3600);
if(minutes != null) timestamp += (Integer.parseInt(minutes.replace(":", ""))*60);
if(seconds != null) timestamp += (Integer.parseInt(seconds));
return streamUrl + url.replace(match.group(0), "#timestamp=" + String.valueOf(timestamp));
return streamUrl + url.replace(match.group(0), "#timestamp=" + timestamp);
}
};
@@ -65,7 +65,7 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
}
@Override
public void updateFromItem(final InfoItem infoItem) {
public void updateFromItem(final InfoItem infoItem, final HistoryRecordManager historyRecordManager) {
if (!(infoItem instanceof CommentsInfoItem)) return;
final CommentsInfoItem item = (CommentsInfoItem) infoItem;
@@ -74,20 +74,17 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
itemThumbnailView,
ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS);
itemThumbnailView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(StringUtil.isBlank(item.getAuthorEndpoint())) return;
try {
final AppCompatActivity activity = (AppCompatActivity) itemBuilder.getContext();
NavigationHelper.openChannelFragment(
activity.getSupportFragmentManager(),
item.getServiceId(),
item.getAuthorEndpoint(),
item.getAuthorName());
} catch (Exception e) {
ErrorActivity.reportUiError((AppCompatActivity) itemBuilder.getContext(), e);
}
itemThumbnailView.setOnClickListener(view -> {
if(StringUtil.isBlank(item.getAuthorEndpoint())) return;
try {
final AppCompatActivity activity = (AppCompatActivity) itemBuilder.getContext();
NavigationHelper.openChannelFragment(
activity.getSupportFragmentManager(),
item.getServiceId(),
item.getAuthorEndpoint(),
item.getAuthorName());
} catch (Exception e) {
ErrorActivity.reportUiError((AppCompatActivity) itemBuilder.getContext(), e);
}
});
@@ -99,7 +96,7 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
itemContentView.setOnTouchListener(CommentTextOnTouchListener.INSTANCE);
if (itemContentView.getLineCount() == 0) {
itemContentView.post(() -> ellipsize());
itemContentView.post(this::ellipsize);
} else {
ellipsize();
}

View File

@@ -6,6 +6,7 @@ import android.view.ViewGroup;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
/*
* Created by Christian Schabesberger on 12.02.17.
@@ -35,5 +36,8 @@ public abstract class InfoItemHolder extends RecyclerView.ViewHolder {
this.itemBuilder = infoItemBuilder;
}
public abstract void updateFromItem(final InfoItem infoItem);
public abstract void updateFromItem(final InfoItem infoItem, final HistoryRecordManager historyRecordManager);
public void updateState(final InfoItem infoItem, final HistoryRecordManager historyRecordManager) {
}
}

View File

@@ -8,6 +8,7 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.ImageDisplayConstants;
public class PlaylistMiniInfoItemHolder extends InfoItemHolder {
@@ -30,7 +31,7 @@ public class PlaylistMiniInfoItemHolder extends InfoItemHolder {
}
@Override
public void updateFromItem(final InfoItem infoItem) {
public void updateFromItem(final InfoItem infoItem, final HistoryRecordManager historyRecordManager) {
if (!(infoItem instanceof PlaylistInfoItem)) return;
final PlaylistInfoItem item = (PlaylistInfoItem) infoItem;

View File

@@ -8,6 +8,7 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.Localization;
/*
@@ -40,8 +41,8 @@ public class StreamInfoItemHolder extends StreamMiniInfoItemHolder {
}
@Override
public void updateFromItem(final InfoItem infoItem) {
super.updateFromItem(infoItem);
public void updateFromItem(final InfoItem infoItem, final HistoryRecordManager historyRecordManager) {
super.updateFromItem(infoItem, historyRecordManager);
if (!(infoItem instanceof StreamInfoItem)) return;
final StreamInfoItem item = (StreamInfoItem) infoItem;

View File

@@ -7,12 +7,18 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.AnimationUtils;
import org.schabi.newpipe.util.ImageDisplayConstants;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.views.AnimatedProgressBar;
import java.util.concurrent.TimeUnit;
public class StreamMiniInfoItemHolder extends InfoItemHolder {
@@ -20,6 +26,7 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
public final TextView itemVideoTitleView;
public final TextView itemUploaderView;
public final TextView itemDurationView;
public final AnimatedProgressBar itemProgressView;
StreamMiniInfoItemHolder(InfoItemBuilder infoItemBuilder, int layoutId, ViewGroup parent) {
super(infoItemBuilder, layoutId, parent);
@@ -28,6 +35,7 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
itemVideoTitleView = itemView.findViewById(R.id.itemVideoTitleView);
itemUploaderView = itemView.findViewById(R.id.itemUploaderView);
itemDurationView = itemView.findViewById(R.id.itemDurationView);
itemProgressView = itemView.findViewById(R.id.itemProgressView);
}
public StreamMiniInfoItemHolder(InfoItemBuilder infoItemBuilder, ViewGroup parent) {
@@ -35,7 +43,7 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
}
@Override
public void updateFromItem(final InfoItem infoItem) {
public void updateFromItem(final InfoItem infoItem, final HistoryRecordManager historyRecordManager) {
if (!(infoItem instanceof StreamInfoItem)) return;
final StreamInfoItem item = (StreamInfoItem) infoItem;
@@ -47,13 +55,24 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
itemDurationView.setBackgroundColor(ContextCompat.getColor(itemBuilder.getContext(),
R.color.duration_background_color));
itemDurationView.setVisibility(View.VISIBLE);
StreamStateEntity state2 = historyRecordManager.loadStreamState(infoItem).blockingGet()[0];
if (state2 != null) {
itemProgressView.setVisibility(View.VISIBLE);
itemProgressView.setMax((int) item.getDuration());
itemProgressView.setProgress((int) TimeUnit.MILLISECONDS.toSeconds(state2.getProgressTime()));
} else {
itemProgressView.setVisibility(View.GONE);
}
} else if (item.getStreamType() == StreamType.LIVE_STREAM) {
itemDurationView.setText(R.string.duration_live);
itemDurationView.setBackgroundColor(ContextCompat.getColor(itemBuilder.getContext(),
R.color.live_duration_background_color));
itemDurationView.setVisibility(View.VISIBLE);
itemProgressView.setVisibility(View.GONE);
} else {
itemDurationView.setVisibility(View.GONE);
itemProgressView.setVisibility(View.GONE);
}
// Default thumbnail is shown on error, while loading and if the url is empty
@@ -83,6 +102,24 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
}
}
@Override
public void updateState(final InfoItem infoItem, final HistoryRecordManager historyRecordManager) {
final StreamInfoItem item = (StreamInfoItem) infoItem;
StreamStateEntity state = historyRecordManager.loadStreamState(infoItem).blockingGet()[0];
if (state != null && item.getDuration() > 0 && item.getStreamType() != StreamType.LIVE_STREAM) {
itemProgressView.setMax((int) item.getDuration());
if (itemProgressView.getVisibility() == View.VISIBLE) {
itemProgressView.setProgressAnimated((int) TimeUnit.MILLISECONDS.toSeconds(state.getProgressTime()));
} else {
itemProgressView.setProgress((int) TimeUnit.MILLISECONDS.toSeconds(state.getProgressTime()));
AnimationUtils.animateView(itemProgressView, true, 500);
}
} else if (itemProgressView.getVisibility() == View.VISIBLE) {
AnimationUtils.animateView(itemProgressView, false, 500);
}
}
private void enableLongClick(final StreamInfoItem item) {
itemView.setLongClickable(true);
itemView.setOnLongClickListener(view -> {
@@ -97,4 +134,4 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
itemView.setLongClickable(false);
itemView.setOnLongClickListener(null);
}
}
}

View File

@@ -1,6 +1,8 @@
package org.schabi.newpipe.local;
import android.app.Activity;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
@@ -8,6 +10,8 @@ import android.view.View;
import android.view.ViewGroup;
import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.local.holder.LocalItemHolder;
import org.schabi.newpipe.local.holder.LocalPlaylistGridItemHolder;
import org.schabi.newpipe.local.holder.LocalPlaylistItemHolder;
@@ -64,6 +68,7 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
private final LocalItemBuilder localItemBuilder;
private final ArrayList<LocalItem> localItems;
private final HistoryRecordManager recordManager;
private final DateFormat dateFormat;
private boolean showFooter = false;
@@ -71,11 +76,12 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
private View header = null;
private View footer = null;
public LocalItemListAdapter(Activity activity) {
localItemBuilder = new LocalItemBuilder(activity);
public LocalItemListAdapter(Context context) {
recordManager = new HistoryRecordManager(context);
localItemBuilder = new LocalItemBuilder(context);
localItems = new ArrayList<>();
dateFormat = DateFormat.getDateInstance(DateFormat.SHORT,
Localization.getPreferredLocale(activity));
Localization.getPreferredLocale(context));
}
public void setSelectedListener(OnClickGesture<LocalItem> listener) {
@@ -86,38 +92,33 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
localItemBuilder.setOnItemSelectedListener(null);
}
public void addItems(List<? extends LocalItem> data) {
if (data != null) {
if (DEBUG) {
Log.d(TAG, "addItems() before > localItems.size() = " +
localItems.size() + ", data.size() = " + data.size());
}
public void addItems(@Nullable List<? extends LocalItem> data) {
if (data == null) {
return;
}
if (DEBUG) Log.d(TAG, "addItems() before > localItems.size() = " +
localItems.size() + ", data.size() = " + data.size());
int offsetStart = sizeConsideringHeader();
localItems.addAll(data);
int offsetStart = sizeConsideringHeader();
localItems.addAll(data);
if (DEBUG) {
Log.d(TAG, "addItems() after > offsetStart = " + offsetStart +
", localItems.size() = " + localItems.size() +
", header = " + header + ", footer = " + footer +
", showFooter = " + showFooter);
}
if (DEBUG) Log.d(TAG, "addItems() after > offsetStart = " + offsetStart +
", localItems.size() = " + localItems.size() +
", header = " + header + ", footer = " + footer +
", showFooter = " + showFooter);
notifyItemRangeInserted(offsetStart, data.size());
notifyItemRangeInserted(offsetStart, data.size());
if (footer != null && showFooter) {
int footerNow = sizeConsideringHeader();
notifyItemMoved(offsetStart, footerNow);
if (footer != null && showFooter) {
int footerNow = sizeConsideringHeader();
notifyItemMoved(offsetStart, footerNow);
if (DEBUG) Log.d(TAG, "addItems() footer from " + offsetStart +
" to " + footerNow);
}
if (DEBUG) Log.d(TAG, "addItems() footer from " + offsetStart +
" to " + footerNow);
}
}
public void removeItem(final LocalItem data) {
final int index = localItems.indexOf(data);
localItems.remove(index);
notifyItemRemoved(index + (header != null ? 1 : 0));
}
@@ -219,8 +220,9 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int type) {
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int type) {
if (DEBUG) Log.d(TAG, "onCreateViewHolder() called with: parent = [" +
parent + "], type = [" + type + "]");
switch (type) {
@@ -251,7 +253,7 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (DEBUG) Log.d(TAG, "onBindViewHolder() called with: holder = [" +
holder.getClass().getSimpleName() + "], position = [" + position + "]");
@@ -259,7 +261,7 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
// If header isn't null, offset the items by -1
if (header != null) position--;
((LocalItemHolder) holder).updateFromItem(localItems.get(position), dateFormat);
((LocalItemHolder) holder).updateFromItem(localItems.get(position), recordManager, dateFormat);
} else if (holder instanceof HeaderFooterHolder && position == 0 && header != null) {
((HeaderFooterHolder) holder).view = header;
} else if (holder instanceof HeaderFooterHolder && position == sizeConsideringHeader()
@@ -268,6 +270,21 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List<Object> payloads) {
if (!payloads.isEmpty() && holder instanceof LocalItemHolder) {
for (Object payload : payloads) {
if (payload instanceof StreamStateEntity) {
((LocalItemHolder) holder).updateState(localItems.get(header == null ? position : position - 1), recordManager);
} else if (payload instanceof Boolean) {
((LocalItemHolder) holder).updateState(localItems.get(header == null ? position : position - 1), recordManager);
}
}
} else {
onBindViewHolder(holder, position);
}
}
public GridLayoutManager.SpanSizeLookup getSpanSizeLookup(final int spanCount) {
return new GridLayoutManager.SpanSizeLookup() {
@Override

View File

@@ -1,6 +1,5 @@
package org.schabi.newpipe.local.dialog;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -28,7 +27,7 @@ import java.util.Collections;
import java.util.List;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.disposables.CompositeDisposable;
public final class PlaylistAppendDialog extends PlaylistDialog {
private static final String TAG = PlaylistAppendDialog.class.getCanonicalName();
@@ -36,7 +35,7 @@ public final class PlaylistAppendDialog extends PlaylistDialog {
private RecyclerView playlistRecyclerView;
private LocalItemListAdapter playlistAdapter;
private Disposable playlistReactor;
private CompositeDisposable playlistDisposables = new CompositeDisposable();
public static PlaylistAppendDialog fromStreamInfo(final StreamInfo info) {
PlaylistAppendDialog dialog = new PlaylistAppendDialog();
@@ -99,9 +98,9 @@ public final class PlaylistAppendDialog extends PlaylistDialog {
final View newPlaylistButton = view.findViewById(R.id.newPlaylist);
newPlaylistButton.setOnClickListener(ignored -> openCreatePlaylistDialog());
playlistReactor = playlistManager.getPlaylists()
playlistDisposables.add(playlistManager.getPlaylists()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onPlaylistsReceived);
.subscribe(this::onPlaylistsReceived));
}
/*//////////////////////////////////////////////////////////////////////////
@@ -111,10 +110,12 @@ public final class PlaylistAppendDialog extends PlaylistDialog {
@Override
public void onDestroyView() {
super.onDestroyView();
if (playlistReactor != null) playlistReactor.dispose();
if (playlistAdapter != null) playlistAdapter.unsetSelectedListener();
playlistDisposables.dispose();
if (playlistAdapter != null) {
playlistAdapter.unsetSelectedListener();
}
playlistReactor = null;
playlistDisposables.clear();
playlistRecyclerView = null;
playlistAdapter = null;
}
@@ -148,13 +149,12 @@ public final class PlaylistAppendDialog extends PlaylistDialog {
@NonNull List<StreamEntity> streams) {
if (getStreams() == null) return;
@SuppressLint("ShowToast")
final Toast successToast = Toast.makeText(getContext(),
R.string.playlist_add_stream_success, Toast.LENGTH_SHORT);
manager.appendToPlaylist(playlist.uid, streams)
playlistDisposables.add(manager.appendToPlaylist(playlist.uid, streams)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(ignored -> successToast.show());
.subscribe(ignored -> successToast.show()));
getDialog().dismiss();
}

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