1
mirror of https://github.com/TeamNewPipe/NewPipe synced 2025-09-21 22:20:50 +02:00

Compare commits

...

199 Commits

Author SHA1 Message Date
Christian Schabesberger
140cfaec90 moved on to version 0.9.7 2017-05-20 17:45:50 +02:00
Дима Гайнуллин
a0f20aac23 Translated using Weblate (Russian)
Currently translated at 86.9% (153 of 176 strings)
2017-05-20 15:40:42 +02:00
ktln
93fafb362f Translated using Weblate (Russian)
Currently translated at 86.9% (153 of 176 strings)
2017-05-20 15:39:44 +02:00
anonymous
9152df5512 Translated using Weblate (Russian)
Currently translated at 84.0% (148 of 176 strings)
2017-05-20 15:37:48 +02:00
Anton Shestakov
415bcd9f7e Translated using Weblate (Russian)
Currently translated at 83.5% (147 of 176 strings)
2017-05-20 15:37:13 +02:00
Дима Гайнуллин
2224033a85 Translated using Weblate (Russian)
Currently translated at 82.9% (146 of 176 strings)
2017-05-20 15:36:57 +02:00
Anton Shestakov
ade0498684 Translated using Weblate (Russian)
Currently translated at 82.9% (146 of 176 strings)
2017-05-20 15:34:06 +02:00
Дима Гайнуллин
211b00fff4 Translated using Weblate (Russian)
Currently translated at 82.9% (146 of 176 strings)
2017-05-20 15:33:52 +02:00
ktln
77c72d03a8 Translated using Weblate (Russian)
Currently translated at 82.9% (146 of 176 strings)
2017-05-20 15:32:32 +02:00
Anton Shestakov
f429d93351 Translated using Weblate (Russian)
Currently translated at 82.3% (145 of 176 strings)
2017-05-20 15:25:48 +02:00
Дима Гайнуллин
e428f8b116 Translated using Weblate (Russian)
Currently translated at 82.3% (145 of 176 strings)
2017-05-20 15:20:18 +02:00
Anton Shestakov
9482b9d638 Translated using Weblate (Russian)
Currently translated at 82.3% (145 of 176 strings)
2017-05-20 15:19:15 +02:00
Дима Гайнуллин
e019c9f720 Translated using Weblate (Russian)
Currently translated at 82.3% (145 of 176 strings)
2017-05-20 15:12:17 +02:00
Anton Shestakov
e2778366e9 Translated using Weblate (Russian)
Currently translated at 82.3% (145 of 176 strings)
2017-05-20 15:11:49 +02:00
ktln
36d2f8339c Translated using Weblate (Russian)
Currently translated at 82.3% (145 of 176 strings)
2017-05-20 15:11:30 +02:00
anonymous
a4a0c3b9fd Translated using Weblate (Russian)
Currently translated at 81.2% (143 of 176 strings)
2017-05-20 15:10:44 +02:00
ktln
1b1b6c8af8 Translated using Weblate (Russian)
Currently translated at 80.6% (142 of 176 strings)
2017-05-20 15:10:20 +02:00
Anton Shestakov
064fd2bc68 Translated using Weblate (Russian)
Currently translated at 80.1% (141 of 176 strings)
2017-05-20 15:10:11 +02:00
ktln
13152ab6ea Translated using Weblate (Russian)
Currently translated at 79.5% (140 of 176 strings)
2017-05-20 15:07:58 +02:00
Anton Shestakov
1743d821eb Translated using Weblate (Russian)
Currently translated at 78.9% (139 of 176 strings)
2017-05-20 15:04:08 +02:00
ktln
ff16e577ef Translated using Weblate (Russian)
Currently translated at 78.9% (139 of 176 strings)
2017-05-20 15:02:58 +02:00
Anton Shestakov
86062c6e94 Translated using Weblate (Russian)
Currently translated at 78.4% (138 of 176 strings)
2017-05-20 15:02:43 +02:00
ktln
8ce2350563 Translated using Weblate (Russian)
Currently translated at 78.4% (138 of 176 strings)
2017-05-20 15:00:51 +02:00
Anton Shestakov
cb8989af7f Translated using Weblate (Russian)
Currently translated at 77.8% (137 of 176 strings)
2017-05-20 15:00:25 +02:00
ktln
877fa45eb4 Translated using Weblate (Russian)
Currently translated at 77.2% (136 of 176 strings)
2017-05-20 14:59:24 +02:00
Anton Shestakov
e33942486d Translated using Weblate (Russian)
Currently translated at 76.7% (135 of 176 strings)
2017-05-20 14:58:50 +02:00
Дима Гайнуллин
9606e080ef Translated using Weblate (Russian)
Currently translated at 76.7% (135 of 176 strings)
2017-05-20 14:57:45 +02:00
Anton Shestakov
d5cd9c55be Translated using Weblate (Russian)
Currently translated at 76.7% (135 of 176 strings)
2017-05-20 14:56:39 +02:00
Дима Гайнуллин
9c197ced80 Translated using Weblate (Russian)
Currently translated at 75.0% (132 of 176 strings)
2017-05-20 14:40:15 +02:00
Anton Shestakov
f8424599e1 Translated using Weblate (Russian)
Currently translated at 75.0% (132 of 176 strings)
2017-05-20 14:38:59 +02:00
naofum
ccee18057a Translated using Weblate (Japanese)
Currently translated at 100.0% (176 of 176 strings)
2017-05-20 07:11:53 +02:00
Freddy Morán Jr
1ad0f342ad Translated using Weblate (Spanish)
Currently translated at 100.0% (176 of 176 strings)
2017-05-19 15:39:44 +02:00
Eduardo Caron
7a16ac574b Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (176 of 176 strings)
2017-05-19 15:16:03 +02:00
Matej U
f46738f750 Translated using Weblate (Slovenian)
Currently translated at 100.0% (176 of 176 strings)
2017-05-19 13:49:47 +02:00
monolifed
fb8ff3fece Translated using Weblate (Turkish)
Currently translated at 100.0% (176 of 176 strings)
2017-05-19 12:20:03 +02:00
Weblate
7498dd3800 Merge remote-tracking branch 'origin/master' 2017-05-19 03:46:42 +02:00
Freddy Morán Jr
957c31b9c5 Translated using Weblate (Spanish)
Currently translated at 100.0% (172 of 172 strings)
2017-05-19 03:46:40 +02:00
Mauricio Colli
b260570e8c Merge pull request #568 from mauriciocolli/option-search-suggestions
Add option to disable the search suggestions
2017-05-16 22:17:28 -03:00
Mauricio Colli
46542747b7 Merge pull request #567 from mauriciocolli/option-gestures-player
Add option to disable the gesture controls of the player
2017-05-16 22:14:31 -03:00
Mauricio Colli
d64480fc9b Add option to disable the search suggestions 2017-05-16 22:14:07 -03:00
Mauricio Colli
c00e694d40 Add option to disable the gesture controls of the player 2017-05-16 21:45:38 -03:00
Bruno Guerreiro
f0761cc95e Translated using Weblate (Portuguese)
Currently translated at 100.0% (172 of 172 strings)
2017-05-16 21:32:24 +02:00
Eduardo Caron
068554955c Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (172 of 172 strings)
2017-05-16 21:25:48 +02:00
Freddy Morán Jr
a2f915f556 Translated using Weblate (Spanish)
Currently translated at 100.0% (172 of 172 strings)
2017-05-16 14:38:29 +02:00
Mohamad Hasan Al Banna
cffd35c974 Translated using Weblate (Indonesian)
Currently translated at 100.0% (172 of 172 strings)
2017-05-15 17:53:50 +02:00
naofum
2ef2aa98a4 Translated using Weblate (Japanese)
Currently translated at 100.0% (172 of 172 strings)
2017-05-15 17:23:57 +02:00
Théophane
ba98b30aa4 Translated using Weblate (French)
Currently translated at 100.0% (172 of 172 strings)
2017-05-15 16:23:59 +02:00
E T
87c0f9c803 Translated using Weblate (Turkish)
Currently translated at 100.0% (172 of 172 strings)
2017-05-15 16:08:54 +02:00
Matej U
ce620b9e28 Translated using Weblate (Slovenian)
Currently translated at 100.0% (172 of 172 strings)
2017-05-15 14:44:49 +02:00
Weblate
fcbb5536eb Merge remote-tracking branch 'origin/master' 2017-05-15 14:42:35 +02:00
Matej U
72df6dbd80 Translated using Weblate (Slovenian)
Currently translated at 100.0% (171 of 171 strings)
2017-05-15 14:42:32 +02:00
Christian Schabesberger
3a6b023dbf update gradle to version 2.3.2 2017-05-15 12:27:46 +02:00
Mauricio Colli
8b67f1358d Implement no-audio icon 2017-05-15 00:57:57 -03:00
Mauricio Colli
2aebb3b8db Add and update resources 2017-05-15 00:57:04 -03:00
Weblate
f2b38be2b0 Merge remote-tracking branch 'origin/master' 2017-05-14 21:46:25 +02:00
E T
a43001f30d Translated using Weblate (Turkish)
Currently translated at 100.0% (171 of 171 strings)
2017-05-14 21:46:25 +02:00
cwgt
17abe1ea5c Translated using Weblate (Bengali (Bangladesh))
Currently translated at 100.0% (167 of 167 strings)
2017-05-14 21:46:24 +02:00
Bruno Guerreiro
6aaefab618 Translated using Weblate (Portuguese)
Currently translated at 98.2% (168 of 171 strings)
2017-05-14 21:46:22 +02:00
Mauricio Colli
cd867fb4d1 Merge pull request #559 from mauriciocolli/default-popup-resolution
Change popup default resolution
2017-05-14 14:01:12 -03:00
Mauricio Colli
25988f61a6 Change popup default resolution 2017-05-14 13:57:08 -03:00
Mauricio Colli
be421e580d Merge pull request #557 from mauriciocolli/fix-settings-rotation
Fix settings on screen rotation
2017-05-14 11:20:29 -03:00
Mauricio Colli
641ab25470 Fix Settings on screen rotation 2017-05-14 11:10:00 -03:00
Mauricio Colli
a508539c2e Merge pull request #556 from mauriciocolli/fix-audio-focus
Improve behavior on audio focus gain
2017-05-14 10:54:13 -03:00
Mauricio Colli
cac79d9a0d Improve behavior on audio focus gain 2017-05-14 10:46:28 -03:00
Christian Schabesberger
9ede8118da Merge pull request #553 from mauriciocolli/fix-screen-on
Fix keep screen on
2017-05-14 10:48:05 +02:00
Mauricio Colli
e47761750a Fix 'keep screen on' 2017-05-14 00:32:28 -03:00
Christian Schabesberger
2f181ce7c9 move on to version 0.9.6 2017-05-13 22:13:28 +02:00
Christian Schabesberger
3a13d4a1de Merge pull request #546 from mueller-ma/kodi
Change order of buttons in the title bar
2017-05-13 20:16:24 +02:00
Christian Schabesberger
719de00e0f Merge branch 'fix-menu-update' of https://github.com/mauriciocolli/NewPipe 2017-05-13 20:08:18 +02:00
cwgt
ddffe99f53 Translated using Weblate (Bengali (Bangladesh))
Currently translated at 100.0% (167 of 167 strings)
2017-05-13 11:36:43 +02:00
Eduardo Caron
9ade596f06 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (171 of 171 strings)
2017-05-11 20:33:38 +02:00
nailyk
46f413b7f2 Translated using Weblate (French)
Currently translated at 100.0% (171 of 171 strings)
2017-05-11 19:41:37 +02:00
nailyk
5fe2e7b8ad Translated using Weblate (French)
Currently translated at 92.3% (158 of 171 strings)

 popup_mode_share_menu_title a été traduit "Module popup de Newpipe", restons cohérents.
2017-05-11 19:33:46 +02:00
nailyk
3008cbb5f4 Translated using Weblate (French)
Currently translated at 91.8% (157 of 171 strings)
2017-05-11 19:20:57 +02:00
Weblate
f7983960e5 Merge remote-tracking branch 'origin/master' 2017-05-10 21:07:55 +02:00
monolifed
bb8007bb7c Translated using Weblate (Turkish)
Currently translated at 100.0% (171 of 171 strings)
2017-05-10 21:07:55 +02:00
Freddy Morán Jr
01751ba97a Translated using Weblate (Spanish)
Currently translated at 100.0% (171 of 171 strings)
2017-05-10 21:07:55 +02:00
Tobias Groza
f41475d11c Translated using Weblate (German)
Currently translated at 96.4% (165 of 171 strings)
2017-05-10 21:07:54 +02:00
Nathan Follens
d8914d9b6d Translated using Weblate (Dutch)
Currently translated at 100.0% (171 of 171 strings)
2017-05-10 21:07:52 +02:00
mueller-ma
94cc2ad365 change order of buttons, see https://github.com/TeamNewPipe/NewPipe/issues/471#issuecomment-300267118 2017-05-09 20:57:42 +02:00
Christian Schabesberger
e07464b81c Merge pull request #545 from mauriciocolli/fix-image-loader
Fix image loading bug
2017-05-09 20:19:43 +02:00
Jose Maeso
9d231b55b5 Translated using Weblate (Spanish)
Currently translated at 100.0% (171 of 171 strings)
2017-05-09 18:09:23 +02:00
Freddy Morán Jr
77d8dac3c1 Translated using Weblate (Spanish)
Currently translated at 100.0% (171 of 171 strings)
2017-05-09 18:07:54 +02:00
Freddy Morán Jr
e160015283 Translated using Weblate (Spanish)
Currently translated at 100.0% (171 of 171 strings)
2017-05-09 18:05:47 +02:00
mueller-ma
aeb0cac3ee change order of buttons. closes #471 2017-05-09 17:11:19 +02:00
naofum
a539f94837 Translated using Weblate (Japanese)
Currently translated at 100.0% (171 of 171 strings)
2017-05-09 16:19:42 +02:00
monolifed
df70751071 Translated using Weblate (Turkish)
Currently translated at 100.0% (171 of 171 strings)
2017-05-09 14:34:49 +02:00
E T
e55f1dff78 Translated using Weblate (Turkish)
Currently translated at 97.6% (167 of 171 strings)
2017-05-09 14:12:43 +02:00
Weblate
47646e1c62 Merge remote-tracking branch 'origin/master' 2017-05-09 14:11:45 +02:00
E T
80e673f20c Translated using Weblate (Turkish)
Currently translated at 100.0% (167 of 167 strings)
2017-05-09 14:11:41 +02:00
Mauricio Colli
9ca8c5480c Fix image loader bug 2017-05-09 00:12:06 -03:00
Mauricio Colli
4d0d3c7ead Update menu items after change in settings 2017-05-08 22:23:27 -03:00
Christian Schabesberger
58137aadc9 Merge pull request #543 from mueller-ma/patch-1
Remove untranslatable string
2017-05-08 22:45:21 +02:00
mueller-ma
82a59ae479 Remove untranslatable string 2017-05-08 20:51:13 +02:00
Mauricio Colli
affd23b14e Fix animations 2017-05-08 10:33:26 -03:00
Mauricio Colli
9c7f249756 Clean and move some classes 2017-05-08 10:28:33 -03:00
Christian Schabesberger
e2a0502171 Merge pull request #538 from cwgt/bn-bd-translation
Add Bangla translation (for Bangladesh)
2017-05-08 11:44:27 +02:00
cwgt
3832a4b355 Add Bangla translation (for Bangladesh) 2017-05-08 15:27:55 +06:00
cwgt
84f059415c Create strings.xml 2017-05-08 13:32:33 +06:00
Christian Schabesberger
bb292e3199 add some more screenshots 2017-05-07 20:41:44 +02:00
Christian Schabesberger
70541bf561 moved on to version 0.9.5 2017-05-07 20:05:00 +02:00
Christian Schabesberger
48dd8e88e3 Merge branch 'master' of github.com:theScrabi/NewPipe 2017-05-07 19:48:21 +02:00
Eduardo Caron
52c2e0899d Translated using Weblate (Portuguese (Brazil))
Currently translated at 99.4% (166 of 167 strings)
2017-05-07 18:46:09 +02:00
Christian Schabesberger
9955d5b62f Merge branch 'resize' 2017-05-04 21:31:38 +02:00
Marian Hanzel
8e26247fa1 Translated using Weblate (Slovak)
Currently translated at 100.0% (167 of 167 strings)
2017-05-04 21:02:23 +02:00
Weblate
72924e2692 Merge remote-tracking branch 'origin/master' 2017-05-04 18:46:39 +02:00
Eduardo Caron
8c2c8d630f Translated using Weblate (Portuguese (Brazil))
Currently translated at 98.8% (165 of 167 strings)
2017-05-04 18:46:39 +02:00
Freddy Morán Jr
5ccf0baa6b Translated using Weblate (Spanish)
Currently translated at 100.0% (167 of 167 strings)
2017-05-04 18:46:36 +02:00
Christian Schabesberger
8fff0ccdf2 Merge pull request #532 from mauriciocolli/improve-readme
Update Readme
2017-05-04 00:10:44 +02:00
Mauricio Colli
35264bfb97 Update Readme 2017-05-03 16:13:31 -03:00
Matej U
4c9b0dc8e9 Translated using Weblate (Slovenian)
Currently translated at 100.0% (167 of 167 strings)
2017-05-02 21:02:58 +02:00
Freddy Morán Jr
4deb7caa83 Translated using Weblate (Spanish)
Currently translated at 100.0% (167 of 167 strings)
2017-05-02 17:22:14 +02:00
Enol P
45f1a512b4 Translated using Weblate (Asturian)
Currently translated at 98.2% (164 of 167 strings)
2017-05-01 18:44:12 +02:00
Mladen Pejaković
ab95fdc087 Translated using Weblate (Serbian)
Currently translated at 99.4% (166 of 167 strings)
2017-05-01 15:46:36 +02:00
Christian Schabesberger
df608b9ded Merge branch 'feature-resize' of https://github.com/mauriciocolli/NewPipe into resize 2017-05-01 15:15:30 +02:00
Tobias Groza
6a4c81d160 Translated using Weblate (German)
Currently translated at 98.2% (164 of 167 strings)
2017-05-01 12:45:14 +02:00
Mauricio Colli
040d658540 Implement resizable popup 2017-05-01 02:23:50 -03:00
naofum
cbc9913e9c Translated using Weblate (Japanese)
Currently translated at 100.0% (167 of 167 strings)
2017-04-30 05:47:23 +02:00
Wout Bertrums
f007cbd5ee Translated using Weblate (Dutch)
Currently translated at 100.0% (167 of 167 strings)
2017-04-29 18:46:39 +02:00
zmni
7351591df7 Translated using Weblate (Indonesian)
Currently translated at 100.0% (167 of 167 strings)
2017-04-29 16:52:22 +02:00
monolifed
5222d4cbba Translated using Weblate (Turkish)
Currently translated at 100.0% (167 of 167 strings)
2017-04-29 09:48:33 +02:00
Weblate
ef9966815e Merge remote-tracking branch 'origin/master' 2017-04-29 08:27:55 +02:00
anonymous
ad73440ce9 Translated using Weblate (Czech)
Currently translated at 93.9% (154 of 164 strings)
2017-04-29 08:27:51 +02:00
Christian Schabesberger
c81cfdc455 moved on to version 0.9.4 2017-04-28 21:26:11 +02:00
Christian Schabesberger
134c3804db Merge branch 'fix-search' of https://github.com/mauriciocolli/NewPipe into fix-search 2017-04-28 20:42:37 +02:00
Christian Schabesberger
e355df5eda update NewPipeExtractor 2017-04-28 20:19:23 +02:00
Mauricio Colli
a68e0a95f4 Fix NullPointerException 2017-04-28 01:07:54 -03:00
Mauricio Colli
6fd6facf72 Improve animations of VideoDetailFragment 2017-04-28 00:58:50 -03:00
Mauricio Colli
00102d4048 Try to fix travis 2017-04-26 17:07:24 -03:00
Mauricio Colli
adbeff11d4 Minor improvements 2017-04-26 16:32:20 -03:00
Mauricio Colli
a8fe329678 Improve fragments
- They save the state now, that means, no more reloading after rotating the screen or switching between apps
2017-04-26 16:32:04 -03:00
Mauricio Colli
a4b61bf730 Add new workers 2017-04-26 16:25:09 -03:00
Mauricio Colli
ee592def0c Add drawables and improve layouts 2017-04-26 16:24:33 -03:00
Allan Nordhøy
c14e117239 Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (164 of 164 strings)
2017-04-25 03:46:10 +02:00
rapi3
b6e94dde0c Translated using Weblate (Romanian)
Currently translated at 100.0% (164 of 164 strings)
2017-04-23 15:46:17 +02:00
monolifed
63a4a44d7e Translated using Weblate (Turkish)
Currently translated at 100.0% (164 of 164 strings)
2017-04-23 12:46:56 +02:00
Allan Nordhøy
eb8ab5d527 Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (164 of 164 strings)
2017-04-23 00:57:22 +02:00
riotism
b778d40d65 Translated using Weblate (Chinese (Hong Kong))
Currently translated at 97.5% (160 of 164 strings)
2017-04-22 18:44:35 +02:00
rapi3
2f570672dc Translated using Weblate (Romanian)
Currently translated at 100.0% (164 of 164 strings)
2017-04-21 14:11:07 +02:00
anonymous
9290ed490f Translated using Weblate (Turkish)
Currently translated at 100.0% (164 of 164 strings)
2017-04-21 11:12:23 +02:00
monolifed
1bda812c75 Translated using Weblate (Turkish)
Currently translated at 100.0% (164 of 164 strings)
2017-04-21 11:11:23 +02:00
Weblate
ab82406c98 Merge remote-tracking branch 'origin/master' 2017-04-19 17:36:17 +02:00
Mladen Pejaković
be763349df Translated using Weblate (Serbian)
Currently translated at 99.3% (163 of 164 strings)
2017-04-19 17:36:16 +02:00
zmni
91764ad601 Translated using Weblate (Indonesian)
Currently translated at 100.0% (164 of 164 strings)
2017-04-19 17:36:14 +02:00
Christian Schabesberger
1c4031aa38 Merge branch 'master' of github.com:theScrabi/NewPipe 2017-04-18 22:39:16 +02:00
Christian Schabesberger
c3bc648dd4 moved on to version 0.9.3 2017-04-18 22:34:32 +02:00
Christian Schabesberger
c97d794272 updated sdk and support lib 2017-04-18 22:34:04 +02:00
Christian Schabesberger
8e7d2e91e9 Merge branch 'feature-backplayer' of https://github.com/mauriciocolli/NewPipe into mark 2017-04-18 22:06:47 +02:00
Laura Arjona Reina
cf0fbbbd3d Translated using Weblate (Spanish)
Currently translated at 100.0% (164 of 164 strings)
2017-04-18 20:19:12 +02:00
Tobias Groza
7d3ede7946 Translated using Weblate (German)
Currently translated at 100.0% (164 of 164 strings)
2017-04-18 12:58:44 +02:00
Eduardo Caron
1aa308eb5d Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (164 of 164 strings)
2017-04-18 00:35:02 +02:00
anonymous
4bfd30e34a Translated using Weblate (Portuguese (Brazil))
Currently translated at 99.3% (163 of 164 strings)
2017-04-18 00:28:43 +02:00
Eduardo Caron
0f46c90688 Translated using Weblate (Portuguese (Brazil))
Currently translated at 99.3% (163 of 164 strings)
2017-04-18 00:27:31 +02:00
Matej U
aa2173fc4a Translated using Weblate (Slovenian)
Currently translated at 100.0% (164 of 164 strings)
2017-04-17 18:09:10 +02:00
Mauricio Colli
932cb1d19c Remove ugly bitmap sharing and improvements
- Now it is just using the ImageLoader to load the image, and better yet, it already have cache implemented in it
- Improve MainActivity intent handler
- Improve utils classes
2017-04-17 01:21:48 -03:00
Mauricio Colli
18b038d8e4 Improve notification layouts 2017-04-17 01:20:14 -03:00
Mauricio Colli
2ac71c75c0 Improve players
- Background player is using ExoPlayer internally now
2017-04-17 01:19:53 -03:00
naofum
4067ba5232 Translated using Weblate (Japanese)
Currently translated at 100.0% (164 of 164 strings)
2017-04-16 16:48:37 +02:00
Marian Hanzel
ab47dd5a5b Translated using Weblate (Slovak)
Currently translated at 100.0% (164 of 164 strings)
2017-04-15 22:32:17 +02:00
Nathan Follens
3130910307 Translated using Weblate (Dutch)
Currently translated at 100.0% (164 of 164 strings)
2017-04-15 17:35:12 +02:00
Sérgio Marques
22113439a4 Translated using Weblate (Portuguese)
Currently translated at 100.0% (164 of 164 strings)
2017-04-15 16:09:58 +02:00
Weblate
2d25a9ad7a Merge remote-tracking branch 'origin/master' 2017-04-15 16:07:22 +02:00
Freddy Morán Jr
8f0a2cc2f0 Translated using Weblate (Spanish)
Currently translated at 100.0% (161 of 161 strings)
2017-04-15 16:07:22 +02:00
Marian Hanzel
4ca39258c9 Translated using Weblate (Slovak)
Currently translated at 100.0% (161 of 161 strings)
2017-04-15 16:07:21 +02:00
Enol P
d0c0238b8b Translated using Weblate (Asturian)
Currently translated at 98.1% (158 of 161 strings)
2017-04-15 16:07:20 +02:00
Sérgio Marques
f9f08e5169 Translated using Weblate (Portuguese)
Currently translated at 100.0% (161 of 161 strings)
2017-04-15 16:07:18 +02:00
Christian Schabesberger
cfc51b2401 Merge branch 'master' of github.com:theScrabi/NewPipe 2017-04-15 14:05:39 +02:00
Christian Schabesberger
54c2704cb5 switch to dark default theme 2017-04-15 14:05:31 +02:00
Christian Schabesberger
9b51c946fe add 1080p to available features 2017-04-15 13:43:21 +02:00
Christian Schabesberger
06f38cbcb4 Merge branch 'feature-4k60f' of git://github.com/mauriciocolli/NewPipe into 4k 2017-04-15 12:52:03 +02:00
Christian Schabesberger
f368d6b257 update extractor 2017-04-15 12:51:35 +02:00
Marian Hanzel
f4301da14d Translated using Weblate (Slovak)
Currently translated at 100.0% (161 of 161 strings)
2017-04-13 21:49:26 +02:00
Weblate
f34c09f165 Merge remote-tracking branch 'origin/master' 2017-04-13 20:51:06 +02:00
Freddy Morán Jr
6d1db56512 Translated using Weblate (Spanish)
Currently translated at 100.0% (161 of 161 strings)
2017-04-13 20:51:03 +02:00
Christian Schabesberger
b70c07d004 update extractor 2017-04-13 19:41:43 +02:00
Christian Schabesberger
f9f48a5eb6 Merge branch 'master' of github.com:theScrabi/NewPipe 2017-04-13 19:41:28 +02:00
Christian Schabesberger
14e4e73444 update gradle 2017-04-13 19:41:15 +02:00
Nathan Follens
f2ce4d2daf Translated using Weblate (Dutch)
Currently translated at 100.0% (161 of 161 strings)
2017-04-13 19:10:56 +02:00
naofum
468ebdda87 Translated using Weblate (Japanese)
Currently translated at 100.0% (161 of 161 strings)
2017-04-13 16:53:26 +02:00
nautilusx
a1f0fb3b14 Translated using Weblate (German)
Currently translated at 100.0% (161 of 161 strings)
2017-04-13 16:08:34 +02:00
zmni
3c9f4de234 Translated using Weblate (Indonesian)
Currently translated at 100.0% (161 of 161 strings)
2017-04-13 15:59:13 +02:00
Tobias Groza
8ae411619f Translated using Weblate (German)
Currently translated at 96.8% (156 of 161 strings)
2017-04-13 15:56:35 +02:00
nautilusx
61e5c9121a Translated using Weblate (German)
Currently translated at 96.2% (155 of 161 strings)
2017-04-13 15:55:28 +02:00
Weblate
8a3cf0d5dc Merge remote-tracking branch 'origin/master' 2017-04-13 15:53:52 +02:00
Freddy Morán Jr
ecb5df65ac Translated using Weblate (Spanish)
Currently translated at 100.0% (160 of 160 strings)
2017-04-13 15:53:52 +02:00
anonymous
5f1e98a0d3 Translated using Weblate (German)
Currently translated at 96.2% (154 of 160 strings)
2017-04-13 15:53:49 +02:00
Mauricio Colli
3b9a477499 Add resolution support up to 4k and 60 fps
- Up to 4k with 60 fps
    - Not every device can play in that resolution and bitrate
    - Add option to hide these high resolution greater than 1080p (2k,4k) for not clutter the menus
- Add a default resolution for the popup, wil be used when opening in popup mode from another app
2017-04-12 03:07:15 -03:00
Christian Schabesberger
e5bf98a741 move on to version 0.9.2 2017-04-11 22:51:04 +02:00
Christian Schabesberger
06fafc247e move to version 0.9.2 of NewPipeExtractor 2017-04-11 22:49:18 +02:00
Christian Schabesberger
e8bb17b631 Merge branch 'fix-next-video' of git://github.com/mauriciocolli/NewPipe into mul 2017-04-11 22:26:41 +02:00
Freddy Morán Jr
363cd07883 Translated using Weblate (Spanish)
Currently translated at 100.0% (160 of 160 strings)
2017-04-11 18:56:03 +02:00
Mladen Pejaković
2b4a9286c4 Translated using Weblate (Serbian)
Currently translated at 99.3% (159 of 160 strings)
2017-04-11 00:46:21 +02:00
Nathan Follens
34c985026f Translated using Weblate (Dutch)
Currently translated at 100.0% (160 of 160 strings)
2017-04-10 17:40:52 +02:00
naofum
4a0aa42914 Translated using Weblate (Japanese)
Currently translated at 100.0% (160 of 160 strings)
2017-04-10 17:21:54 +02:00
Mauricio Colli
746c2a15bf Migrate to fragments and improvements
- Migrate to fragments
- Fix #487
- Don't show "Open in popup mode" to channel links
- New backstack of videos
- Change the subscribers count to format using `NumberFormat`, for example some locales use `.`  others `,`, this handles it automatically (and the old method had a bug for leading zero, e.g. 4.82.125 instead of 4.082.125)
- Add string 'subscribers' for channels with more than 1 subscriber (plural)
- Popup player chooses the default format and resolution based on the new preference (format)
- Fix taskaffinity of the router activities
- Show title before loading, as it is available from the items already loaded
2017-04-09 14:34:00 -03:00
zmni
9318bb5306 Translated using Weblate (Indonesian)
Currently translated at 100.0% (160 of 160 strings)
2017-04-09 07:39:53 +02:00
Matej U
2a10ceb74f Translated using Weblate (Slovenian)
Currently translated at 100.0% (160 of 160 strings)
2017-04-08 22:08:31 +02:00
Weblate
83f4db59e2 Merge remote-tracking branch 'origin/master' 2017-04-08 21:47:50 +02:00
Olexandr Nesterenko
9f66f759ad Translated using Weblate (Ukrainian)
Currently translated at 84.9% (135 of 159 strings)
2017-04-08 21:47:47 +02:00
213 changed files with 9836 additions and 6931 deletions

View File

@@ -5,7 +5,7 @@ android:
components:
# The BuildTools version used by NewPipe
- tools
- build-tools-25.0.0
- build-tools-25.0.2
# The SDK version used to compile NewPipe
- android-25

View File

@@ -19,11 +19,16 @@ Project status:
## Screenshots
[<img src="screenshots/screenshot_1.png" width=150>](screenshots/screenshot_1.png)
[<img src="screenshots/screenshot_2.png" width=150>](screenshots/screenshot_2.png)
[<img src="screenshots/screenshot_3.png" width=150>](screenshots/screenshot_3.png)
[<img src="screenshots/screenshot_4.png" width=150>](screenshots/screenshot_4.png)
[<img src="screenshots/screenshot_5.png" width=150>](screenshots/screenshot_5.png)
[<img src="screenshots/screenshot_1.png" width=160>](screenshots/screenshot_1.png)
[<img src="screenshots/screenshot_2.png" width=160>](screenshots/screenshot_2.png)
[<img src="screenshots/screenshot_3.png" width=160>](screenshots/screenshot_3.png)
[<img src="screenshots/screenshot_4.png" width=160>](screenshots/screenshot_4.png)
[<img src="screenshots/screenshot_5.png" width=160>](screenshots/screenshot_5.png)
[<img src="screenshots/screenshot_6.png" width=160>](screenshots/screenshot_6.png)
[<img src="screenshots/screenshot_7.png" width=160>](screenshots/screenshot_7.png)
[<img src="screenshots/screenshot_8.png" width=160>](screenshots/screenshot_8.png)
[<img src="screenshots/screenshot_9.png" width=160>](screenshots/screenshot_9.png)
## Description
@@ -35,6 +40,7 @@ NewPipe does not use any Google framework libraries, or the YouTube API. It only
* Display general information about a video
* Watch YouTube videos
* Listen to YouTube videos (experimental)
* Popup mode (floating player)
* Select the streaming player to watch the video with
* Download videos
* Download audio only
@@ -46,6 +52,7 @@ NewPipe does not use any Google framework libraries, or the YouTube API. It only
* Search channels
* Watch videos from a channel
* Orbot/Tor support (not yet directly)
* 1080p/2k/4k support
### Coming Features
@@ -56,7 +63,6 @@ NewPipe does not use any Google framework libraries, or the YouTube API. It only
* Search/Watch Playlists
* Queeing videos
* Subtitles support
* 1080p support
* livestream support
* ... and many more

View File

@@ -2,14 +2,14 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion '25.0.0'
buildToolsVersion '25.0.2'
defaultConfig {
applicationId "org.schabi.newpipe"
minSdkVersion 15
targetSdkVersion 25
versionCode 28
versionName "0.9.1"
versionCode 34
versionName "0.9.7"
}
buildTypes {
release {
@@ -35,18 +35,20 @@ dependencies {
testCompile 'org.mockito:mockito-core:1.10.19'
testCompile 'org.json:json:20160810'
compile 'com.android.support:appcompat-v7:25.1.0'
compile 'com.android.support:support-v4:25.1.0'
compile 'com.android.support:design:25.1.0'
compile 'com.android.support:recyclerview-v7:25.1.0'
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:support-v4:25.3.1'
compile 'com.android.support:design:25.3.1'
compile 'com.android.support:recyclerview-v7:25.3.1'
compile 'com.google.code.gson:gson:2.7'
compile 'org.jsoup:jsoup:1.8.3'
compile 'org.mozilla:rhino:1.7.7'
compile 'info.guardianproject.netcipher:netcipher:1.2'
compile 'de.hdodenhof:circleimageview:2.0.0'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
compile 'com.github.nirhart:parallaxscroll:1.0'
compile 'com.google.code.gson:gson:2.4'
compile 'com.nononsenseapps:filepicker:3.0.0'
compile 'ch.acra:acra:4.9.0'
compile 'info.guardianproject.netcipher:netcipher:1.2'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
compile 'de.hdodenhof:circleimageview:2.0.0'
compile 'com.github.nirhart:parallaxscroll:1.0'
compile 'com.nononsenseapps:filepicker:3.0.0'
compile 'com.google.android.exoplayer:exoplayer:r2.3.1'
}

View File

@@ -19,22 +19,15 @@
tools:ignore="AllowBackup">
<activity
android:name=".MainActivity"
android:label="@string/app_name">
android:label="@string/app_name"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".detail.VideoItemDetailActivity"
android:label="@string/title_videoitem_detail"
android:launchMode="singleTask"
android:theme="@style/AppTheme">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
<activity
android:name=".player.PlayVideoActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
@@ -47,10 +40,10 @@
android:label="@string/background_player_name" />
<activity
android:name=".player.ExoPlayerActivity"
android:name=".player.MainVideoPlayer"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleInstance"
android:launchMode="singleTask"
android:theme="@style/PlayerTheme"/>
<activity
@@ -87,9 +80,6 @@
android:label="@string/app_name"
android:launchMode="singleTop"
android:theme="@style/FilePickerTheme"/>
<activity
android:name=".ChannelActivity"
android:launchMode="singleTask" />
<activity
android:name=".ReCaptchaActivity"
android:label="@string/reCaptchaActivity" />
@@ -104,7 +94,9 @@
android:resource="@xml/provider_paths" />
</provider>
<activity android:name=".RouterActivity"
<activity
android:name=".RouterActivity"
android:taskAffinity=""
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@@ -161,7 +153,9 @@
</intent-filter>
</activity>
<activity android:name=".PopupActivity"
<activity
android:name=".RouterPopupActivity"
android:taskAffinity=""
android:theme="@android:style/Theme.NoDisplay"
android:label="@string/popup_mode_share_menu_title">
<intent-filter>
@@ -182,9 +176,6 @@
<data android:pathPrefix="/embed/" />
<data android:pathPrefix="/watch" />
<data android:pathPrefix="/attribution_link" />
<!-- channel prefix -->
<data android:pathPrefix="/channel/"/>
<data android:pathPrefix="/user/"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@@ -212,9 +203,7 @@
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>

View File

@@ -20,10 +20,6 @@ package org.schabi.newpipe;
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/
import android.graphics.Bitmap;
import java.util.List;
/**
* Singleton:
* Used to send data between certain Activity/Services within the same process.
@@ -39,8 +35,5 @@ public class ActivityCommunicator {
return activityCommunicator;
}
// Thumbnail send from VideoItemDetailFragment to BackgroundPlayer
public volatile Bitmap backgroundPlayerThumbnail;
public volatile Class returnActivity;
}

View File

@@ -15,6 +15,7 @@ import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.report.AcraReportSenderFactory;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.settings.SettingsActivity;
import org.schabi.newpipe.util.ThemeHelper;
import info.guardianproject.netcipher.NetCipher;
import info.guardianproject.netcipher.proxy.OrbotHelper;
@@ -82,6 +83,8 @@ public class App extends Application {
// DO NOT REMOVE THIS FUNCTION!!!
// Otherwise downloadPathPreference has invalid value.
SettingsActivity.initSettings(this);
ThemeHelper.setTheme(getApplicationContext());
}
/**

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,14 @@
package org.schabi.newpipe;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.View;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.report.ErrorActivity;
/**
* Created by Christian Schabesberger on 01.08.16.
@@ -33,11 +33,11 @@ import org.schabi.newpipe.extractor.NewPipe;
public class ImageErrorLoadingListener implements ImageLoadingListener {
private int serviceId = -1;
private Activity activity = null;
private Context context = null;
private View rootView = null;
public ImageErrorLoadingListener(Activity activity, View rootView, int serviceId) {
this.activity = activity;
public ImageErrorLoadingListener(Context context, View rootView, int serviceId) {
this.context = context;
this.serviceId= serviceId;
this.rootView = rootView;
}
@@ -47,7 +47,7 @@ public class ImageErrorLoadingListener implements ImageLoadingListener {
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
ErrorActivity.reportError(activity,
ErrorActivity.reportError(context,
failReason.getCause(), null, rootView,
ErrorActivity.ErrorInfo.make(ErrorActivity.LOAD_IMAGE,
NewPipe.getNameOfService(serviceId), imageUri,

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,7 @@ import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.webkit.CookieManager;
import android.webkit.ValueCallback;
@@ -48,10 +49,15 @@ public class ReCaptchaActivity extends AppCompatActivity {
// Set return to Cancel by default
setResult(RESULT_CANCELED);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(R.string.reCaptcha_title);
actionBar.setDisplayShowTitleEnabled(true);
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(R.string.reCaptcha_title);
actionBar.setDisplayShowTitleEnabled(true);
}
WebView myWebView = (WebView) findViewById(R.id.reCaptchaWebView);

View File

@@ -3,19 +3,14 @@ package org.schabi.newpipe;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
import org.schabi.newpipe.detail.VideoItemDetailActivity;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.util.NavStack;
import org.schabi.newpipe.util.NavigationHelper;
import java.util.Collection;
import java.util.HashSet;
/**
/*
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
* RouterActivity .java is part of NewPipe.
*
@@ -38,7 +33,7 @@ import java.util.HashSet;
* to the part of the service which can handle the url.
*/
public class RouterActivity extends Activity {
private static final String TAG = RouterActivity.class.toString();
//private static final String TAG = "RouterActivity"
/**
* Removes invisible separators (\p{Z}) and punctuation characters including
@@ -54,6 +49,25 @@ public class RouterActivity extends Activity {
finish();
}
private void handleIntent(Intent intent) {
String videoUrl = "";
// first gather data and find service
if (intent.getData() != null) {
// this means the video was called though another app
videoUrl = intent.getData().toString();
} else if (intent.getStringExtra(Intent.EXTRA_TEXT) != null) {
//this means that vidoe was called through share menu
String extraText = intent.getStringExtra(Intent.EXTRA_TEXT);
videoUrl = getUris(extraText)[0];
}
try {
NavigationHelper.openByLink(this, videoUrl);
} catch (Exception e) {
Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show();
}
}
private static String removeHeadingGibberish(final String input) {
int start = 0;
@@ -107,50 +121,4 @@ public class RouterActivity extends Activity {
return result.toArray(new String[result.size()]);
}
private void handleIntent(Intent intent) {
String videoUrl = "";
StreamingService service = null;
// first gather data and find service
if (intent.getData() != null) {
// this means the video was called though another app
videoUrl = intent.getData().toString();
} else if(intent.getStringExtra(Intent.EXTRA_TEXT) != null) {
//this means that vidoe was called through share menu
String extraText = intent.getStringExtra(Intent.EXTRA_TEXT);
videoUrl = getUris(extraText)[0];
}
service = NewPipe.getServiceByUrl(videoUrl);
if(service == null) {
Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG)
.show();
return;
} else {
Intent callIntent = new Intent();
switch(service.getLinkTypeByUrl(videoUrl)) {
case CHANNEL:
callIntent.setClass(this, ChannelActivity.class);
break;
case STREAM:
callIntent.setClass(this, VideoItemDetailActivity.class);
callIntent.putExtra(VideoItemDetailActivity.AUTO_PLAY,
PreferenceManager.getDefaultSharedPreferences(this)
.getBoolean(
getString(R.string.autoplay_through_intent_key), false));
break;
case PLAYLIST:
Log.e(TAG, "NOT YET DEFINED");
break;
default:
Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG)
.show();
return;
}
callIntent.putExtra(NavStack.URL, videoUrl);
callIntent.putExtra(NavStack.SERVICE_ID, service.getServiceId());
startActivity(callIntent);
}
}
}

View File

@@ -4,24 +4,22 @@ import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.player.PopupVideoPlayer;
import org.schabi.newpipe.util.NavStack;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.PermissionHelper;
import java.util.Collection;
import java.util.HashSet;
/**
* This activity is thought to open video streams form an external app using the popup playser.
* This activity is thought to open video streams form an external app using the popup player.
*/
public class PopupActivity extends Activity {
private static final String TAG = RouterActivity.class.toString();
public class RouterPopupActivity extends Activity {
//private static final String TAG = "RouterPopupActivity";
/**
* Removes invisible separators (\p{Z}) and punctuation characters including
@@ -38,6 +36,45 @@ public class PopupActivity extends Activity {
}
private void handleIntent(Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& !PermissionHelper.checkSystemAlertWindowPermission(this)) {
Toast.makeText(this, R.string.msg_popup_permission, Toast.LENGTH_LONG).show();
return;
}
String videoUrl = "";
StreamingService service;
// first gather data and find service
if (intent.getData() != null) {
// this means the video was called though another app
videoUrl = intent.getData().toString();
} else if (intent.getStringExtra(Intent.EXTRA_TEXT) != null) {
//this means that vidoe was called through share menu
String extraText = intent.getStringExtra(Intent.EXTRA_TEXT);
videoUrl = getUris(extraText)[0];
}
service = NewPipe.getServiceByUrl(videoUrl);
if (service == null) {
Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show();
return;
}
Intent callIntent = new Intent(this, PopupVideoPlayer.class);
switch (service.getLinkTypeByUrl(videoUrl)) {
case STREAM:
break;
default:
Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show();
return;
}
callIntent.putExtra(Constants.KEY_URL, videoUrl);
callIntent.putExtra(Constants.KEY_SERVICE_ID, service.getServiceId());
startService(callIntent);
}
private static String removeHeadingGibberish(final String input) {
int start = 0;
for (int i = input.indexOf("://") - 1; i >= 0; i--) {
@@ -90,47 +127,4 @@ public class PopupActivity extends Activity {
return result.toArray(new String[result.size()]);
}
private void handleIntent(Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& !PermissionHelper.checkSystemAlertWindowPermission(this)) {
Toast.makeText(this, R.string.msg_popup_permission, Toast.LENGTH_LONG).show();
return;
}
String videoUrl = "";
StreamingService service = null;
// first gather data and find service
if (intent.getData() != null) {
// this means the video was called though another app
videoUrl = intent.getData().toString();
} else if (intent.getStringExtra(Intent.EXTRA_TEXT) != null) {
//this means that vidoe was called through share menu
String extraText = intent.getStringExtra(Intent.EXTRA_TEXT);
videoUrl = getUris(extraText)[0];
}
service = NewPipe.getServiceByUrl(videoUrl);
if (service == null) {
Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG)
.show();
return;
} else {
Intent callIntent = new Intent();
switch (service.getLinkTypeByUrl(videoUrl)) {
case STREAM:
callIntent.setClass(this, PopupVideoPlayer.class);
break;
case PLAYLIST:
Log.e(TAG, "NOT YET DEFINED");
break;
default:
Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show();
return;
}
callIntent.putExtra(NavStack.URL, videoUrl);
callIntent.putExtra(NavStack.SERVICE_ID, service.getServiceId());
startService(callIntent);
}
}
}

View File

@@ -1,28 +0,0 @@
package org.schabi.newpipe;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
public class ThemableActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (PreferenceManager.getDefaultSharedPreferences(this)
.getString("theme", getResources().getString(R.string.light_theme_title)).
equals(getResources().getString(R.string.dark_theme_title))) {
setTheme(R.style.DarkTheme);
}
}
@Override
protected void onResume() {
super.onResume();
if (PreferenceManager.getDefaultSharedPreferences(this)
.getString("theme", getResources().getString(R.string.light_theme_title)).
equals(getResources().getString(R.string.dark_theme_title))) {
setTheme(R.style.DarkTheme);
}
}
}

View File

@@ -1,250 +0,0 @@
package org.schabi.newpipe.detail;
import android.app.Activity;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipe.extractor.services.youtube.YoutubeStreamExtractor;
import org.schabi.newpipe.extractor.stream_info.StreamExtractor;
import org.schabi.newpipe.extractor.stream_info.StreamInfo;
import org.schabi.newpipe.report.ErrorActivity;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Extract {@link StreamInfo} with {@link StreamExtractor} from the given url of the given service
*/
@SuppressWarnings("WeakerAccess")
public class StreamExtractorWorker extends Thread {
private static final String TAG = "StreamExtractorWorker";
private Activity activity;
private final String videoUrl;
private final int serviceId;
private OnStreamInfoReceivedListener callback;
private final AtomicBoolean isRunning = new AtomicBoolean(false);
private final Handler handler = new Handler();
public interface OnStreamInfoReceivedListener {
void onReceive(StreamInfo info);
void onError(int messageId);
void onReCaptchaException();
void onBlockedByGemaError();
void onContentErrorWithMessage(int messageId);
void onContentError();
}
public StreamExtractorWorker(Activity activity, String videoUrl, int serviceId, OnStreamInfoReceivedListener callback) {
this.serviceId = serviceId;
this.videoUrl = videoUrl;
this.activity = activity;
this.callback = callback;
}
/**
* Returns a new instance <b>already</b> started of {@link StreamExtractorWorker}.<br>
* The caller is responsible to check if {@link StreamExtractorWorker#isRunning()}, or {@link StreamExtractorWorker#cancel()} it
*
* @param serviceId id of the request service
* @param url videoUrl of the service (e.g. https://www.youtube.com/watch?v=HyHNuVaZJ-k)
* @param activity activity for error reporting purposes
* @param callback listener that will be called-back when events occur (check {@link OnStreamInfoReceivedListener})
* @return new instance already started of {@link StreamExtractorWorker}
*/
public static StreamExtractorWorker startExtractorThread(int serviceId, String url, Activity activity, OnStreamInfoReceivedListener callback) {
StreamExtractorWorker extractorThread = getExtractorThread(serviceId, url, activity, callback);
extractorThread.start();
return extractorThread;
}
/**
* Returns a new instance of {@link StreamExtractorWorker}.<br>
* The caller is responsible to check if {@link StreamExtractorWorker#isRunning()}, or {@link StreamExtractorWorker#cancel()}
* when it doesn't need it anymore
* <p>
* <b>Note:</b> this instance is <b>not</b> started yet
*
* @param serviceId id of the request service
* @param url videoUrl of the service (e.g. https://www.youtube.com/watch?v=HyHNuVaZJ-k)
* @param activity activity for error reporting purposes
* @param callback listener that will be called-back when events occur (check {@link OnStreamInfoReceivedListener})
* @return instance of {@link StreamExtractorWorker}
*/
public static StreamExtractorWorker getExtractorThread(int serviceId, String url, Activity activity, OnStreamInfoReceivedListener callback) {
return new StreamExtractorWorker(activity, url, serviceId, callback);
}
@Override
//Just ignore the errors for now
@SuppressWarnings("ConstantConditions")
public void run() {
// TODO: Improve error checking
// and this method in general
StreamInfo streamInfo = null;
StreamingService service;
try {
service = NewPipe.getService(serviceId);
} catch (Exception e) {
e.printStackTrace();
ErrorActivity.reportError(handler, activity, e, VideoItemDetailActivity.class, null,
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
"", videoUrl, R.string.could_not_get_stream));
return;
}
try {
isRunning.set(true);
StreamExtractor streamExtractor = service.getExtractorInstance(videoUrl);
streamInfo = StreamInfo.getVideoInfo(streamExtractor);
final StreamInfo info = streamInfo;
if (callback != null) handler.post(new Runnable() {
@Override
public void run() {
callback.onReceive(info);
}
});
isRunning.set(false);
// look for errors during extraction
// this if statement only covers extra information.
// if these are not available or caused an error, they are just not available
// but don't render the stream information unusalbe.
if (streamInfo != null && !streamInfo.errors.isEmpty()) {
Log.e(TAG, "OCCURRED ERRORS DURING EXTRACTION:");
for (Throwable e : streamInfo.errors) {
e.printStackTrace();
Log.e(TAG, "------");
}
View rootView = activity != null ? activity.findViewById(R.id.video_item_detail) : null;
ErrorActivity.reportError(handler, activity,
streamInfo.errors, null, rootView,
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
service.getServiceInfo().name, videoUrl, 0 /* no message for the user */));
}
// These errors render the stream information unusable.
} catch (ReCaptchaException e) {
if (callback != null) handler.post(new Runnable() {
@Override
public void run() {
callback.onReCaptchaException();
}
});
} catch (IOException e) {
if (callback != null) handler.post(new Runnable() {
@Override
public void run() {
callback.onError(R.string.network_error);
}
});
if (callback != null) e.printStackTrace();
} catch (YoutubeStreamExtractor.DecryptException de) {
// custom service related exceptions
ErrorActivity.reportError(handler, activity, de, VideoItemDetailActivity.class, null,
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
service.getServiceInfo().name, videoUrl, R.string.youtube_signature_decryption_error));
handler.post(new Runnable() {
@Override
public void run() {
activity.finish();
}
});
de.printStackTrace();
} catch (YoutubeStreamExtractor.GemaException ge) {
if (callback != null) handler.post(new Runnable() {
@Override
public void run() {
callback.onBlockedByGemaError();
}
});
} catch (YoutubeStreamExtractor.LiveStreamException e) {
if (callback != null) handler.post(new Runnable() {
@Override
public void run() {
callback.onContentErrorWithMessage(R.string.live_streams_not_supported);
}
});
}
// ----------------------------------------
catch (StreamExtractor.ContentNotAvailableException e) {
if (callback != null) handler.post(new Runnable() {
@Override
public void run() {
callback.onContentError();
}
});
e.printStackTrace();
} catch (StreamInfo.StreamExctractException e) {
if (!streamInfo.errors.isEmpty()) {
// !!! if this case ever kicks in someone gets kicked out !!!
ErrorActivity.reportError(handler, activity, e, VideoItemDetailActivity.class, null,
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
service.getServiceInfo().name, videoUrl, R.string.could_not_get_stream));
} else {
ErrorActivity.reportError(handler, activity, streamInfo.errors, VideoItemDetailActivity.class, null,
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
service.getServiceInfo().name, videoUrl, R.string.could_not_get_stream));
}
handler.post(new Runnable() {
@Override
public void run() {
activity.finish();
}
});
e.printStackTrace();
} catch (ParsingException e) {
ErrorActivity.reportError(handler, activity, e, VideoItemDetailActivity.class, null,
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
service.getServiceInfo().name, videoUrl, R.string.parsing_error));
handler.post(new Runnable() {
@Override
public void run() {
activity.finish();
}
});
e.printStackTrace();
} catch (Exception e) {
ErrorActivity.reportError(handler, activity, e, VideoItemDetailActivity.class, null,
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
service.getServiceInfo().name, videoUrl, R.string.general_error));
handler.post(new Runnable() {
@Override
public void run() {
activity.finish();
}
});
e.printStackTrace();
}
}
/**
* Return true if the extraction is not completed yet
*
* @return the value of the AtomicBoolean {@link #isRunning}
*/
public boolean isRunning() {
return isRunning.get();
}
/**
* Cancel this ExtractorThread, setting the callback to null, the AtomicBoolean {@link #isRunning} to false and interrupt this thread.
* <p>
* <b>Note:</b> Any I/O that is active in the moment that this method is called will be canceled and a Exception will be thrown, because of the {@link #interrupt()}.<br>
* This is useful when you don't want the resulting {@link StreamInfo} anymore, but don't want to waste bandwidth, otherwise it'd run till it receives the StreamInfo.
*/
public void cancel() {
this.callback = null;
this.isRunning.set(false);
this.interrupt();
}
}

View File

@@ -8,7 +8,6 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.NavUtils;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
@@ -26,13 +25,11 @@ import android.widget.TextView;
import android.widget.Toast;
import org.schabi.newpipe.R;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.settings.NewPipeSettings;
import org.schabi.newpipe.settings.SettingsActivity;
import org.schabi.newpipe.util.ThemeHelper;
import java.io.File;
import java.util.Vector;
import us.shandian.giga.service.DownloadManagerService;
import us.shandian.giga.ui.fragment.AllMissionsFragment;
@@ -64,17 +61,19 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
i.setClass(this, DownloadManagerService.class);
startService(i);
ThemeHelper.setTheme(this);
super.onCreate(savedInstanceState);
ThemeHelper.setTheme(this, true);
setContentView(R.layout.activity_downloader);
//noinspection ConstantConditions
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// its ok if this fails, we will catch that error later, and send it as report
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(R.string.downloads_title);
actionBar.setDisplayShowTitleEnabled(true);
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(R.string.downloads_title);
actionBar.setDisplayShowTitleEnabled(true);
}
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
@@ -159,7 +158,7 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
name.setText(getIntent().getStringExtra("fileName"));
toolbar.setTitle(R.string.add);
toolbar.setNavigationIcon(R.drawable.ic_arrow_back_black_24dp);
toolbar.setNavigationIcon(ThemeHelper.isLightThemeSelected(this) ? R.drawable.ic_arrow_back_black_24dp : R.drawable.ic_arrow_back_white_24dp);
toolbar.inflateMenu(R.menu.dialog_url);
// Show the dialog
@@ -183,7 +182,7 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
if (item.getItemId() == R.id.okay) {
String location;
if(audioButton.isChecked()) {
if (audioButton.isChecked()) {
location = NewPipeSettings.getAudioDownloadPath(DownloadActivity.this);
} else {
location = NewPipeSettings.getVideoDownloadPath(DownloadActivity.this);
@@ -201,7 +200,7 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
audioButton.isChecked(), threads.getProgress() + 1);
mFragment.notifyChange();
mPrefs.edit().putInt(THREADS, threads.getProgress() + 1).commit();
mPrefs.edit().putInt(THREADS, threads.getProgress() + 1).apply();
mPendingUrl = null;
dialog.dismiss();
}

View File

@@ -1,165 +0,0 @@
package org.schabi.newpipe.download;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import org.schabi.newpipe.R;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import javax.net.ssl.HttpsURLConnection;
import info.guardianproject.netcipher.NetCipher;
/**
* Created by Christian Schabesberger on 14.08.15.
*
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
* FileDownloader.java is part of NewPipe.
*
* NewPipe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NewPipe is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/
// TODO: FOR HEAVEN SAKE !!! DO NOT SIMPLY USE ASYNCTASK. MAKE THIS A PROPER SERVICE !!!
public class FileDownloader extends AsyncTask<Void, Integer, Void> {
public static final String TAG = "FileDownloader";
private NotificationManager nm;
private NotificationCompat.Builder builder;
private int notifyId = 0x1234;
private int fileSize = 0xffffffff;
private final Context context;
private final String fileURL;
private final File saveFilePath;
private final String title;
private final String debugContext;
public FileDownloader(Context context, String fileURL, File saveFilePath, String title) {
this.context = context;
this.fileURL = fileURL;
this.saveFilePath = saveFilePath;
this.title = title;
this.debugContext = "'" + fileURL +
"' => '" + saveFilePath + "'";
}
/**
* Downloads a file from a URL in the background using an {@link AsyncTask}.
*
* @param fileURL HTTP URL of the file to be downloaded
* @param saveFilePath path of the directory to save the file
* @param title
* @throws IOException
*/
public static void downloadFile(final Context context, final String fileURL, final File saveFilePath, String title) {
new FileDownloader(context, fileURL, saveFilePath, title).execute();
}
/** AsyncTask impl: executed in gui thread */
@Override
protected void onPreExecute() {
super.onPreExecute();
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Drawable icon = context.getResources().getDrawable(R.mipmap.ic_launcher);
builder = new NotificationCompat.Builder(context)
.setSmallIcon(android.R.drawable.stat_sys_download)
.setLargeIcon(((BitmapDrawable) icon).getBitmap())
.setContentTitle(saveFilePath.getName())
.setContentText(saveFilePath.getAbsolutePath())
.setProgress(fileSize, 0, false);
nm.notify(notifyId, builder.build());
}
/** AsyncTask impl: executed in background thread does the download */
@Override
protected Void doInBackground(Void... voids) {
HttpsURLConnection con = null;
InputStream inputStream = null;
FileOutputStream outputStream = null;
try {
con = NetCipher.getHttpsURLConnection(fileURL);
int responseCode = con.getResponseCode();
// always check HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK) {
fileSize = con.getContentLength();
inputStream = new BufferedInputStream(con.getInputStream());
outputStream = new FileOutputStream(saveFilePath);
int bufferSize = 8192;
int downloaded = 0;
int bytesRead = -1;
byte[] buffer = new byte[bufferSize];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
downloaded += bytesRead;
if (downloaded % 50000 < bufferSize) {
publishProgress(downloaded);
}
}
publishProgress(bufferSize);
} else {
Log.i(TAG, "No file to download. Server replied HTTP code: " + responseCode);
}
} catch (IOException e) {
Log.e(TAG, "No file to download. Server replied HTTP code: ", e);
e.printStackTrace();
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (con != null) {
con.disconnect();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... progress) {
builder.setProgress(fileSize, progress[0], false);
nm.notify(notifyId, builder.build());
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
nm.cancel(notifyId);
}
}

View File

@@ -0,0 +1,179 @@
package org.schabi.newpipe.fragments;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.AttrRes;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.schabi.newpipe.util.AnimationUtils.animateView;
public abstract class BaseFragment extends Fragment {
protected final String TAG = "BaseFragment@" + Integer.toHexString(hashCode());
protected static final boolean DEBUG = MainActivity.DEBUG;
protected AppCompatActivity activity;
protected OnItemSelectedListener onItemSelectedListener;
protected AtomicBoolean isLoading = new AtomicBoolean(false);
protected AtomicBoolean wasLoading = new AtomicBoolean(false);
protected static final ImageLoader imageLoader = ImageLoader.getInstance();
protected static final DisplayImageOptions displayImageOptions =
new DisplayImageOptions.Builder().displayer(new FadeInBitmapDisplayer(400)).cacheInMemory(false).build();
/*//////////////////////////////////////////////////////////////////////////
// Views
//////////////////////////////////////////////////////////////////////////*/
protected Toolbar toolbar;
protected View errorPanel;
protected Button errorButtonRetry;
protected TextView errorTextView;
protected ProgressBar loadingProgressBar;
//protected SwipeRefreshLayout swipeRefreshLayout;
/*//////////////////////////////////////////////////////////////////////////
// Fragment's Lifecycle
//////////////////////////////////////////////////////////////////////////*/
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (DEBUG) Log.d(TAG, "onAttach() called with: context = [" + context + "]");
activity = (AppCompatActivity) context;
onItemSelectedListener = (OnItemSelectedListener) context;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (DEBUG) Log.d(TAG, "onCreate() called with: savedInstanceState = [" + savedInstanceState + "]");
isLoading.set(false);
setHasOptionsMenu(true);
}
@Override
public void onViewCreated(View rootView, Bundle savedInstanceState) {
if (DEBUG) Log.d(TAG, "onViewCreated() called with: rootView = [" + rootView + "], savedInstanceState = [" + savedInstanceState + "]");
initViews(rootView, savedInstanceState);
initListeners();
wasLoading.set(false);
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (DEBUG) Log.d(TAG, "onDestroyView() called");
toolbar = null;
errorPanel = null;
errorButtonRetry = null;
errorTextView = null;
}
/*//////////////////////////////////////////////////////////////////////////
// Init
//////////////////////////////////////////////////////////////////////////*/
protected void initViews(View rootView, Bundle savedInstanceState) {
toolbar = (Toolbar) activity.findViewById(R.id.toolbar);
loadingProgressBar = (ProgressBar) rootView.findViewById(R.id.loading_progress_bar);
//swipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_refresh);
errorPanel = rootView.findViewById(R.id.error_panel);
errorButtonRetry = (Button) rootView.findViewById(R.id.error_button_retry);
errorTextView = (TextView) rootView.findViewById(R.id.error_message_view);
}
protected void initListeners() {
errorButtonRetry.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onRetryButtonClicked();
}
});
}
protected abstract void reloadContent();
protected void onRetryButtonClicked() {
if (DEBUG) Log.d(TAG, "onRetryButtonClicked() called");
reloadContent();
}
/*//////////////////////////////////////////////////////////////////////////
// Utils
//////////////////////////////////////////////////////////////////////////*/
protected void setErrorMessage(String message, boolean showRetryButton) {
if (errorTextView == null || activity == null) return;
errorTextView.setText(message);
if (showRetryButton) animateView(errorButtonRetry, true, 300);
else animateView(errorButtonRetry, false, 0);
animateView(errorPanel, true, 300);
isLoading.set(false);
animateView(loadingProgressBar, false, 200);
}
protected int getResourceIdFromAttr(@AttrRes int attr) {
TypedArray a = activity.getTheme().obtainStyledAttributes(new int[]{attr});
int attributeResourceId = a.getResourceId(0, 0);
a.recycle();
return attributeResourceId;
}
public static void showMenuTooltip(View v, String message) {
final int[] screenPos = new int[2];
final Rect displayFrame = new Rect();
v.getLocationOnScreen(screenPos);
v.getWindowVisibleDisplayFrame(displayFrame);
final Context context = v.getContext();
final int width = v.getWidth();
final int height = v.getHeight();
final int midy = screenPos[1] + height / 2;
int referenceX = screenPos[0] + width / 2;
if (ViewCompat.getLayoutDirection(v) == View.LAYOUT_DIRECTION_LTR) {
final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
referenceX = screenWidth - referenceX; // mirror
}
Toast cheatSheet = Toast.makeText(context, message, Toast.LENGTH_SHORT);
if (midy < displayFrame.height()) {
// Show along the top; follow action buttons
cheatSheet.setGravity(Gravity.TOP | Gravity.END, referenceX,
screenPos[1] + height - displayFrame.top);
} else {
// Show along the bottom center
cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height);
}
cheatSheet.show();
}
}

View File

@@ -0,0 +1,76 @@
package org.schabi.newpipe.fragments;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.util.NavigationHelper;
public class MainFragment extends Fragment {
private final String TAG = "MainFragment@" + Integer.toHexString(hashCode());
private static final boolean DEBUG = MainActivity.DEBUG;
private AppCompatActivity activity;
/*//////////////////////////////////////////////////////////////////////////
// Fragment's LifeCycle
//////////////////////////////////////////////////////////////////////////*/
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (DEBUG) Log.d(TAG, "onAttach() called with: context = [" + context + "]");
activity = ((AppCompatActivity) context);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (DEBUG) Log.d(TAG, "onCreate() called with: savedInstanceState = [" + savedInstanceState + "]");
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (DEBUG) Log.d(TAG, "onCreateView() called with: inflater = [" + inflater + "], container = [" + container + "], savedInstanceState = [" + savedInstanceState + "]");
return inflater.inflate(R.layout.fragment_main, container, false);
}
/*//////////////////////////////////////////////////////////////////////////
// Menu
//////////////////////////////////////////////////////////////////////////*/
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
if (DEBUG) Log.d(TAG, "onCreateOptionsMenu() called with: menu = [" + menu + "], inflater = [" + inflater + "]");
inflater.inflate(R.menu.main_fragment_menu, menu);
ActionBar supportActionBar = activity.getSupportActionBar();
if (supportActionBar != null) {
supportActionBar.setDisplayShowTitleEnabled(false);
supportActionBar.setDisplayHomeAsUpEnabled(false);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_search:
NavigationHelper.openSearch(activity, 0, "");
return true;
}
return super.onOptionsItemSelected(item);
}
}

View File

@@ -0,0 +1,10 @@
package org.schabi.newpipe.fragments;
import org.schabi.newpipe.extractor.StreamingService;
/**
* Interface for communication purposes between activity and fragment
*/
public interface OnItemSelectedListener {
void onItemSelected(StreamingService.LinkType linkType, int serviceId, String url, String name);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,163 @@
package org.schabi.newpipe.fragments.detail;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Spinner;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.stream_info.VideoStream;
import org.schabi.newpipe.util.Utils;
import java.util.List;
/**
* Created by Christian Schabesberger on 18.08.15.
* <p>
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
* DetailsMenuHandler.java is part of NewPipe.
* <p>
* NewPipe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* <p>
* NewPipe is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* <p>
* You should have received a copy of the GNU General Public License
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/
@SuppressWarnings("WeakerAccess")
class ActionBarHandler {
private static final String TAG = "ActionBarHandler";
private AppCompatActivity activity;
private int selectedVideoStream = -1;
private SharedPreferences defaultPreferences;
private Menu menu;
// Only callbacks are listed here, there are more actions which don't need a callback.
// those are edited directly. Typically VideoDetailFragment will implement those callbacks.
private OnActionListener onShareListener;
private OnActionListener onOpenInBrowserListener;
private OnActionListener onDownloadListener;
private OnActionListener onPlayWithKodiListener;
// Triggered when a stream related action is triggered.
public interface OnActionListener {
void onActionSelected(int selectedStreamId);
}
public ActionBarHandler(AppCompatActivity activity) {
this.activity = activity;
}
public void setupStreamList(final List<VideoStream> videoStreams, Spinner toolbarSpinner) {
if (activity == null) return;
selectedVideoStream = 0;
int defaultResolutionIndex = Utils.getDefaultResolution(activity, videoStreams);
boolean isExternalPlayerEnabled = PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(activity.getString(R.string.use_external_video_player_key), false);
toolbarSpinner.setAdapter(new SpinnerToolbarAdapter(activity, videoStreams, isExternalPlayerEnabled));
toolbarSpinner.setSelection(defaultResolutionIndex);
toolbarSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
selectedVideoStream = position;
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
public void setupMenu(Menu menu, MenuInflater inflater) {
this.menu = menu;
// CAUTION set item properties programmatically otherwise it would not be accepted by
// appcompat itemsinflater.inflate(R.menu.videoitem_detail, menu);
defaultPreferences = PreferenceManager.getDefaultSharedPreferences(activity);
inflater.inflate(R.menu.video_detail_menu, menu);
updateItemsVisibility();
}
public void updateItemsVisibility(){
showPlayWithKodiAction(defaultPreferences.getBoolean(activity.getString(R.string.show_play_with_kodi_key), false));
}
public boolean onItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.menu_item_share: {
if (onShareListener != null) {
onShareListener.onActionSelected(selectedVideoStream);
}
return true;
}
case R.id.menu_item_openInBrowser: {
if (onOpenInBrowserListener != null) {
onOpenInBrowserListener.onActionSelected(selectedVideoStream);
}
return true;
}
case R.id.menu_item_download:
if (onDownloadListener != null) {
onDownloadListener.onActionSelected(selectedVideoStream);
}
return true;
case R.id.action_play_with_kodi:
if (onPlayWithKodiListener != null) {
onPlayWithKodiListener.onActionSelected(selectedVideoStream);
}
return true;
default:
Log.e(TAG, "Menu Item not known");
}
return false;
}
public int getSelectedVideoStream() {
return selectedVideoStream;
}
public void setOnShareListener(OnActionListener listener) {
onShareListener = listener;
}
public void setOnOpenInBrowserListener(OnActionListener listener) {
onOpenInBrowserListener = listener;
}
public void setOnDownloadListener(OnActionListener listener) {
onDownloadListener = listener;
}
public void setOnPlayWithKodiListener(OnActionListener listener) {
onPlayWithKodiListener = listener;
}
public void showDownloadAction(boolean visible) {
menu.findItem(R.id.menu_item_download).setVisible(visible);
}
public void showPlayWithKodiAction(boolean visible) {
menu.findItem(R.id.action_play_with_kodi).setVisible(visible);
}
}

View File

@@ -0,0 +1,74 @@
package org.schabi.newpipe.fragments.detail;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.MediaFormat;
import org.schabi.newpipe.extractor.stream_info.VideoStream;
import java.util.List;
public class SpinnerToolbarAdapter extends BaseAdapter {
private final List<VideoStream> videoStreams;
private final boolean showIconNoAudio;
private final Context context;
public SpinnerToolbarAdapter(Context context, List<VideoStream> videoStreams, boolean showIconNoAudio) {
this.context = context;
this.videoStreams = videoStreams;
this.showIconNoAudio = showIconNoAudio;
}
@Override
public int getCount() {
return videoStreams.size();
}
@Override
public Object getItem(int position) {
return videoStreams.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return getCustomView(position, convertView, parent, true);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return getCustomView(((Spinner) parent).getSelectedItemPosition(), convertView, parent, false);
}
private View getCustomView(int position, View convertView, ViewGroup parent, boolean isDropdownItem) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.resolutions_spinner_item, parent, false);
}
ImageView woSoundIcon = (ImageView) convertView.findViewById(R.id.wo_sound_icon);
TextView text = (TextView) convertView.findViewById(android.R.id.text1);
VideoStream item = (VideoStream) getItem(position);
text.setText(MediaFormat.getNameById(item.format) + " " + item.resolution);
int visibility = !showIconNoAudio ? View.GONE
: item.isVideoOnly ? View.VISIBLE
: isDropdownItem ? View.INVISIBLE
: View.GONE;
woSoundIcon.setVisibility(visibility);
return convertView;
}
}

View File

@@ -0,0 +1,42 @@
package org.schabi.newpipe.fragments.detail;
import org.schabi.newpipe.extractor.stream_info.StreamInfo;
import java.io.Serializable;
@SuppressWarnings("WeakerAccess")
public class StackItem implements Serializable {
private String title, url;
private StreamInfo info;
public StackItem(String url, String title) {
this.title = title;
this.url = url;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public String getUrl() {
return url;
}
public void setInfo(StreamInfo info) {
this.info = info;
}
public StreamInfo getInfo() {
return info;
}
@Override
public String toString() {
return getUrl() + " > " + getTitle();
}
}

View File

@@ -0,0 +1,85 @@
package org.schabi.newpipe.fragments.detail;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.extractor.stream_info.StreamInfo;
import java.util.Iterator;
import java.util.LinkedHashMap;
@SuppressWarnings("WeakerAccess")
public class StreamInfoCache {
private static String TAG = "StreamInfoCache@";
private static final boolean DEBUG = MainActivity.DEBUG;
private static final StreamInfoCache instance = new StreamInfoCache();
private static final int MAX_ITEMS_ON_CACHE = 20;
private final LinkedHashMap<String, StreamInfo> myCache = new LinkedHashMap<>();
private StreamInfoCache() {
TAG += "" + Integer.toHexString(hashCode());
}
public static StreamInfoCache getInstance() {
if (DEBUG) Log.d(TAG, "getInstance() called");
return instance;
}
public boolean hasKey(@NonNull String url) {
if (DEBUG) Log.d(TAG, "hasKey() called with: url = [" + url + "]");
return !TextUtils.isEmpty(url) && myCache.containsKey(url) && myCache.get(url) != null;
}
public StreamInfo getFromKey(@NonNull String url) {
if (DEBUG) Log.d(TAG, "getFromKey() called with: url = [" + url + "]");
return myCache.get(url);
}
public void putInfo(@NonNull StreamInfo info) {
if (DEBUG) Log.d(TAG, "putInfo() called with: info = [" + info + "]");
putInfo(info.webpage_url, info);
}
public void putInfo(@NonNull String url, @NonNull StreamInfo info) {
if (DEBUG) Log.d(TAG, "putInfo() called with: url = [" + url + "], info = [" + info + "]");
myCache.put(url, info);
}
public void removeInfo(@NonNull StreamInfo info) {
if (DEBUG) Log.d(TAG, "removeInfo() called with: info = [" + info + "]");
myCache.remove(info.webpage_url);
}
public void removeInfo(@NonNull String url) {
if (DEBUG) Log.d(TAG, "removeInfo() called with: url = [" + url + "]");
myCache.remove(url);
}
@SuppressWarnings("unused")
public void clearCache() {
if (DEBUG) Log.d(TAG, "clearCache() called");
myCache.clear();
}
public void removeOldEntries() {
if (DEBUG) Log.d(TAG, "removeOldEntries() called , size = " + getSize());
if (getSize() > MAX_ITEMS_ON_CACHE) {
Iterator<String> iterator = myCache.keySet().iterator();
while (iterator.hasNext()) {
iterator.next();
iterator.remove();
if (DEBUG) Log.d(TAG, "getSize() = " + getSize());
if (getSize() <= MAX_ITEMS_ON_CACHE) break;
}
}
}
public int getSize() {
return myCache.size();
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
package org.schabi.newpipe.search_fragment;
package org.schabi.newpipe.fragments.search;
import android.content.Context;
import android.database.Cursor;
@@ -75,6 +75,11 @@ public class SuggestionListAdapter extends ResourceCursorAdapter {
return ((Cursor) getItem(position)).getString(INDEX_TITLE);
}
@Override
public CharSequence convertToString(Cursor cursor) {
return cursor.getString(INDEX_TITLE);
}
private class ViewHolder {
private final TextView suggestionTitle;
private ViewHolder(View view) {

View File

@@ -1,7 +1,6 @@
package org.schabi.newpipe.info_list;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.schabi.newpipe.R;
@@ -35,16 +34,17 @@ public class ChannelInfoItemHolder extends InfoItemHolder {
public final TextView itemSubscriberCountView;
public final TextView itemVideoCountView;
public final TextView itemChannelDescriptionView;
public final Button itemButton;
public final View itemRoot;
ChannelInfoItemHolder(View v) {
super(v);
itemRoot = v.findViewById(R.id.itemRoot);
itemThumbnailView = (CircleImageView) v.findViewById(R.id.itemThumbnailView);
itemChannelTitleView = (TextView) v.findViewById(R.id.itemChannelTitleView);
itemSubscriberCountView = (TextView) v.findViewById(R.id.itemSubscriberCountView);
itemVideoCountView = (TextView) v.findViewById(R.id.itemVideoCountView);
itemChannelDescriptionView = (TextView) v.findViewById(R.id.itemChannelDescriptionView);
itemButton = (Button) v.findViewById(R.id.item_button);
}
@Override

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