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

Compare commits

...

303 Commits

Author SHA1 Message Date
TobiGr
ba151a8b83 Release 0.19.1 2020-03-31 00:24:13 +02:00
TobiGr
a5153f5375 Improve database migration SQL statement 2020-03-31 00:20:13 +02:00
Tobias Groza
4899f01d6e Merge pull request #3307 from mauriciocolli/hotfix-db-migration
Hotfix for the latest database migration
2020-03-30 23:37:13 +02:00
Mauricio Colli
e6b3107997 Add tests for database migration to version 3 handling null values 2020-03-30 15:50:47 -03:00
Mauricio Colli
053440c4a8 Fix handling of null values in database migration to version 3
Some values prior to this version could be null, this wasn't handled
properly before.
2020-03-30 15:50:46 -03:00
Tobias Groza
dd682013f9 Merge pull request #3267 from TeamNewPipe/release_0.19.0
Release 0.19.0
2020-03-29 18:57:28 +02:00
TobiGr
7f21975971 release version 0.19.0 (900) 2020-03-28 20:32:20 +01:00
TobiGr
bcd77031f3 Add changelog 2020-03-28 20:32:20 +01:00
Tobias Groza
505a689268 Merge pull request #3292 from vlt23/dev
Fix UI crash in Settings, Content (chinese language)
2020-03-28 20:31:47 +01:00
vlt23
3c3848d4f8 Fix UI crash in Settings, Content (chinese language) 2020-03-28 20:12:17 +01:00
TobiGr
949150f9ff Update extractor version 2020-03-28 19:18:37 +01:00
Tobias Groza
7c72f17fad Merge pull request #3279 from mauriciocolli/fix-not-found-handling
Handle content not available exception more comprehensively
2020-03-28 19:10:43 +01:00
Mauricio Colli
b4cabe23e3 Handle content not available exception more comprehensively 2020-03-28 14:54:52 -03:00
Tobias Groza
40de014732 Merge pull request #3283 from Stypox/fix-mute-button
Fix mute button inflation problems on API<21
2020-03-28 18:38:36 +01:00
Mauricio Colli
f9b718f1eb Use correct class for getting a vector drawable in older APIs 2020-03-28 14:30:47 -03:00
Tobias Groza
d051df9599 Merge pull request #3278 from mauriciocolli/fix-url-parsing-share
Fix url parsing from shared content
2020-03-28 18:15:26 +01:00
Mauricio Colli
4dc28989c8 Fix bug when searching for urls from shared content 2020-03-28 14:06:11 -03:00
Mauricio Colli
f133bbf499 Introduce a proper way to find urls in a string input 2020-03-28 14:06:09 -03:00
Tobias Groza
bbd8751f62 Merge pull request #3281 from mauriciocolli/fix-main-screen-menu-creation
Temporary fix for main screen menu visibility
2020-03-28 12:15:21 +01:00
Mauricio Colli
d8e83dabc6 Temporary: Fix menu visibility when restoring state in the pager adapter
When restoring the state of the adapter, all the fragments' menu
visibility were set to false, effectively disabling the menu from the
user until he switched pages or another event that triggered the menu to
be visible again happened.

FragmentStatePagerAdapter is deprecated and should be replaced with its
ViewPager2 counterpart, until then, this should do it.
2020-03-27 11:30:38 -03:00
TobiGr
c6eaed76f3 Translation fixes 2020-03-26 23:09:49 +01:00
TobiGr
6ce338b2d0 Weblate ... 2020-03-26 21:56:30 +01:00
TobiGr
aa87f10b6a Merge remote-tracking branch 'Weblate/dev' into dev 2020-03-26 21:45:46 +01:00
Xiang Xu
9a980f9341 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (560 of 560 strings)
2020-03-26 20:10:32 +01:00
MohammedSR Vevo
544751895e Translated using Weblate (Kurdish)
Currently translated at 99.8% (559 of 560 strings)
2020-03-26 20:10:30 +01:00
B0pol
082b7fa0ec Translated using Weblate (French)
Currently translated at 100.0% (560 of 560 strings)
2020-03-26 20:10:27 +01:00
wb9688
4d23cf7746 Translated using Weblate (Dutch)
Currently translated at 97.1% (544 of 560 strings)
2020-03-26 20:10:26 +01:00
pjammo
c687d832fa Translated using Weblate (Italian)
Currently translated at 99.6% (558 of 560 strings)
2020-03-26 20:10:21 +01:00
Yaron Shahrabani
4cd5afa3fb Translated using Weblate (Hebrew)
Currently translated at 100.0% (560 of 560 strings)
2020-03-26 20:10:20 +01:00
anonymous
39bb0f4c3e Translated using Weblate (Croatian)
Currently translated at 89.6% (502 of 560 strings)
2020-03-26 20:10:19 +01:00
Stjepan
aef673abd1 Translated using Weblate (Croatian)
Currently translated at 89.6% (502 of 560 strings)
2020-03-26 20:10:19 +01:00
zeritti
c4f58cb6e2 Translated using Weblate (Czech)
Currently translated at 100.0% (560 of 560 strings)
2020-03-26 20:10:10 +01:00
AioiLight
6e3170f5c7 Translated using Weblate (Japanese)
Currently translated at 100.0% (560 of 560 strings)
2020-03-26 20:10:09 +01:00
Enol P
782b983354 Translated using Weblate (Asturian)
Currently translated at 51.2% (287 of 560 strings)
2020-03-26 20:10:07 +01:00
B0pol
89dc5cec59 Translated using Weblate (Esperanto)
Currently translated at 99.8% (559 of 560 strings)
2020-03-26 20:10:06 +01:00
C. Rüdinger
1994dad972 Translated using Weblate (German)
Currently translated at 99.8% (559 of 560 strings)
2020-03-26 20:10:05 +01:00
nautilusx
8168445b4a Translated using Weblate (German)
Currently translated at 99.8% (559 of 560 strings)
2020-03-26 20:10:04 +01:00
anonymous
838f8cb2e2 Translated using Weblate (Portuguese (Brazil))
Currently translated at 95.5% (535 of 560 strings)
2020-03-26 20:10:03 +01:00
Emin Tufan Çetin
2e3f240ac6 Translated using Weblate (Turkish)
Currently translated at 100.0% (560 of 560 strings)
2020-03-26 20:10:03 +01:00
Daniele Lira Mereb
c6de6e53b5 Translated using Weblate (Portuguese (Brazil))
Currently translated at 95.5% (535 of 560 strings)
2020-03-26 20:09:58 +01:00
TobiGr
55c577e76e Seek duration should not be rounded up when opening the settings, even if inexact seek is disabled 2020-03-25 22:34:02 +01:00
TobiGr
93b75b6013 Update extractor version 2020-03-25 22:31:21 +01:00
Tobias Groza
452f258b17 Merge pull request #3273 from kapodamy/int-overflow-fix
fix #2790
2020-03-25 21:12:36 +01:00
kapodamy
5f940c40ed fix integer overflow 2020-03-25 16:13:36 -03:00
TobiGr
a19be79891 Remove unused "clear_finished_download" string 2020-03-25 12:45:37 +01:00
TobiGr
60252bbda8 Remove unused "playback_default" string 2020-03-25 12:44:04 +01:00
TobiGr
6ac52f241d Do not show nothing for some quantities for Chinese 2020-03-25 12:40:55 +01:00
TobiGr
6eeb22926a Fix what Weblate screwed up again 2020-03-25 12:36:43 +01:00
TobiGr
329047836b Merge remote-tracking branch 'Weblate/dev' into dev 2020-03-25 12:26:54 +01:00
TobiGr
4524a69f99 Update extractor version 2020-03-25 12:04:16 +01:00
Tobias Groza
5a8b565199 Merge pull request #3252 from B0pol/mute_button
Change mute button color for more visibility
2020-03-23 23:10:48 +01:00
Hosted Weblate
da5369e902 Merge branch 'origin/dev' into Weblate. 2020-03-23 04:49:07 +01:00
Jeff Huang
a433e5b65f Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (560 of 560 strings)
2020-03-23 04:47:37 +01:00
B0pol
ebb1389133 Translated using Weblate (French)
Currently translated at 100.0% (560 of 560 strings)
2020-03-23 04:47:32 +01:00
JoC
b31fbc380f Translated using Weblate (Spanish)
Currently translated at 99.8% (559 of 560 strings)
2020-03-23 04:47:29 +01:00
Hemanta Sharma
a86912c8e7 Translated using Weblate (Nepali)
Currently translated at 95.3% (534 of 560 strings)
2020-03-23 04:47:27 +01:00
nautilusx
3e348f8c71 Translated using Weblate (German)
Currently translated at 98.0% (549 of 560 strings)
2020-03-23 04:47:25 +01:00
bopol
bb91b16863 use 8F instead of 6f for white hexadecimal, on @wb9688 advise 2020-03-21 22:07:39 +01:00
bopol
8d068b339a remove unused imports 2020-03-21 21:54:40 +01:00
bopol
c54ac32732 mute button color for queue 2020-03-21 21:51:11 +01:00
bopol
47c5008871 Change mute button color for more visibility 2020-03-21 16:58:53 +01:00
jonas-skywalker
0a412e2abb Remove search icon in search mode. Issue: #3183 (see PR #3193) 2020-03-20 11:59:34 +01:00
Tobias Groza
27156d74da Merge pull request #3220 from kapodamy/webm-seek-fix
fix for #3204
2020-03-20 11:49:39 +01:00
TobiGr
50fd10ecd6 Remove titles from issue templates and fix typo 2020-03-19 22:50:48 +01:00
Tobias Groza
cab104a60a Merge pull request #3132 from Poolitzer/templates
Updating issue and PR templates
2020-03-19 22:11:55 +01:00
Hosted Weblate
37f4469503 Merge branch 'origin/dev' into Weblate. 2020-03-19 21:42:11 +01:00
Allan Nordhøy
60bcd70718 Translated using Weblate (Norwegian Bokmål)
Currently translated at 88.7% (497 of 560 strings)
2020-03-19 21:42:08 +01:00
Marian Hanzel
ac9057bd23 Translated using Weblate (Slovak)
Currently translated at 91.9% (515 of 560 strings)
2020-03-19 21:42:07 +01:00
zmni
565a5abb55 Translated using Weblate (Indonesian)
Currently translated at 99.2% (556 of 560 strings)
2020-03-19 21:42:05 +01:00
Yaron Shahrabani
8b45256725 Translated using Weblate (Hebrew)
Currently translated at 99.1% (555 of 560 strings)
2020-03-19 21:42:03 +01:00
nautilusx
b4a5f29cd1 Translated using Weblate (German)
Currently translated at 97.1% (544 of 560 strings)
2020-03-19 21:42:02 +01:00
TobiGr
4d4fb9f435 Merge branch 'master' into dev 2020-03-19 21:13:43 +01:00
Tobias Groza
49c6aa2d74 Update .github/ISSUE_TEMPLATE/feature_request.md
Co-Authored-By: opusforlife2 <53176348+opusforlife2@users.noreply.github.com>
2020-03-19 18:03:33 +01:00
Mauricio Colli
fb3290e870 Merge pull request #3230 from B0pol/seconds
Merge duplicated duration plurals and introduce new plurals for selected count
2020-03-19 09:56:57 -03:00
Mauricio Colli
27fc0d5900 Make duration plurals naming consistent 2020-03-19 09:44:13 -03:00
bopol
85e16afaa0 use val instead of val, make sentence more natural 2020-03-19 09:44:12 -03:00
bopol
0ae4d1369d use plural string for feed_group_dialog_selection_count 2020-03-19 09:44:11 -03:00
bopol
d0f2a02277 delete «seconds» plural string in favor of «dynamic_seek_duration_description» to avoid weblate conflicts 2020-03-19 09:44:10 -03:00
Mauricio Colli
b1c72bacc4 Merge remote-tracking branch 'weblate/dev' 2020-03-19 09:00:50 -03:00
poolitzer
02ef0b0818 a document is not nice 2020-03-18 19:44:37 -07:00
Poolitzer
e83e755fe1 dropping markdown links in comments
Co-Authored-By: Tobias Groza <TobiGr@users.noreply.github.com>
2020-03-18 19:42:03 -07:00
TobiGr
c73f7dd2f8 Update extractor version
Update changelog
2020-03-18 18:00:54 +01:00
Hemanta Sharma
436b08ab05 Translated using Weblate (Nepali)
Currently translated at 100.0% (535 of 535 strings)
2020-03-17 08:32:09 +01:00
Tobias Groza
ce15697ceb Merge pull request #3234 from mauriciocolli/revert-manifest-removal
Revert manifest removal from debug build variant
2020-03-16 17:59:26 +01:00
TobiGr
95883b1e3c Release version 0.187 2020-03-16 17:34:11 +01:00
Hemanta Sharma
0f96f3bd43 Translated using Weblate (Nepali)
Currently translated at 100.0% (535 of 535 strings)
2020-03-16 13:36:24 +01:00
Mauricio Colli
df2a3837a9 Revert manifest removal from build variant
The file was responsible for making the app use the Debug application
class, which various debug tools depended on.
2020-03-15 17:37:40 -03:00
wb9688
be5654dbd7 Merge pull request #3233 from TeamNewPipe/delete-subscription-header
Delete subscription_header.xml
2020-03-15 18:06:47 +01:00
Stypox
0ab4b6d63d Delete subscription_header.xml
Unused file
2020-03-15 17:47:48 +01:00
Tobias Groza
c4a601b6f6 Merge pull request #3090 from B0pol/mediaccc
Links support for mediaccc and shortened invidious
2020-03-15 17:24:32 +01:00
bopol
eacd21b230 update extractor version 2020-03-15 17:17:18 +01:00
Hemanta Sharma
373ec96051 Translated using Weblate (Nepali)
Currently translated at 100.0% (535 of 535 strings)
2020-03-15 00:37:27 +01:00
Software In Interlingua
0876cdd697 Translated using Weblate (Interlingua)
Currently translated at 36.4% (195 of 535 strings)
2020-03-15 00:37:05 +01:00
anonymous
fcc806615e Translated using Weblate (Polish)
Currently translated at 100.0% (535 of 535 strings)
2020-03-15 00:37:01 +01:00
Darko Ristovski
0486ccb0d4 Translated using Weblate (Macedonian)
Currently translated at 73.4% (393 of 535 strings)
2020-03-15 00:37:00 +01:00
B0pol
dc1312d58a Translated using Weblate (Esperanto)
Currently translated at 100.0% (535 of 535 strings)
2020-03-15 00:36:56 +01:00
nautilusx
878a5dba60 Translated using Weblate (German)
Currently translated at 100.0% (535 of 535 strings)
2020-03-15 00:36:54 +01:00
Tobias Groza
f8cc3180e8 Merge pull request #2309 from mauriciocolli/feed
Feed order and subscriptions groups
2020-03-14 18:15:57 +01:00
Mauricio Colli
97f5490c13 Add help dialog to feed screen
Help to a possible confusion or simply awareness that NewPipe has both
ways to load the feed.
2020-03-14 13:24:25 -03:00
Tobias Groza
a4babc10c0 Merge pull request #3225 from mauriciocolli/improve-build-branch
Change share title to differentiate multiple builds
2020-03-14 10:18:36 +01:00
Mauricio Colli
6a9a0f1e73 Add tests for migrations in the Room database
Doing this increase the level of reliability of migrations, as we can be
pretty much more confident of avoiding problems with them.
2020-03-14 00:12:54 -03:00
Mauricio Colli
ac44ed0862 Localize duration strings used in feed settings using plurals 2020-03-14 00:12:53 -03:00
Mauricio Colli
b62142db82 Detect if the subscription list should be shown as a grid
Also used proper string keys for the preferences, left a TODO to fix it
in other places later.
2020-03-14 00:12:52 -03:00
Mauricio Colli
f01e40e671 Simplify screen handling in feed group dialog 2020-03-14 00:12:51 -03:00
Mauricio Colli
d8b9d353aa Add a confirmation dialog when deleting a feed group 2020-03-14 00:12:50 -03:00
Mauricio Colli
98c65d8ddb Don't expose MutableLiveData in view models 2020-03-14 00:12:48 -03:00
Mauricio Colli
597859eb23 Disable buttons when processing actions in the feed dialogs 2020-03-14 00:12:47 -03:00
Mauricio Colli
34082c40d3 Fix behavior of the feed group dialog under some screen sizes/scales 2020-03-14 00:12:46 -03:00
Mauricio Colli
d1d5f6821f Implement feed groups manual sorting
Now, the user can sort its groups to his liking even after he created
them.

Also updated the database diagram to reflect the table's new column.
2020-03-14 00:12:45 -03:00
Mauricio Colli
50714c3006 Add ability to cancel a feed update through a notification action
- Change prefetch value default so each parallel rail buffers less
items.
2020-03-14 00:12:44 -03:00
Mauricio Colli
18a40168d9 Add Groupie library to the credit list in the about page 2020-03-14 00:12:43 -03:00
Mauricio Colli
2c783ff911 Stick info header when selecting subscriptions in the feed group dialog
- Avoid creating plural translation by using a different wording
2020-03-14 00:12:42 -03:00
Mauricio Colli
3f32573638 Replace hardcoded value that represents the group "All" with a constant 2020-03-14 00:12:41 -03:00
Mauricio Colli
5ea323ce02 New option to use dedicated feed sources for services that support it
YouTube, for example, has a dedicated feed which was built to be used
like this. It comes with some caveats though, like lacking enough
information about the items and returning a limited amount of them.

Nonetheless, a nice option for users that like speedy updates but don't
mind this issue.
2020-03-14 00:12:39 -03:00
Mauricio Colli
b2f317ab7c Load only the selected group and customizable updated status timeout
Now only the subscriptions from the selected group by the user will be
loaded.

Also add an option to decide how much time have to pass since the last
refresh before the subscription is deemed as not up to date. This helps
when a subscription appear in multiple groups, since updating in one
will not require to be fetched again in the others.
2020-03-14 00:12:38 -03:00
Mauricio Colli
2948e4190b Change feed groups header title and icon from feed representing "All" 2020-03-14 00:12:37 -03:00
Mauricio Colli
f05b8c9542 Expand import/export options by default when subscriptions list is empty 2020-03-14 00:12:36 -03:00
Mauricio Colli
8b87893248 Update Groupie list library to v2.7.0 2020-03-14 00:12:35 -03:00
Mauricio Colli
a93e2cdc30 Quick fix for NPE when exiting the feed fragment 2020-03-14 00:12:34 -03:00
Mauricio Colli
f69b6c85f8 Fix alignment issues in group creator dialog 2020-03-14 00:12:33 -03:00
Mauricio Colli
20a4bb0936 Implement new feed and subscriptions groups
- Introduce Groupie for easier lists implementations
- Use some of the new components of the Android Architecture libraries
- Add a bunch of icons for groups, using vectors, which still is
compatible with older APIs through the compatibility layer
2020-03-14 00:12:31 -03:00
Mauricio Colli
e8ab5aacc7 Setup initial database for feed implementation
- Update the database diagram
- Add new migration for the new tables and fields
- Enable schema exports
2020-03-14 00:12:30 -03:00
Mauricio Colli
0e2f062148 Disable database destructive migration fallback
This really shouldn't be enabled, as this database is not just a temp
one. Making the mistake of shipping the app without a proper migration
would cause a big problem.

Really hard to happen but an error is far better than data loss.
2020-03-14 00:12:29 -03:00
Mauricio Colli
d247d32221 Change share title as well to differentiate multiple builds 2020-03-13 20:11:24 -03:00
Mauricio Colli
89e3292ced Move code with lower priority to the bottom of the file 2020-03-13 20:11:22 -03:00
Tobias Groza
c2535d7764 Merge pull request #3195 from B0pol/second
Fix seek duration not showing
2020-03-13 23:27:37 +01:00
bopol
200121477c Fix seek duration not showing 2020-03-13 23:12:10 +01:00
Tobias Groza
d23b63ca83 Merge pull request #3177 from wb9688/yt-music
Accept music.youtube.com in manifest
2020-03-13 23:02:48 +01:00
TobiGr
9f91043131 Merge remote-tracking branch 'Weblate/dev' into dev 2020-03-13 22:50:15 +01:00
Tobias Groza
c668620c97 Merge pull request #3196 from mauriciocolli/fix-app-glitch
Fix visual glitch when exiting the app
2020-03-13 22:39:52 +01:00
Tobias Groza
0ee78769a1 Merge pull request #3224 from B0pol/buttons_player
Fix captions overtaking mute button
2020-03-13 22:16:30 +01:00
bopol
95f0e60343 fix captions overtaking mute button 2020-03-13 19:50:11 +01:00
Hosted Weblate
c35b13b3e2 Merge branch 'origin/dev' into Weblate. 2020-03-12 10:50:06 +01:00
Igor Nedoboy
1f42491284 Translated using Weblate (Russian)
Currently translated at 100.0% (536 of 536 strings)
2020-03-12 10:50:04 +01:00
kapodamy
ca8f8e0ee9 misc changes
* read "SeekPreRoll" from the source track (if available)
* use the longest track duration as segment duration, instead of the video track duration
* do not hardcode the "Cue" reserved space behavior
* do not hardcode the "EBML Void" element, unreported issue. The size was not properly calculated
* rewrite the key-frame picking
* remove writeInt(), writeFloat() and writeShort() methods, use inline code
* set "SeekPreRoll" and "CodecDelays" values on output tracks (if available)
* rewrite the "Cluster" maker
* rewrite the code of how "Cluster" sizes are written

Fix encode() method (the reason of this commit/pull-request):
* Use the unsigned shift operator instead of dividing the value, due precession lost
2020-03-12 00:50:14 -03:00
Tobias Groza
f7822a448e Merge pull request #3133 from Stypox/gradle-app-id-suffix
Change app id based on current git branch
2020-03-11 22:41:52 +01:00
Hosted Weblate
29edb8c8a1 Merge branch 'origin/dev' into Weblate. 2020-03-11 22:16:47 +01:00
Xiang Xu
d2403d1b34 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (536 of 536 strings)
2020-03-11 22:16:47 +01:00
Jeff Huang
c296634168 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (536 of 536 strings)
2020-03-11 22:16:46 +01:00
anonymous
ead22fa325 Translated using Weblate (French)
Currently translated at 100.0% (536 of 536 strings)
2020-03-11 22:16:46 +01:00
JoC
3265cdc3e5 Translated using Weblate (Spanish)
Currently translated at 100.0% (536 of 536 strings)
2020-03-11 22:16:46 +01:00
Software In Interlingua
8806981e64 Translated using Weblate (Interlingua)
Currently translated at 26.6% (143 of 536 strings)
2020-03-11 22:16:45 +01:00
random r
04c7a66eb4 Translated using Weblate (Italian)
Currently translated at 100.0% (536 of 536 strings)
2020-03-11 22:16:38 +01:00
WaldiS
0a32314156 Translated using Weblate (Polish)
Currently translated at 100.0% (536 of 536 strings)
2020-03-11 22:16:37 +01:00
Yaron Shahrabani
6cdf97dfed Translated using Weblate (Hebrew)
Currently translated at 100.0% (536 of 536 strings)
2020-03-11 22:16:37 +01:00
zeritti
17c140c03d Translated using Weblate (Czech)
Currently translated at 100.0% (536 of 536 strings)
2020-03-11 22:16:36 +01:00
AioiLight
dcdabe4551 Translated using Weblate (Japanese)
Currently translated at 100.0% (536 of 536 strings)
2020-03-11 22:16:36 +01:00
Enol P
a0823b2fda Translated using Weblate (Asturian)
Currently translated at 51.1% (274 of 536 strings)
2020-03-11 22:16:35 +01:00
Olexandr Nesterenko
afcda3774c Translated using Weblate (Ukrainian)
Currently translated at 93.2% (500 of 536 strings)
2020-03-11 22:16:34 +01:00
nautilusx
f895e225d4 Translated using Weblate (German)
Currently translated at 99.8% (535 of 536 strings)
2020-03-11 22:16:33 +01:00
anonymous
d0a5f757ad Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (536 of 536 strings)
2020-03-11 22:16:33 +01:00
Eduardo Caron
b43bc7f8e3 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (536 of 536 strings)
2020-03-11 22:16:32 +01:00
Florian
c09e833627 Translated using Weblate (French)
Currently translated at 99.8% (535 of 536 strings)
2020-03-11 22:16:29 +01:00
Tobias Groza
33475ef403 Merge pull request #3197 from mauriciocolli/fix-main-tabs
Fix bug in main screen tabs state management
2020-03-11 22:03:16 +01:00
undeadfox
73e14af1e3 Translated using Weblate (Russian)
Currently translated at 99.8% (535 of 536 strings)
2020-03-11 21:57:38 +01:00
undeadfox
158cd83d17 Translated using Weblate (Russian)
Currently translated at 99.6% (534 of 536 strings)
2020-03-11 21:56:58 +01:00
Igor Nedoboy
d1b1b77a4c Translated using Weblate (Russian)
Currently translated at 99.6% (534 of 536 strings)
2020-03-11 21:56:58 +01:00
Hosted Weblate
bc6ecd4101 Merge branch 'origin/dev' into Weblate. 2020-03-08 17:33:06 +01:00
Xiang Xu
9c0d44ed9c Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (534 of 534 strings)
2020-03-08 17:33:02 +01:00
Jeff Huang
ed5e99cfee Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (534 of 534 strings)
2020-03-08 17:33:02 +01:00
Éfrit
6ef75b3645 Translated using Weblate (French)
Currently translated at 100.0% (534 of 534 strings)
2020-03-08 17:33:02 +01:00
IQBAL AL FATAH
8143783cc5 Translated using Weblate (Indonesian)
Currently translated at 100.0% (534 of 534 strings)
2020-03-08 17:32:57 +01:00
Sylke Vicious
454efa5426 Translated using Weblate (Italian)
Currently translated at 100.0% (534 of 534 strings)
2020-03-08 17:32:55 +01:00
WaldiS
51e3905cd4 Translated using Weblate (Polish)
Currently translated at 99.6% (532 of 534 strings)
2020-03-08 17:32:55 +01:00
Yaron Shahrabani
b61c8d5a9e Translated using Weblate (Hebrew)
Currently translated at 100.0% (534 of 534 strings)
2020-03-08 17:32:54 +01:00
Milo Ivir
583451ee02 Translated using Weblate (Croatian)
Currently translated at 82.0% (438 of 534 strings)
2020-03-08 17:32:53 +01:00
Krysa Czech
8e779c9ad1 Translated using Weblate (Czech)
Currently translated at 100.0% (534 of 534 strings)
2020-03-08 17:32:53 +01:00
Vojtěch Šamla
b0c631709f Translated using Weblate (Czech)
Currently translated at 100.0% (534 of 534 strings)
2020-03-08 17:32:53 +01:00
Osoitz
225d7dca7e Translated using Weblate (Basque)
Currently translated at 100.0% (534 of 534 strings)
2020-03-08 17:32:52 +01:00
nautilusx
5c5f4ad29f Translated using Weblate (German)
Currently translated at 99.8% (533 of 534 strings)
2020-03-08 17:32:52 +01:00
Emin Tufan Çetin
cb2cb2eab5 Translated using Weblate (Turkish)
Currently translated at 100.0% (534 of 534 strings)
2020-03-08 17:32:51 +01:00
Stypox
64c289c014 Merge pull request #3184 from opusforlife2/relocate_settings
Relocate two settings from Appearance to Content
2020-03-08 17:12:38 +01:00
Mauricio Colli
f2526ed5a8 Fix bug in main screen tabs state management
Tabs were not being destroyed/restored correctly due to a call to a
method that populated the view pager before it even had a chance of
restoring itself.

The solution was to null out the adapter before calling that method so
the view pager will postpone the populating process.
2020-03-08 09:09:04 -03:00
Stypox
8fa29ffc19 Merge pull request #3165 from karkaminski/mute_button
Mute button
2020-03-08 10:29:25 +01:00
Stypox
029758fdff Merge pull request #3046 from XiangRongLin/shareDownload
Fix bug causing crashes when sharing a downloaded file.
2020-03-08 09:44:04 +01:00
Tobias Groza
9db2197be1 Improve code style
Co-Authored-By: B0pol <bopol@e.email>
2020-03-07 20:09:05 +01:00
yausername
3e1e07e468 refactor checkpointing 2020-03-07 20:09:05 +01:00
yausername
c6b062a698 checkpoint db before export 2020-03-07 20:09:05 +01:00
Mauricio Colli
ecb1b45280 Fix visual glitch when exiting the app 2020-03-07 15:55:55 -03:00
karol
55d7be0b2f null risk issue 2020-03-05 19:07:46 +01:00
poolitzer
4e37a762d2 Further minor improvements 2020-03-04 20:31:36 -08:00
Poolitzer
2ca580dc16 minor improvements of sentences
Co-Authored-By: Stypox <stypox@pm.me>
2020-03-04 20:21:44 -08:00
karol
83c7c4a68e mute/unmute text change in action bar 2020-03-04 18:53:17 +01:00
karol
1ae8a72ba6 mute icon change in action bar 2020-03-04 18:37:04 +01:00
opusforlife2
7da11206da Relocate two settings from Appearance to Content 2020-03-04 18:41:41 +05:30
Hosted Weblate
4cd9e0f97e Merge branch 'origin/dev' into Weblate. 2020-03-04 10:09:59 +01:00
Isak Holmström
5c559e4cc6 Translated using Weblate (Swedish)
Currently translated at 86.8% (463 of 533 strings)
2020-03-04 10:09:59 +01:00
IQBAL AL FATAH
371280ff76 Translated using Weblate (Indonesian)
Currently translated at 100.0% (533 of 533 strings)
2020-03-04 10:09:58 +01:00
Mohd. A
ebdf48899f Translated using Weblate (Arabic)
Currently translated at 98.3% (524 of 533 strings)
2020-03-04 10:09:58 +01:00
Sylke Vicious
6962882e75 Translated using Weblate (Italian)
Currently translated at 100.0% (533 of 533 strings)
2020-03-04 10:09:57 +01:00
AioiLight
e1fb8831de Translated using Weblate (Japanese)
Currently translated at 100.0% (533 of 533 strings)
2020-03-04 10:09:57 +01:00
IQBAL AL FATAH
e421d47b23 Translated using Weblate (Indonesian)
Currently translated at 100.0% (533 of 533 strings)
2020-03-04 10:09:51 +01:00
Dani Pragustia
9b65b000db Translated using Weblate (Indonesian)
Currently translated at 100.0% (533 of 533 strings)
2020-03-04 10:09:50 +01:00
Stypox
d5c29bf1b5 Merge pull request #3160 from XiangRongLin/b3127
Hide 5, 15, 25 second seek options if inexact seek is enabled
2020-03-03 21:58:18 +01:00
Stypox
4bb6a146e8 Update app/src/main/res/values/strings.xml 2020-03-03 21:51:46 +01:00
XiangRongLin
f7ef7a18ac Update app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java
Co-Authored-By: Stypox <stypox@pm.me>
2020-03-03 21:41:15 +01:00
Stypox
0a87f13ceb Merge pull request #3107 from comradekingu/patch-11
Spelling: Some devices are incompatible
2020-03-03 21:08:30 +01:00
Xiang Rong Lin
efb67b0fd4 Change toast string resource to be useable with different languages 2020-03-03 19:50:50 +01:00
Xiang Rong Lin
e3fff4356a Show a toast when seek duration was rounded up 2020-03-03 19:40:10 +01:00
Xiang Rong Lin
7d3b21582c Use DateUtils constant for 1000 2020-03-03 19:40:10 +01:00
Xiang Rong Lin
6a42714326 Round seek duration up instead of setting it to 10 seconds 2020-03-03 19:40:10 +01:00
Xiang Rong Lin
288a61895c Update inexact seek summary 2020-03-03 19:40:10 +01:00
Xiang Rong Lin
4463804338 Update seek options on inexact seek option change.
Reset to 10 seconds when previous value is not valid anymore
2020-03-03 19:40:10 +01:00
Xiang Rong Lin
57504acd00 If inexact seekt is used, hide 5,15,25 seconds seek duration options when opening settings 2020-03-03 19:40:10 +01:00
Poolitzer
3f118a7239 appending dots
Co-Authored-By: opusforlife2 <53176348+opusforlife2@users.noreply.github.com>
2020-03-02 21:08:34 -08:00
Poolitzer
d265382ddf missed this
because GitHub thought its funny to hide it for a reason.

Co-Authored-By: opusforlife2 <53176348+opusforlife2@users.noreply.github.com>
2020-03-02 20:56:03 -08:00
poolitzer
08dffad160 opus4improvements 2020-03-02 20:52:50 -08:00
poolitzer
afebd9b724 improvements 2020-03-02 16:38:23 -08:00
karol
840bb29c54 icon color change in action bar 2020-03-03 00:01:19 +01:00
karol
c79f09c119 mute button in actionbar, no color change 2020-03-02 22:52:58 +01:00
bopol
124340175a remove redundant code 2020-03-02 22:50:52 +01:00
bopol
07d1faf544 Links support for mediaccc and shortened invidious 2020-03-02 22:50:33 +01:00
karol
92ee51b8db resolved issues 2020-03-02 21:12:02 +01:00
Stypox
92f4010e8e Add more checks to prevent build failures in gradle branch suffix
- Add function `getGitWorkingBranch` that returns the current working branch, and "" if it could not be determined (either because git is not installed or because the directory is not a git repo).
- Make sure normalizedWorkingBranch is not empty (leading to an invalid app id terminating with `.`)
- Make normalizedWorkingBranch lowercase
- Add comments
2020-03-02 20:50:35 +01:00
Dani Pragustia
667a52427e Translated using Weblate (Indonesian)
Currently translated at 100.0% (533 of 533 strings)
2020-03-02 18:59:04 +01:00
KOK ASiiK
e7063b2c69 Translated using Weblate (Indonesian)
Currently translated at 100.0% (533 of 533 strings)
2020-03-02 18:59:04 +01:00
wb9688
add08ead14 Accept music.youtube.com in manifest 2020-03-02 17:58:48 +01:00
poolitzer
5d7eba30a6 Merge remote-tracking branch 'upstream/dev' into templates 2020-03-01 12:36:32 -08:00
Hosted Weblate
7e2bec85ee Merge branch 'origin/dev' into Weblate. 2020-03-01 20:58:25 +01:00
B0pol
ca2e9d4afa Translated using Weblate (French)
Currently translated at 100.0% (533 of 533 strings)
2020-03-01 20:58:21 +01:00
Igor Nedoboy
deafe93e6c Translated using Weblate (Russian)
Currently translated at 100.0% (533 of 533 strings)
2020-03-01 20:58:20 +01:00
B0pol
5257c5a0a8 Translated using Weblate (Esperanto)
Currently translated at 100.0% (533 of 533 strings)
2020-03-01 20:58:19 +01:00
karol
a6fcb70d12 fix typo 2020-03-01 16:42:46 +01:00
TobiGr
4674431829 Release 0.18.6 (860) 2020-03-01 15:43:12 +01:00
TobiGr
2b9c7fee20 Update extractor version 2020-03-01 15:37:47 +01:00
karol
ee75909c80 set mute button in main player from other player 2020-03-01 13:02:20 +01:00
TobiGr
fbab80145e Merge remote-tracking branch 'Weblate/dev' into dev 2020-02-29 21:50:45 +01:00
Éfrit
95d8b12065 Translated using Weblate (French)
Currently translated at 100.0% (533 of 533 strings)
2020-02-29 18:51:26 +01:00
Hosted Weblate
9f8b7a180f Merge branch 'origin/dev' into Weblate. 2020-02-29 17:04:56 +01:00
Allan Nordhøy
7f62f56661 Translated using Weblate (Norwegian Bokmål)
Currently translated at 91.9% (490 of 533 strings)
2020-02-29 17:04:56 +01:00
Xiang Xu
28ecf98fa6 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (533 of 533 strings)
2020-02-29 17:04:55 +01:00
Jeff Huang
68f55e6639 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (533 of 533 strings)
2020-02-29 17:04:55 +01:00
Isak Holmström
83e7af4503 Translated using Weblate (Swedish)
Currently translated at 81.4% (434 of 533 strings)
2020-02-29 17:04:55 +01:00
Éfrit
fbfaa8d25f Translated using Weblate (French)
Currently translated at 100.0% (533 of 533 strings)
2020-02-29 17:04:54 +01:00
Erik Peeremand
b46d199086 Translated using Weblate (Dutch)
Currently translated at 82.1% (438 of 533 strings)
2020-02-29 17:04:54 +01:00
pjammo
64c6aac0cf Translated using Weblate (Italian)
Currently translated at 100.0% (533 of 533 strings)
2020-02-29 17:04:54 +01:00
WaldiS
f3c64edf6e Translated using Weblate (Polish)
Currently translated at 99.8% (532 of 533 strings)
2020-02-29 17:04:52 +01:00
Vojtěch Šamla
61673cda70 Translated using Weblate (Czech)
Currently translated at 100.0% (533 of 533 strings)
2020-02-29 17:04:52 +01:00
Enol P
d71e6b18c0 Translated using Weblate (Asturian)
Currently translated at 50.8% (271 of 533 strings)
2020-02-29 17:04:52 +01:00
Nicu Borta
19fe47f71e Translated using Weblate (Romanian)
Currently translated at 74.1% (395 of 533 strings)
2020-02-29 17:04:50 +01:00
Gontzal Manuel Pujana Onaindia
720bcbf8ac Translated using Weblate (Basque)
Currently translated at 100.0% (533 of 533 strings)
2020-02-29 17:04:49 +01:00
nautilusx
bb3b7d68c1 Translated using Weblate (German)
Currently translated at 100.0% (533 of 533 strings)
2020-02-29 17:04:47 +01:00
Eduardo Caron
eb4b6d2a7f Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (533 of 533 strings)
2020-02-29 17:04:46 +01:00
Daniele Lira Mereb
abc3e8d59c Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (533 of 533 strings)
2020-02-29 17:04:45 +01:00
Oğuz Ersen
9f05f360f9 Translated using Weblate (Turkish)
Currently translated at 100.0% (533 of 533 strings)
2020-02-29 17:04:44 +01:00
Lucas Thuries
9b2dc1b263 Translated using Weblate (French)
Currently translated at 99.8% (532 of 533 strings)
2020-02-29 17:04:41 +01:00
Alexandre Hô
50777d8d2c Translated using Weblate (French)
Currently translated at 99.8% (532 of 533 strings)
2020-02-29 17:04:41 +01:00
Florian
63e85fe4be Translated using Weblate (French)
Currently translated at 99.8% (532 of 533 strings)
2020-02-29 17:04:40 +01:00
poolitzer
e2cb927e1f Merge branch 'templates' of https://github.com/Poolitzer/NewPipe into templates 2020-02-28 15:32:20 -08:00
poolitzer
46165f4a4f adding version section to bug report 2020-02-28 15:32:14 -08:00
Tobias Groza
b1eaf5616a Merge pull request #3154 from B0pol/round
Round at one place for Localization.shortCount()
2020-02-29 00:08:20 +01:00
bopol
22aa6d16a2 public Utils.round() moved to private Localization.round() 2020-02-28 17:04:25 +01:00
bopol
dfaa5675b6 Round at one place for Localization.shortCount() 2020-02-28 17:04:25 +01:00
karol
0400fcb106 mute icon in main refactored 2020-02-27 23:30:17 +01:00
karol
40f54aea53 mute intent send between main-bckgrnd-popup players 2020-02-27 22:30:18 +01:00
Poolitzer
d9a8e4d797 NewPipe is an app though :(
And its our app!

Co-Authored-By: Tobias Groza <TobiGr@users.noreply.github.com>
2020-02-26 19:50:11 -08:00
Tobias Groza
ab4e1819c1 Merge pull request #2967 from moneytoo/cutout
Support display cutout
2020-02-26 20:05:57 +01:00
Marcel Dopita
91aa65e717 Support display cutout
Fixes #2682
2020-02-26 17:47:22 +01:00
TobiGr
ec684434dc Merge branch 'master' into dev 2020-02-26 17:46:59 +01:00
TobiGr
3b5b9d7dab Release 0.18.5 (850) and update extractor version
Update User-Agent
2020-02-25 23:38:51 +01:00
TobiGr
e7082baaff Exception is ignored in SearchFragment 2020-02-25 23:12:12 +01:00
poolitzer
1d9ffffc49 Minor improvements 2020-02-24 14:18:48 -08:00
poolitzer
01c1fa0393 B0pol suggested improvements 2020-02-23 16:16:18 -08:00
karol
c4d5886059 icon change implemented in queque 2020-02-23 23:44:16 +01:00
karol
2a63f2a3a6 mute-buton in queue layout and logic, but no icon change 2020-02-23 23:31:30 +01:00
karol
cc559dc9ce isMuted() added 2020-02-23 22:55:34 +01:00
karol
4415888324 mute-button implementation in main player 2020-02-23 22:32:23 +01:00
karol
dc6a0e3eec mute-button added to activity_main_player.xml's 2020-02-23 21:28:40 +01:00
Stypox
3434ff4d45 Merge branch 'gradle-app-id-suffix' of github.com:Stypox/NewPipe into gradle-app-id-suffix 2020-02-23 20:57:50 +01:00
Stypox
030e5ab894 Add comment to gradle 2020-02-23 20:56:56 +01:00
Hosted Weblate
1caafac89a Merge branch 'origin/dev' into Weblate. 2020-02-23 20:37:42 +01:00
chr56
26e2fc6d91 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (533 of 533 strings)
2020-02-23 20:37:39 +01:00
JoC
740fa67a4e Translated using Weblate (Spanish)
Currently translated at 100.0% (533 of 533 strings)
2020-02-23 20:37:37 +01:00
ButterflyOfFire
d468423db3 Translated using Weblate (Arabic)
Currently translated at 97.1% (518 of 533 strings)
2020-02-23 20:37:36 +01:00
Yaron Shahrabani
84664ebcdc Translated using Weblate (Hebrew)
Currently translated at 100.0% (533 of 533 strings)
2020-02-23 20:37:34 +01:00
Stypox
d46cd265f5 Merge branch 'dev' into gradle-app-id-suffix 2020-02-23 10:04:19 +01:00
Stypox
a3bce7f7ca Change app id based on current git branch
This enables to install multiple builds from different branches at once
2020-02-23 09:46:42 +01:00
Poolitzer
30f66d012e Update PULL_REQUEST_TEMPLATE.md 2020-02-22 20:16:14 -08:00
poolitzer
495b495f27 deleting old template 2020-02-22 20:03:38 -08:00
poolitzer
e8f28ebc43 Merge branch 'templates' of https://github.com/Poolitzer/NewPipe into templates 2020-02-22 20:02:11 -08:00
Poolitzer
01dcf550cf Update issue templates 2020-02-22 19:56:56 -08:00
Tobias Groza
987078fab5 Merge pull request #3043 from Stypox/unhook-save-restore
Save and restore whether pitch and tempo are unhooked or not
2020-02-23 00:36:10 +01:00
Tobias Groza
7da28f28e5 Merge branch 'dev' into unhook-save-restore 2020-02-23 00:19:44 +01:00
Hosted Weblate
3c9af84ea2 Merge branch 'origin/dev' into Weblate. 2020-02-23 00:10:49 +01:00
chr56
286fd19ba2 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (533 of 533 strings)
2020-02-23 00:10:49 +01:00
MohammedSR Vevo
39dce71c28 Translated using Weblate (Kurdish)
Currently translated at 99.8% (532 of 533 strings)
2020-02-23 00:10:49 +01:00
zmni
b3b1d6d706 Translated using Weblate (Indonesian)
Currently translated at 100.0% (533 of 533 strings)
2020-02-23 00:10:48 +01:00
Yaron Shahrabani
c04040468e Translated using Weblate (Hebrew)
Currently translated at 99.4% (530 of 533 strings)
2020-02-23 00:10:48 +01:00
Vojtěch Šamla
aee7777478 Translated using Weblate (Czech)
Currently translated at 100.0% (533 of 533 strings)
2020-02-23 00:10:48 +01:00
Igor Nedoboy
09c1e21560 Translated using Weblate (Russian)
Currently translated at 100.0% (533 of 533 strings)
2020-02-23 00:10:47 +01:00
nautilusx
60e9f56b0f Translated using Weblate (German)
Currently translated at 100.0% (533 of 533 strings)
2020-02-23 00:10:47 +01:00
Oğuz Ersen
302e4ab664 Translated using Weblate (Turkish)
Currently translated at 100.0% (533 of 533 strings)
2020-02-23 00:10:46 +01:00
chr56
484c3aa320 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (533 of 533 strings)
2020-02-23 00:10:41 +01:00
Hosted Weblate
13d2334a45 Merge branch 'origin/dev' into Weblate. 2020-02-22 12:07:27 +01:00
Jeff Huang
9864e04aae Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (532 of 532 strings)
2020-02-22 12:07:26 +01:00
B0pol
4d6bbbf004 Translated using Weblate (French)
Currently translated at 97.9% (521 of 532 strings)
2020-02-22 12:07:26 +01:00
C. Rüdinger
44305b4ccd Translated using Weblate (German)
Currently translated at 99.4% (529 of 532 strings)
2020-02-22 12:07:23 +01:00
Igor Nedoboy
7f86b13d93 Translated using Weblate (Russian)
Currently translated at 100.0% (532 of 532 strings)
2020-02-22 12:07:19 +01:00
Allan Nordhøy
91bd0be39e Spelling: Some devices are incompatible 2020-02-17 14:54:45 +01:00
Stypox
4b8474b0ac Merge branch 'dev' into unhook-save-restore 2020-02-09 13:10:35 +01:00
Xiang Rong Lin
cf377c2591 Fix bug causing crashes when sharing a downloaded file. 2020-02-03 10:43:08 +01:00
Stypox
244009a1cd Change "Unlink" to "Unhook" in unhook_checkbox string
"Unlink" is not an english word, and "Unhook" is used everywhere in the code
2020-02-02 15:54:31 +01:00
Stypox
0f22833ad5 Save and restore whether pitch and tempo are unhooked or not
Fixes #1536
2020-02-02 15:52:35 +01:00
289 changed files with 11119 additions and 3200 deletions

View File

@@ -1,3 +0,0 @@
- [ ] I carefully read the [contribution guidelines](https://github.com/TeamNewPipe/NewPipe/blob/HEAD/.github/CONTRIBUTING.md) and agree to them.
- [ ] I checked if the issue/feature exists in the latest version.
- [ ] I did use the [incredible bugreport to markdown converter](https://teamnewpipe.github.io/CrashReportToMarkdown/) to paste bug reports.

44
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,44 @@
---
name: Bug report
about: Create a bug report to help us improve
labels: bug
assignees: ''
---
<!--
Oh no, a bug! It happens. Thanks for reporting an issue with NewPipe.
Use this template to notify us if you found a bug.
To make it easier for us to help you please enter detailed information below.
Please note, we only support the latest version of NewPipe and the master branch. Make sure you have that version installed. If you don't, upgrade & reproduce the problem before opening the issue. The release page (https://github.com/TeamNewPipe/NewPipe/releases/latest) is the go-to place to get this version. In order to check your app version, open the left drawer and click on "About".
P.S.: Our contribution guidelines might be a nice document to read before you fill out the report :) You can find it at https://github.com/TeamNewPipe/NewPipe/blob/HEAD/.github/CONTRIBUTING.md
-->
### Version
<!-- Which version are you using? -->
-
### Steps to reproduce the bug
<!-- If you can't reproduce it, please try to give as many details as possible on how you think you got to the bug. -->
Steps to reproduce the behavior:
1. Go to '...'
2. Press on '....'
3. Swipe down to '....'
### Expected behavior
Tell us what you expected to happen.
### Actual behaviour
Tell us what happens instead.
### Screenshots/Screen records
If applicable, add screenshots or a screen recording to help explain your problem. GitHub should support uploading them directly in the issue field. If your file is too big, feel free to paste a link from an image/video hoster here instead.
### Logs
If your bug includes a crash, please head over to the [incredible bugreport to markdown converter](https://teamnewpipe.github.io/CrashReportToMarkdown/). Copy the result. Paste it here:
<!-- That's right, here! -->

View File

@@ -0,0 +1,28 @@
---
name: Feature request
about: Suggest an idea for this project
labels: enhancement
assignees: ''
---
<!-- Hey. Our contribution guidelines (https://github.com/TeamNewPipe/NewPipe/blob/HEAD/.github/CONTRIBUTING.md) might be an appropriate
document to read before you fill out the request :) -->
#### Is your feature request related to a problem? Please describe it
A clear and concise description of what the problem is.
Example: *I want to do X, but there is no way to do it.*
#### Describe the solution you'd like
A clear and concise description of what you want to happen.
Example: *I think it would be nice if you add feature Y which makes X possible.*
#### (Optional) Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
Example: *I considered Z, but that didn't turn out to be a good idea because...*
#### Additional context
Add any other context or screenshots about the feature request here.
Example: *Here's a photo of my cat!*
#### How will you/everyone benefit from this feature?
Convince us! How does it change your NewPipe experience and/or your life?
The better this paragraph is, the more likely a developer will think about working on it.

View File

@@ -1 +1,26 @@
<!-- Hey there. Thank you so much for improving NewPipe. Please take a moment to fill out the following suggestion on how to structure this PR description. Having roughly the same layout helps everyone considerably :)-->
#### What is it?
- [ ] Bug fix
- [ ] Feature
#### Long description of the changes in your PR
<!-- While bullet points are the norm in this section, feel free to write a text instead if you can't fit it in a list -->
- record videos
- create clones
- take over the world
#### Fixes the following issue(s)
<!-- Also add reddit or other links which are relevant to your change. -->
-
#### Relies on the following changes
<!-- Delete this if it doesn't apply to you. -->
-
#### Testing apk
<!-- Ensure that you have your changes on a new branch which has a meaningful name. This name will be used as a suffix for the app ID to allow installing and testing multiple versions of NewPipe. Do NOT name your branches like "patch-0" and "feature-1". For example, if your PR implements a bug fix for comments, an appropriate branch name would be "commentfix". -->
debug.zip
#### Agreement
- [ ] I carefully read the [contribution guidelines](https://github.com/TeamNewPipe/NewPipe/blob/HEAD/.github/CONTRIBUTING.md) and agree to them.

View File

@@ -9,13 +9,20 @@ android {
defaultConfig {
applicationId "org.schabi.newpipe"
resValue "string", "app_name", "NewPipe"
minSdkVersion 19
targetSdkVersion 28
versionCode 840
versionName "0.18.4"
versionCode 910
versionName "0.19.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
buildTypes {
@@ -28,7 +35,18 @@ android {
debug {
multiDexEnabled true
debuggable true
applicationIdSuffix ".debug"
// suffix the app id and the app name with git branch name
def workingBranch = getGitWorkingBranch()
def normalizedWorkingBranch = workingBranch.replaceAll("[^A-Za-z]+", "").toLowerCase()
if (normalizedWorkingBranch.isEmpty() || workingBranch == "master" || workingBranch == "dev") {
// default values when branch name could not be determined or is master or dev
applicationIdSuffix ".debug"
resValue "string", "app_name", "NewPipe Debug"
} else {
applicationIdSuffix ".debug." + normalizedWorkingBranch
resValue "string", "app_name", "NewPipe " + workingBranch
}
}
}
@@ -43,6 +61,15 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// Required and used only by groupie
androidExtensions {
experimental = true
}
sourceSets {
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
}
}
ext {
@@ -59,11 +86,13 @@ ext {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation "android.arch.persistence.room:testing:1.1.1"
androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
exclude module: 'support-annotations'
})
implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.18.4'
implementation 'com.github.TeamNewPipe:NewPipeExtractor:69e0624e3'
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.23.0'
@@ -75,6 +104,13 @@ dependencies {
implementation "androidx.cardview:cardview:${androidxLibVersion}"
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.xwray:groupie:2.7.0'
implementation 'com.xwray:groupie-kotlin-android-extensions:2.7.0'
implementation 'androidx.lifecycle:lifecycle-livedata:2.0.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
// Originally in NewPipeExtractor
implementation 'com.grack:nanojson:1.1'
implementation 'org.jsoup:jsoup:1.9.2'
@@ -113,3 +149,19 @@ dependencies {
implementation "io.noties.markwon:core:${markwonVersion}"
implementation "io.noties.markwon:linkify:${markwonVersion}"
}
static String getGitWorkingBranch() {
try {
def gitProcess = "git rev-parse --abbrev-ref HEAD".execute()
gitProcess.waitFor()
if (gitProcess.exitValue() == 0) {
return gitProcess.text.trim()
} else {
// not a git repository
return ""
}
} catch (IOException ignored) {
// git was not found
return ""
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,118 @@
package org.schabi.newpipe.database
import android.content.ContentValues
import android.database.sqlite.SQLiteDatabase
import androidx.room.Room
import androidx.room.testing.MigrationTestHelper
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.schabi.newpipe.extractor.stream.StreamType
@RunWith(AndroidJUnit4::class)
class AppDatabaseTest {
companion object {
private const val DEFAULT_SERVICE_ID = 0
private const val DEFAULT_URL = "https://www.youtube.com/watch?v=cDphUib5iG4"
private const val DEFAULT_TITLE = "Test Title"
private val DEFAULT_TYPE = StreamType.VIDEO_STREAM
private const val DEFAULT_DURATION = 480L
private const val DEFAULT_UPLOADER_NAME = "Uploader Test"
private const val DEFAULT_THUMBNAIL = "https://example.com/example.jpg"
private const val DEFAULT_SECOND_SERVICE_ID = 0
private const val DEFAULT_SECOND_URL = "https://www.youtube.com/watch?v=ncQU6iBn5Fc"
}
@get:Rule val testHelper = MigrationTestHelper(InstrumentationRegistry.getInstrumentation(),
AppDatabase::class.java.canonicalName, FrameworkSQLiteOpenHelperFactory());
@Test
fun migrateDatabaseFrom2to3() {
val databaseInV2 = testHelper.createDatabase(AppDatabase.DATABASE_NAME, Migrations.DB_VER_2)
databaseInV2.run {
insert("streams", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply {
// put("uid", null)
put("service_id", DEFAULT_SERVICE_ID)
put("url", DEFAULT_URL)
put("title", DEFAULT_TITLE)
put("stream_type", DEFAULT_TYPE.name)
put("duration", DEFAULT_DURATION)
put("uploader", DEFAULT_UPLOADER_NAME)
put("thumbnail_url", DEFAULT_THUMBNAIL)
})
insert("streams", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply {
// put("uid", null)
put("service_id", DEFAULT_SECOND_SERVICE_ID)
put("url", DEFAULT_SECOND_URL)
// put("title", null)
// put("stream_type", null)
// put("duration", null)
// put("uploader", null)
// put("thumbnail_url", null)
})
insert("streams", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply {
// put("uid", null)
put("service_id", DEFAULT_SERVICE_ID)
// put("url", null)
// put("title", null)
// put("stream_type", null)
// put("duration", null)
// put("uploader", null)
// put("thumbnail_url", null)
})
close()
}
testHelper.runMigrationsAndValidate(AppDatabase.DATABASE_NAME, Migrations.DB_VER_3,
true, Migrations.MIGRATION_2_3);
val migratedDatabaseV3 = getMigratedDatabase()
val listFromDB = migratedDatabaseV3.streamDAO().all.blockingFirst()
// Only expect 2, the one with the null url will be ignored
assertEquals(2, listFromDB.size)
val streamFromMigratedDatabase = listFromDB[0]
assertEquals(DEFAULT_SERVICE_ID, streamFromMigratedDatabase.serviceId)
assertEquals(DEFAULT_URL, streamFromMigratedDatabase.url)
assertEquals(DEFAULT_TITLE, streamFromMigratedDatabase.title)
assertEquals(DEFAULT_TYPE, streamFromMigratedDatabase.streamType)
assertEquals(DEFAULT_DURATION, streamFromMigratedDatabase.duration)
assertEquals(DEFAULT_UPLOADER_NAME, streamFromMigratedDatabase.uploader)
assertEquals(DEFAULT_THUMBNAIL, streamFromMigratedDatabase.thumbnailUrl)
assertNull(streamFromMigratedDatabase.viewCount)
assertNull(streamFromMigratedDatabase.textualUploadDate)
assertNull(streamFromMigratedDatabase.uploadDate)
assertNull(streamFromMigratedDatabase.isUploadDateApproximation)
val secondStreamFromMigratedDatabase = listFromDB[1]
assertEquals(DEFAULT_SECOND_SERVICE_ID, secondStreamFromMigratedDatabase.serviceId)
assertEquals(DEFAULT_SECOND_URL, secondStreamFromMigratedDatabase.url)
assertEquals("", secondStreamFromMigratedDatabase.title)
// Should fallback to VIDEO_STREAM
assertEquals(StreamType.VIDEO_STREAM, secondStreamFromMigratedDatabase.streamType)
assertEquals(0, secondStreamFromMigratedDatabase.duration)
assertEquals("", secondStreamFromMigratedDatabase.uploader)
assertEquals("", secondStreamFromMigratedDatabase.thumbnailUrl)
assertNull(secondStreamFromMigratedDatabase.viewCount)
assertNull(secondStreamFromMigratedDatabase.textualUploadDate)
assertNull(secondStreamFromMigratedDatabase.uploadDate)
assertNull(secondStreamFromMigratedDatabase.isUploadDateApproximation)
}
private fun getMigratedDatabase(): AppDatabase {
val database: AppDatabase = Room.databaseBuilder(ApplicationProvider.getApplicationContext(),
AppDatabase::class.java, AppDatabase.DATABASE_NAME)
.build()
testHelper.closeWhenFinished(database)
return database
}
}

View File

@@ -6,12 +6,5 @@
<application
android:name=".DebugApp"
android:label="NewPipe Debug"
tools:replace="android:name, android:label">
<activity
android:name=".MainActivity"
android:label="NewPipe Debug"
tools:replace="android:label"/>
</application>
tools:replace="android:name" />
</manifest>

View File

@@ -61,7 +61,8 @@
android:name=".player.MainVideoPlayer"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleTask"/>
android:launchMode="singleTask"
android:theme="@style/VideoPlayerTheme"/>
<activity
android:name=".settings.SettingsActivity"
@@ -73,6 +74,7 @@
<service android:name=".local.subscription.services.SubscriptionsImportService"/>
<service android:name=".local.subscription.services.SubscriptionsExportService"/>
<service android:name=".local.feed.service.FeedLoadService"/>
<activity
android:name=".PanicResponderActivity"
@@ -145,6 +147,7 @@
<data android:host="youtube.com"/>
<data android:host="m.youtube.com"/>
<data android:host="www.youtube.com"/>
<data android:host="music.youtube.com"/>
<!-- video prefix -->
<data android:pathPrefix="/v/"/>
<data android:pathPrefix="/embed/"/>
@@ -243,14 +246,7 @@
<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"/>
<!-- channel prefix -->
<data android:pathPrefix="/channel/"/>
<data android:pathPrefix="/user/"/>
<!-- playlist prefix -->
<data android:pathPrefix="/playlist"/>
<data android:pathPrefix="/"/>
</intent-filter>
<!-- Soundcloud filter -->
@@ -276,8 +272,26 @@
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>
<!-- MediaCCC filter -->
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http"/>
<data android:scheme="https"/>
<data android:host="media.ccc.de"/>
<!-- video prefix -->
<data android:pathPrefix="/v/"/>
<!-- channel prefix-->
<data android:pathPrefix="/c/"/>
<data android:pathPrefix="/b/"/>
</intent-filter>
</activity>
<service
android:name=".RouterActivity$FetcherService"
android:exported="false"/>

View File

@@ -38,7 +38,7 @@ import okhttp3.ResponseBody;
import static org.schabi.newpipe.MainActivity.DEBUG;
public class DownloaderImpl extends Downloader {
public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0";
public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Firefox/68.0";
private static DownloaderImpl instance;
private String mCookies;
@@ -171,7 +171,8 @@ public class DownloaderImpl extends Downloader {
responseBodyToReturn = body.string();
}
return new Response(response.code(), response.message(), response.headers().toMultimap(), responseBodyToReturn);
final String latestUrl = response.request().url().toString();
return new Response(response.code(), response.message(), response.headers().toMultimap(), responseBodyToReturn, latestUrl);
}
/**

View File

@@ -159,7 +159,7 @@ public class MainActivity extends AppCompatActivity {
.add(R.id.menu_tabs_group, ITEM_ID_SUBSCRIPTIONS, ORDER, R.string.tab_subscriptions)
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_channel));
drawerItems.getMenu()
.add(R.id.menu_tabs_group, ITEM_ID_FEED, ORDER, R.string.fragment_whats_new)
.add(R.id.menu_tabs_group, ITEM_ID_FEED, ORDER, R.string.fragment_feed_title)
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.rss));
drawerItems.getMenu()
.add(R.id.menu_tabs_group, ITEM_ID_BOOKMARKS, ORDER, R.string.tab_bookmarks)
@@ -240,7 +240,7 @@ public class MainActivity extends AppCompatActivity {
NavigationHelper.openSubscriptionFragment(getSupportFragmentManager());
break;
case ITEM_ID_FEED:
NavigationHelper.openWhatsNewFragment(getSupportFragmentManager());
NavigationHelper.openFeedFragment(getSupportFragmentManager());
break;
case ITEM_ID_BOOKMARKS:
NavigationHelper.openBookmarksFragment(getSupportFragmentManager());
@@ -389,7 +389,7 @@ public class MainActivity extends AppCompatActivity {
.add(R.id.menu_tabs_group, ITEM_ID_SUBSCRIPTIONS, ORDER, R.string.tab_subscriptions)
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_channel));
drawerItems.getMenu()
.add(R.id.menu_tabs_group, ITEM_ID_FEED, ORDER, R.string.fragment_whats_new)
.add(R.id.menu_tabs_group, ITEM_ID_FEED, ORDER, R.string.fragment_feed_title)
.setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.rss));
drawerItems.getMenu()
.add(R.id.menu_tabs_group, ITEM_ID_BOOKMARKS, ORDER, R.string.tab_bookmarks)

View File

@@ -1,13 +1,16 @@
package org.schabi.newpipe;
import androidx.room.Room;
import android.content.Context;
import android.database.Cursor;
import androidx.annotation.NonNull;
import androidx.room.Room;
import org.schabi.newpipe.database.AppDatabase;
import static org.schabi.newpipe.database.AppDatabase.DATABASE_NAME;
import static org.schabi.newpipe.database.Migrations.MIGRATION_11_12;
import static org.schabi.newpipe.database.Migrations.MIGRATION_1_2;
import static org.schabi.newpipe.database.Migrations.MIGRATION_2_3;
public final class NewPipeDatabase {
@@ -20,8 +23,7 @@ public final class NewPipeDatabase {
private static AppDatabase getDatabase(Context context) {
return Room
.databaseBuilder(context.getApplicationContext(), AppDatabase.class, DATABASE_NAME)
.addMigrations(MIGRATION_11_12)
.fallbackToDestructiveMigration()
.addMigrations(MIGRATION_1_2, MIGRATION_2_3)
.build();
}
@@ -39,4 +41,14 @@ public final class NewPipeDatabase {
return result;
}
public static void checkpoint() {
if (databaseInstance == null) {
throw new IllegalStateException("database is not initialized");
}
Cursor c = databaseInstance.query("pragma wal_checkpoint(full)", null);
if (c.moveToFirst() && c.getInt(0) == 1) {
throw new RuntimeException("Checkpoint was blocked from completing");
}
}
}

View File

@@ -9,12 +9,6 @@ import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
@@ -26,6 +20,12 @@ import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import androidx.fragment.app.FragmentManager;
import org.schabi.newpipe.download.DownloadDialog;
@@ -49,12 +49,11 @@ import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PermissionHelper;
import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.util.urlfinder.UrlFinder;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import icepick.Icepick;
@@ -625,78 +624,18 @@ public class RouterActivity extends AppCompatActivity {
// Utils
//////////////////////////////////////////////////////////////////////////*/
/**
* Removes invisible separators (\p{Z}) and punctuation characters including
* brackets (\p{P}). See http://www.regular-expressions.info/unicode.html for
* more details.
*/
private final static String REGEX_REMOVE_FROM_URL = "[\\p{Z}\\p{P}]";
@Nullable
private String getUrl(Intent intent) {
// first gather data and find service
String videoUrl = null;
String foundUrl = null;
if (intent.getData() != null) {
// this means the video was called though another app
videoUrl = intent.getData().toString();
// Called from another app
foundUrl = 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);
final String[] uris = getUris(extraText);
videoUrl = uris.length > 0 ? uris[0] : null;
// Called from the share menu
final String extraText = intent.getStringExtra(Intent.EXTRA_TEXT);
foundUrl = UrlFinder.firstUrlFromInput(extraText);
}
return videoUrl;
}
private String removeHeadingGibberish(final String input) {
int start = 0;
for (int i = input.indexOf("://") - 1; i >= 0; i--) {
if (!input.substring(i, i + 1).matches("\\p{L}")) {
start = i + 1;
break;
}
}
return input.substring(start, input.length());
}
private String trim(final String input) {
if (input == null || input.length() < 1) {
return input;
} else {
String output = input;
while (output.length() > 0 && output.substring(0, 1).matches(REGEX_REMOVE_FROM_URL)) {
output = output.substring(1);
}
while (output.length() > 0
&& output.substring(output.length() - 1, output.length()).matches(REGEX_REMOVE_FROM_URL)) {
output = output.substring(0, output.length() - 1);
}
return output;
}
}
/**
* Retrieves all Strings which look remotely like URLs from a text.
* Used if NewPipe was called through share menu.
*
* @param sharedText text to scan for URLs.
* @return potential URLs
*/
protected String[] getUris(final String sharedText) {
final Collection<String> result = new HashSet<>();
if (sharedText != null) {
final String[] array = sharedText.split("\\p{Space}");
for (String s : array) {
s = trim(s);
if (s.length() != 0) {
if (s.matches(".+://.+")) {
result.add(removeHeadingGibberish(s));
} else if (s.matches(".+\\..+")) {
result.add("http://" + s);
}
}
}
}
return result.toArray(new String[result.size()]);
return foundUrl;
}
}

View File

@@ -45,7 +45,8 @@ public class AboutActivity extends AppCompatActivity {
new SoftwareComponent("RxJava", "2016 - 2020", "RxJava Contributors", "https://github.com/ReactiveX/RxJava", StandardLicenses.APACHE2),
new SoftwareComponent("RxBinding", "2015 - 2018", "Jake Wharton", "https://github.com/JakeWharton/RxBinding", StandardLicenses.APACHE2),
new SoftwareComponent("PrettyTime", "2012 - 2020", "Lincoln Baxter, III", "https://github.com/ocpsoft/prettytime", StandardLicenses.APACHE2),
new SoftwareComponent("Markwon", "2017 - 2020", "Noties", "https://github.com/noties/Markwon", StandardLicenses.APACHE2)
new SoftwareComponent("Markwon", "2017 - 2020", "Noties", "https://github.com/noties/Markwon", StandardLicenses.APACHE2),
new SoftwareComponent("Groupie", "2016", "Lisa Wray", "https://github.com/lisawray/groupie", StandardLicenses.MIT)
};
/**

View File

@@ -4,6 +4,12 @@ import androidx.room.Database;
import androidx.room.RoomDatabase;
import androidx.room.TypeConverters;
import org.schabi.newpipe.database.feed.dao.FeedDAO;
import org.schabi.newpipe.database.feed.dao.FeedGroupDAO;
import org.schabi.newpipe.database.feed.model.FeedEntity;
import org.schabi.newpipe.database.feed.model.FeedGroupEntity;
import org.schabi.newpipe.database.feed.model.FeedGroupSubscriptionEntity;
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity;
import org.schabi.newpipe.database.history.dao.SearchHistoryDAO;
import org.schabi.newpipe.database.history.dao.StreamHistoryDAO;
import org.schabi.newpipe.database.history.model.SearchHistoryEntry;
@@ -21,35 +27,33 @@ import org.schabi.newpipe.database.stream.model.StreamStateEntity;
import org.schabi.newpipe.database.subscription.SubscriptionDAO;
import org.schabi.newpipe.database.subscription.SubscriptionEntity;
import static org.schabi.newpipe.database.Migrations.DB_VER_12_0;
import static org.schabi.newpipe.database.Migrations.DB_VER_3;
@TypeConverters({Converters.class})
@Database(
entities = {
SubscriptionEntity.class, SearchHistoryEntry.class,
StreamEntity.class, StreamHistoryEntity.class, StreamStateEntity.class,
PlaylistEntity.class, PlaylistStreamEntity.class, PlaylistRemoteEntity.class
PlaylistEntity.class, PlaylistStreamEntity.class, PlaylistRemoteEntity.class,
FeedEntity.class, FeedGroupEntity.class, FeedGroupSubscriptionEntity.class,
FeedLastUpdatedEntity.class
},
version = DB_VER_12_0,
exportSchema = false
version = DB_VER_3
)
public abstract class AppDatabase extends RoomDatabase {
public static final String DATABASE_NAME = "newpipe.db";
public abstract SubscriptionDAO subscriptionDAO();
public abstract SearchHistoryDAO searchHistoryDAO();
public abstract StreamDAO streamDAO();
public abstract StreamHistoryDAO streamHistoryDAO();
public abstract StreamStateDAO streamStateDAO();
public abstract PlaylistDAO playlistDAO();
public abstract PlaylistStreamDAO playlistStreamDAO();
public abstract PlaylistRemoteDAO playlistRemoteDAO();
public abstract FeedDAO feedDAO();
public abstract FeedGroupDAO feedGroupDAO();
public abstract SubscriptionDAO subscriptionDAO();
}

View File

@@ -3,6 +3,7 @@ package org.schabi.newpipe.database;
import androidx.room.TypeConverter;
import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.local.subscription.FeedGroupIcon;
import java.util.Date;
@@ -37,4 +38,18 @@ public class Converters {
public static String stringOf(StreamType streamType) {
return streamType.name();
}
@TypeConverter
public static Integer integerOf(FeedGroupIcon feedGroupIcon) {
return feedGroupIcon.getId();
}
@TypeConverter
public static FeedGroupIcon feedGroupIconOf(Integer id) {
for (FeedGroupIcon icon : FeedGroupIcon.values()) {
if (icon.getId() == id) return icon;
}
throw new IllegalArgumentException("There's no feed group icon with the id \"" + id + "\"");
}
}

View File

@@ -8,14 +8,14 @@ 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 int DB_VER_1 = 1;
public static final int DB_VER_2 = 2;
public static final int DB_VER_3 = 3;
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) {
public static final Migration MIGRATION_1_2 = new Migration(DB_VER_1, DB_VER_2) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
if(DEBUG) {
@@ -71,4 +71,40 @@ public class Migrations {
}
}
};
public static final Migration MIGRATION_2_3 = new Migration(DB_VER_2, DB_VER_3) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
// Add NOT NULLs and new fields
database.execSQL("CREATE TABLE IF NOT EXISTS streams_new " +
"(uid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, service_id INTEGER NOT NULL, url TEXT NOT NULL, title TEXT NOT NULL, stream_type TEXT NOT NULL," +
" duration INTEGER NOT NULL, uploader TEXT NOT NULL, thumbnail_url TEXT, view_count INTEGER, textual_upload_date TEXT, upload_date INTEGER," +
" is_upload_date_approximation INTEGER)");
database.execSQL("INSERT INTO streams_new (uid, service_id, url, title, stream_type," +
"duration, uploader, thumbnail_url, view_count," +
"textual_upload_date, upload_date, is_upload_date_approximation) " +
"SELECT uid, service_id, url, ifnull(title, ''), ifnull(stream_type, 'VIDEO_STREAM')," +
"ifnull(duration, 0), ifnull(uploader, ''), ifnull(thumbnail_url, ''), NULL," +
"NULL, NULL, NULL " +
"FROM streams " +
"WHERE url IS NOT NULL");
database.execSQL("DROP TABLE streams");
database.execSQL("ALTER TABLE streams_new RENAME TO streams");
database.execSQL("CREATE UNIQUE INDEX index_streams_service_id_url ON streams (service_id, url)");
// Tables for feed feature
database.execSQL("CREATE TABLE IF NOT EXISTS feed (stream_id INTEGER NOT NULL, subscription_id INTEGER NOT NULL, PRIMARY KEY(stream_id, subscription_id), FOREIGN KEY(stream_id) REFERENCES streams(uid) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(subscription_id) REFERENCES subscriptions(uid) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)");
database.execSQL("CREATE INDEX index_feed_subscription_id ON feed (subscription_id)");
database.execSQL("CREATE TABLE IF NOT EXISTS feed_group (uid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT NOT NULL, icon_id INTEGER NOT NULL, sort_order INTEGER NOT NULL)");
database.execSQL("CREATE INDEX index_feed_group_sort_order ON feed_group (sort_order)");
database.execSQL("CREATE TABLE IF NOT EXISTS feed_group_subscription_join (group_id INTEGER NOT NULL, subscription_id INTEGER NOT NULL, PRIMARY KEY(group_id, subscription_id), FOREIGN KEY(group_id) REFERENCES feed_group(uid) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(subscription_id) REFERENCES subscriptions(uid) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)");
database.execSQL("CREATE INDEX index_feed_group_subscription_join_subscription_id ON feed_group_subscription_join (subscription_id)");
database.execSQL("CREATE TABLE IF NOT EXISTS feed_last_updated (subscription_id INTEGER NOT NULL, last_updated INTEGER, PRIMARY KEY(subscription_id), FOREIGN KEY(subscription_id) REFERENCES subscriptions(uid) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)");
}
};
}

View File

@@ -0,0 +1,147 @@
package org.schabi.newpipe.database.feed.dao
import androidx.room.*
import io.reactivex.Flowable
import org.schabi.newpipe.database.feed.model.FeedEntity
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity
import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.database.subscription.SubscriptionEntity
import java.util.*
@Dao
abstract class FeedDAO {
@Query("DELETE FROM feed")
abstract fun deleteAll(): Int
@Query("""
SELECT s.* FROM streams s
INNER JOIN feed f
ON s.uid = f.stream_id
ORDER BY s.upload_date IS NULL DESC, s.upload_date DESC, s.uploader ASC
LIMIT 500
""")
abstract fun getAllStreams(): Flowable<List<StreamEntity>>
@Query("""
SELECT s.* FROM streams s
INNER JOIN feed f
ON s.uid = f.stream_id
INNER JOIN feed_group_subscription_join fgs
ON fgs.subscription_id = f.subscription_id
INNER JOIN feed_group fg
ON fg.uid = fgs.group_id
WHERE fgs.group_id = :groupId
ORDER BY s.upload_date IS NULL DESC, s.upload_date DESC, s.uploader ASC
LIMIT 500
""")
abstract fun getAllStreamsFromGroup(groupId: Long): Flowable<List<StreamEntity>>
@Query("""
DELETE FROM feed WHERE
feed.stream_id IN (
SELECT s.uid FROM streams s
INNER JOIN feed f
ON s.uid = f.stream_id
WHERE s.upload_date < :date
)
""")
abstract fun unlinkStreamsOlderThan(date: Date)
@Query("""
DELETE FROM feed
WHERE feed.subscription_id = :subscriptionId
AND feed.stream_id IN (
SELECT s.uid FROM streams s
INNER JOIN feed f
ON s.uid = f.stream_id
WHERE s.stream_type = "LIVE_STREAM" OR s.stream_type = "AUDIO_LIVE_STREAM"
)
""")
abstract fun unlinkOldLivestreams(subscriptionId: Long)
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract fun insert(feedEntity: FeedEntity)
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract fun insertAll(entities: List<FeedEntity>): List<Long>
@Insert(onConflict = OnConflictStrategy.IGNORE)
internal abstract fun insertLastUpdated(lastUpdatedEntity: FeedLastUpdatedEntity): Long
@Update(onConflict = OnConflictStrategy.IGNORE)
internal abstract fun updateLastUpdated(lastUpdatedEntity: FeedLastUpdatedEntity)
@Transaction
open fun setLastUpdatedForSubscription(lastUpdatedEntity: FeedLastUpdatedEntity) {
val id = insertLastUpdated(lastUpdatedEntity)
if (id == -1L) {
updateLastUpdated(lastUpdatedEntity)
}
}
@Query("""
SELECT MIN(lu.last_updated) FROM feed_last_updated lu
INNER JOIN feed_group_subscription_join fgs
ON fgs.subscription_id = lu.subscription_id AND fgs.group_id = :groupId
""")
abstract fun oldestSubscriptionUpdate(groupId: Long): Flowable<List<Date>>
@Query("SELECT MIN(last_updated) FROM feed_last_updated")
abstract fun oldestSubscriptionUpdateFromAll(): Flowable<List<Date>>
@Query("SELECT COUNT(*) FROM feed_last_updated WHERE last_updated IS NULL")
abstract fun notLoadedCount(): Flowable<Long>
@Query("""
SELECT COUNT(*) FROM subscriptions s
INNER JOIN feed_group_subscription_join fgs
ON s.uid = fgs.subscription_id AND fgs.group_id = :groupId
LEFT JOIN feed_last_updated lu
ON s.uid = lu.subscription_id
WHERE lu.last_updated IS NULL
""")
abstract fun notLoadedCountForGroup(groupId: Long): Flowable<Long>
@Query("""
SELECT s.* FROM subscriptions s
LEFT JOIN feed_last_updated lu
ON s.uid = lu.subscription_id
WHERE lu.last_updated IS NULL OR lu.last_updated < :outdatedThreshold
""")
abstract fun getAllOutdated(outdatedThreshold: Date): Flowable<List<SubscriptionEntity>>
@Query("""
SELECT s.* FROM subscriptions s
INNER JOIN feed_group_subscription_join fgs
ON s.uid = fgs.subscription_id AND fgs.group_id = :groupId
LEFT JOIN feed_last_updated lu
ON s.uid = lu.subscription_id
WHERE lu.last_updated IS NULL OR lu.last_updated < :outdatedThreshold
""")
abstract fun getAllOutdatedForGroup(groupId: Long, outdatedThreshold: Date): Flowable<List<SubscriptionEntity>>
}

View File

@@ -0,0 +1,62 @@
package org.schabi.newpipe.database.feed.dao
import androidx.room.*
import io.reactivex.Flowable
import io.reactivex.Maybe
import org.schabi.newpipe.database.feed.model.FeedGroupEntity
import org.schabi.newpipe.database.feed.model.FeedGroupSubscriptionEntity
@Dao
abstract class FeedGroupDAO {
@Query("SELECT * FROM feed_group ORDER BY sort_order ASC")
abstract fun getAll(): Flowable<List<FeedGroupEntity>>
@Query("SELECT * FROM feed_group WHERE uid = :groupId")
abstract fun getGroup(groupId: Long): Maybe<FeedGroupEntity>
@Transaction
open fun insert(feedGroupEntity: FeedGroupEntity): Long {
val nextSortOrder = nextSortOrder()
feedGroupEntity.sortOrder = nextSortOrder
return insertInternal(feedGroupEntity)
}
@Update(onConflict = OnConflictStrategy.IGNORE)
abstract fun update(feedGroupEntity: FeedGroupEntity): Int
@Query("DELETE FROM feed_group")
abstract fun deleteAll(): Int
@Query("DELETE FROM feed_group WHERE uid = :groupId")
abstract fun delete(groupId: Long): Int
@Query("SELECT subscription_id FROM feed_group_subscription_join WHERE group_id = :groupId")
abstract fun getSubscriptionIdsFor(groupId: Long): Flowable<List<Long>>
@Query("DELETE FROM feed_group_subscription_join WHERE group_id = :groupId")
abstract fun deleteSubscriptionsFromGroup(groupId: Long): Int
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract fun insertSubscriptionsToGroup(entities: List<FeedGroupSubscriptionEntity>): List<Long>
@Transaction
open fun updateSubscriptionsForGroup(groupId: Long, subscriptionIds: List<Long>) {
deleteSubscriptionsFromGroup(groupId)
insertSubscriptionsToGroup(subscriptionIds.map { FeedGroupSubscriptionEntity(groupId, it) })
}
@Transaction
open fun updateOrder(orderMap: Map<Long, Long>) {
orderMap.forEach { (groupId, sortOrder) -> updateOrder(groupId, sortOrder) }
}
@Query("UPDATE feed_group SET sort_order = :sortOrder WHERE uid = :groupId")
abstract fun updateOrder(groupId: Long, sortOrder: Long): Int
@Query("SELECT IFNULL(MAX(sort_order) + 1, 0) FROM feed_group")
protected abstract fun nextSortOrder(): Long
@Insert(onConflict = OnConflictStrategy.ABORT)
protected abstract fun insertInternal(feedGroupEntity: FeedGroupEntity): Long
}

View File

@@ -0,0 +1,43 @@
package org.schabi.newpipe.database.feed.model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index
import org.schabi.newpipe.database.feed.model.FeedEntity.Companion.FEED_TABLE
import org.schabi.newpipe.database.feed.model.FeedEntity.Companion.STREAM_ID
import org.schabi.newpipe.database.feed.model.FeedEntity.Companion.SUBSCRIPTION_ID
import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.database.subscription.SubscriptionEntity
@Entity(tableName = FEED_TABLE,
primaryKeys = [STREAM_ID, SUBSCRIPTION_ID],
indices = [Index(SUBSCRIPTION_ID)],
foreignKeys = [
ForeignKey(
entity = StreamEntity::class,
parentColumns = [StreamEntity.STREAM_ID],
childColumns = [STREAM_ID],
onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE, deferred = true),
ForeignKey(
entity = SubscriptionEntity::class,
parentColumns = [SubscriptionEntity.SUBSCRIPTION_UID],
childColumns = [SUBSCRIPTION_ID],
onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE, deferred = true)
]
)
data class FeedEntity(
@ColumnInfo(name = STREAM_ID)
var streamId: Long,
@ColumnInfo(name = SUBSCRIPTION_ID)
var subscriptionId: Long
) {
companion object {
const val FEED_TABLE = "feed"
const val STREAM_ID = "stream_id"
const val SUBSCRIPTION_ID = "subscription_id"
}
}

View File

@@ -0,0 +1,39 @@
package org.schabi.newpipe.database.feed.model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Index
import androidx.room.PrimaryKey
import org.schabi.newpipe.database.feed.model.FeedGroupEntity.Companion.FEED_GROUP_TABLE
import org.schabi.newpipe.database.feed.model.FeedGroupEntity.Companion.SORT_ORDER
import org.schabi.newpipe.local.subscription.FeedGroupIcon
@Entity(
tableName = FEED_GROUP_TABLE,
indices = [Index(SORT_ORDER)]
)
data class FeedGroupEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = ID)
val uid: Long,
@ColumnInfo(name = NAME)
var name: String,
@ColumnInfo(name = ICON)
var icon: FeedGroupIcon,
@ColumnInfo(name = SORT_ORDER)
var sortOrder: Long = -1
) {
companion object {
const val FEED_GROUP_TABLE = "feed_group"
const val ID = "uid"
const val NAME = "name"
const val ICON = "icon_id"
const val SORT_ORDER = "sort_order"
const val GROUP_ALL_ID = -1L
}
}

View File

@@ -0,0 +1,45 @@
package org.schabi.newpipe.database.feed.model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.ForeignKey.CASCADE
import androidx.room.Index
import org.schabi.newpipe.database.feed.model.FeedGroupSubscriptionEntity.Companion.FEED_GROUP_SUBSCRIPTION_TABLE
import org.schabi.newpipe.database.feed.model.FeedGroupSubscriptionEntity.Companion.GROUP_ID
import org.schabi.newpipe.database.feed.model.FeedGroupSubscriptionEntity.Companion.SUBSCRIPTION_ID
import org.schabi.newpipe.database.subscription.SubscriptionEntity
@Entity(
tableName = FEED_GROUP_SUBSCRIPTION_TABLE,
primaryKeys = [GROUP_ID, SUBSCRIPTION_ID],
indices = [Index(SUBSCRIPTION_ID)],
foreignKeys = [
ForeignKey(
entity = FeedGroupEntity::class,
parentColumns = [FeedGroupEntity.ID],
childColumns = [GROUP_ID],
onDelete = CASCADE, onUpdate = CASCADE, deferred = true),
ForeignKey(
entity = SubscriptionEntity::class,
parentColumns = [SubscriptionEntity.SUBSCRIPTION_UID],
childColumns = [SUBSCRIPTION_ID],
onDelete = CASCADE, onUpdate = CASCADE, deferred = true)
]
)
data class FeedGroupSubscriptionEntity(
@ColumnInfo(name = GROUP_ID)
var feedGroupId: Long,
@ColumnInfo(name = SUBSCRIPTION_ID)
var subscriptionId: Long
) {
companion object {
const val FEED_GROUP_SUBSCRIPTION_TABLE = "feed_group_subscription_join"
const val GROUP_ID = "group_id"
const val SUBSCRIPTION_ID = "subscription_id"
}
}

View File

@@ -0,0 +1,37 @@
package org.schabi.newpipe.database.feed.model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity.Companion.FEED_LAST_UPDATED_TABLE
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity.Companion.SUBSCRIPTION_ID
import org.schabi.newpipe.database.subscription.SubscriptionEntity
import java.util.*
@Entity(
tableName = FEED_LAST_UPDATED_TABLE,
foreignKeys = [
ForeignKey(
entity = SubscriptionEntity::class,
parentColumns = [SubscriptionEntity.SUBSCRIPTION_UID],
childColumns = [SUBSCRIPTION_ID],
onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE, deferred = true)
]
)
data class FeedLastUpdatedEntity(
@PrimaryKey
@ColumnInfo(name = SUBSCRIPTION_ID)
var subscriptionId: Long,
@ColumnInfo(name = LAST_UPDATED)
var lastUpdated: Date? = null
) {
companion object {
const val FEED_LAST_UPDATED_TABLE = "feed_last_updated"
const val SUBSCRIPTION_ID = "subscription_id"
const val LAST_UPDATED = "last_updated"
}
}

View File

@@ -1,59 +0,0 @@
package org.schabi.newpipe.database.history.model;
import androidx.room.ColumnInfo;
import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.extractor.stream.StreamType;
import java.util.Date;
public class StreamHistoryEntry {
@ColumnInfo(name = StreamEntity.STREAM_ID)
final public long uid;
@ColumnInfo(name = StreamEntity.STREAM_SERVICE_ID)
final public int serviceId;
@ColumnInfo(name = StreamEntity.STREAM_URL)
final public String url;
@ColumnInfo(name = StreamEntity.STREAM_TITLE)
final public String title;
@ColumnInfo(name = StreamEntity.STREAM_TYPE)
final public StreamType streamType;
@ColumnInfo(name = StreamEntity.STREAM_DURATION)
final public long duration;
@ColumnInfo(name = StreamEntity.STREAM_UPLOADER)
final public String uploader;
@ColumnInfo(name = StreamEntity.STREAM_THUMBNAIL_URL)
final public String thumbnailUrl;
@ColumnInfo(name = StreamHistoryEntity.JOIN_STREAM_ID)
final public long streamId;
@ColumnInfo(name = StreamHistoryEntity.STREAM_ACCESS_DATE)
final public Date accessDate;
@ColumnInfo(name = StreamHistoryEntity.STREAM_REPEAT_COUNT)
final public long repeatCount;
public StreamHistoryEntry(long uid, int serviceId, String url, String title,
StreamType streamType, long duration, String uploader,
String thumbnailUrl, long streamId, Date accessDate,
long repeatCount) {
this.uid = uid;
this.serviceId = serviceId;
this.url = url;
this.title = title;
this.streamType = streamType;
this.duration = duration;
this.uploader = uploader;
this.thumbnailUrl = thumbnailUrl;
this.streamId = streamId;
this.accessDate = accessDate;
this.repeatCount = repeatCount;
}
public StreamHistoryEntity toStreamHistoryEntity() {
return new StreamHistoryEntity(streamId, accessDate, repeatCount);
}
public boolean hasEqualValues(StreamHistoryEntry other) {
return this.uid == other.uid && streamId == other.streamId &&
accessDate.compareTo(other.accessDate) == 0;
}
}

View File

@@ -0,0 +1,30 @@
package org.schabi.newpipe.database.history.model
import androidx.room.ColumnInfo
import androidx.room.Embedded
import org.schabi.newpipe.database.stream.model.StreamEntity
import java.util.*
data class StreamHistoryEntry(
@Embedded
val streamEntity: StreamEntity,
@ColumnInfo(name = StreamHistoryEntity.JOIN_STREAM_ID)
val streamId: Long,
@ColumnInfo(name = StreamHistoryEntity.STREAM_ACCESS_DATE)
val accessDate: Date,
@ColumnInfo(name = StreamHistoryEntity.STREAM_REPEAT_COUNT)
val repeatCount: Long
) {
fun toStreamHistoryEntity(): StreamHistoryEntity {
return StreamHistoryEntity(streamId, accessDate, repeatCount)
}
fun hasEqualValues(other: StreamHistoryEntry): Boolean {
return this.streamEntity.uid == other.streamEntity.uid && streamId == other.streamId &&
accessDate.compareTo(other.accessDate) == 0
}
}

View File

@@ -1,60 +0,0 @@
package org.schabi.newpipe.database.playlist;
import androidx.room.ColumnInfo;
import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity;
import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.stream.StreamType;
public class PlaylistStreamEntry implements LocalItem {
@ColumnInfo(name = StreamEntity.STREAM_ID)
final public long uid;
@ColumnInfo(name = StreamEntity.STREAM_SERVICE_ID)
final public int serviceId;
@ColumnInfo(name = StreamEntity.STREAM_URL)
final public String url;
@ColumnInfo(name = StreamEntity.STREAM_TITLE)
final public String title;
@ColumnInfo(name = StreamEntity.STREAM_TYPE)
final public StreamType streamType;
@ColumnInfo(name = StreamEntity.STREAM_DURATION)
final public long duration;
@ColumnInfo(name = StreamEntity.STREAM_UPLOADER)
final public String uploader;
@ColumnInfo(name = StreamEntity.STREAM_THUMBNAIL_URL)
final public String thumbnailUrl;
@ColumnInfo(name = PlaylistStreamEntity.JOIN_STREAM_ID)
final public long streamId;
@ColumnInfo(name = PlaylistStreamEntity.JOIN_INDEX)
final public int joinIndex;
public PlaylistStreamEntry(long uid, int serviceId, String url, String title,
StreamType streamType, long duration, String uploader,
String thumbnailUrl, long streamId, int joinIndex) {
this.uid = uid;
this.serviceId = serviceId;
this.url = url;
this.title = title;
this.streamType = streamType;
this.duration = duration;
this.uploader = uploader;
this.thumbnailUrl = thumbnailUrl;
this.streamId = streamId;
this.joinIndex = joinIndex;
}
public StreamInfoItem toStreamInfoItem() throws IllegalArgumentException {
StreamInfoItem item = new StreamInfoItem(serviceId, url, title, streamType);
item.setThumbnailUrl(thumbnailUrl);
item.setUploaderName(uploader);
item.setDuration(duration);
return item;
}
@Override
public LocalItemType getLocalItemType() {
return LocalItemType.PLAYLIST_STREAM_ITEM;
}
}

View File

@@ -0,0 +1,34 @@
package org.schabi.newpipe.database.playlist
import androidx.room.ColumnInfo
import androidx.room.Embedded
import org.schabi.newpipe.database.LocalItem
import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity
import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.extractor.stream.StreamInfoItem
class PlaylistStreamEntry(
@Embedded
val streamEntity: StreamEntity,
@ColumnInfo(name = PlaylistStreamEntity.JOIN_STREAM_ID)
val streamId: Long,
@ColumnInfo(name = PlaylistStreamEntity.JOIN_INDEX)
val joinIndex: Int
) : LocalItem {
@Throws(IllegalArgumentException::class)
fun toStreamInfoItem(): StreamInfoItem {
val item = StreamInfoItem(streamEntity.serviceId, streamEntity.url, streamEntity.title, streamEntity.streamType)
item.duration = streamEntity.duration
item.uploaderName = streamEntity.uploader
item.thumbnailUrl = streamEntity.thumbnailUrl
return item
}
override fun getLocalItemType(): LocalItem.LocalItemType {
return LocalItem.LocalItemType.PLAYLIST_STREAM_ITEM
}
}

View File

@@ -1,69 +0,0 @@
package org.schabi.newpipe.database.stream;
import androidx.room.ColumnInfo;
import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.database.history.model.StreamHistoryEntity;
import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.stream.StreamType;
import java.util.Date;
public class StreamStatisticsEntry implements LocalItem {
final public static String STREAM_LATEST_DATE = "latestAccess";
final public static String STREAM_WATCH_COUNT = "watchCount";
@ColumnInfo(name = StreamEntity.STREAM_ID)
final public long uid;
@ColumnInfo(name = StreamEntity.STREAM_SERVICE_ID)
final public int serviceId;
@ColumnInfo(name = StreamEntity.STREAM_URL)
final public String url;
@ColumnInfo(name = StreamEntity.STREAM_TITLE)
final public String title;
@ColumnInfo(name = StreamEntity.STREAM_TYPE)
final public StreamType streamType;
@ColumnInfo(name = StreamEntity.STREAM_DURATION)
final public long duration;
@ColumnInfo(name = StreamEntity.STREAM_UPLOADER)
final public String uploader;
@ColumnInfo(name = StreamEntity.STREAM_THUMBNAIL_URL)
final public String thumbnailUrl;
@ColumnInfo(name = StreamHistoryEntity.JOIN_STREAM_ID)
final public long streamId;
@ColumnInfo(name = StreamStatisticsEntry.STREAM_LATEST_DATE)
final public Date latestAccessDate;
@ColumnInfo(name = StreamStatisticsEntry.STREAM_WATCH_COUNT)
final public long watchCount;
public StreamStatisticsEntry(long uid, int serviceId, String url, String title,
StreamType streamType, long duration, String uploader,
String thumbnailUrl, long streamId, Date latestAccessDate,
long watchCount) {
this.uid = uid;
this.serviceId = serviceId;
this.url = url;
this.title = title;
this.streamType = streamType;
this.duration = duration;
this.uploader = uploader;
this.thumbnailUrl = thumbnailUrl;
this.streamId = streamId;
this.latestAccessDate = latestAccessDate;
this.watchCount = watchCount;
}
public StreamInfoItem toStreamInfoItem() {
StreamInfoItem item = new StreamInfoItem(serviceId, url, title, streamType);
item.setDuration(duration);
item.setUploaderName(uploader);
item.setThumbnailUrl(thumbnailUrl);
return item;
}
@Override
public LocalItemType getLocalItemType() {
return LocalItemType.STATISTIC_STREAM_ITEM;
}
}

View File

@@ -0,0 +1,42 @@
package org.schabi.newpipe.database.stream
import androidx.room.ColumnInfo
import androidx.room.Embedded
import org.schabi.newpipe.database.LocalItem
import org.schabi.newpipe.database.history.model.StreamHistoryEntity
import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.extractor.stream.StreamInfoItem
import java.util.*
class StreamStatisticsEntry(
@Embedded
val streamEntity: StreamEntity,
@ColumnInfo(name = StreamHistoryEntity.JOIN_STREAM_ID)
val streamId: Long,
@ColumnInfo(name = STREAM_LATEST_DATE)
val latestAccessDate: Date,
@ColumnInfo(name = STREAM_WATCH_COUNT)
val watchCount: Long
) : LocalItem {
fun toStreamInfoItem(): StreamInfoItem {
val item = StreamInfoItem(streamEntity.serviceId, streamEntity.url, streamEntity.title, streamEntity.streamType)
item.duration = streamEntity.duration
item.uploaderName = streamEntity.uploader
item.thumbnailUrl = streamEntity.thumbnailUrl
return item
}
override fun getLocalItemType(): LocalItem.LocalItemType {
return LocalItem.LocalItemType.STATISTIC_STREAM_ITEM
}
companion object {
const val STREAM_LATEST_DATE = "latestAccess"
const val STREAM_WATCH_COUNT = "watchCount"
}
}

View File

@@ -1,98 +0,0 @@
package org.schabi.newpipe.database.stream.dao;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.Transaction;
import org.schabi.newpipe.database.BasicDAO;
import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity;
import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.database.history.model.StreamHistoryEntity;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.Flowable;
import static org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity.PLAYLIST_STREAM_JOIN_TABLE;
import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_ID;
import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_SERVICE_ID;
import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_TABLE;
import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_URL;
import static org.schabi.newpipe.database.history.model.StreamHistoryEntity.STREAM_HISTORY_TABLE;
@Dao
public abstract class StreamDAO implements BasicDAO<StreamEntity> {
@Override
@Query("SELECT * FROM " + STREAM_TABLE)
public abstract Flowable<List<StreamEntity>> getAll();
@Override
@Query("DELETE FROM " + STREAM_TABLE)
public abstract int deleteAll();
@Override
@Query("SELECT * FROM " + STREAM_TABLE + " WHERE " + STREAM_SERVICE_ID + " = :serviceId")
public abstract Flowable<List<StreamEntity>> listByService(int serviceId);
@Query("SELECT * FROM " + STREAM_TABLE + " WHERE " +
STREAM_URL + " = :url AND " +
STREAM_SERVICE_ID + " = :serviceId")
public abstract Flowable<List<StreamEntity>> getStream(long serviceId, String url);
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract void silentInsertAllInternal(final List<StreamEntity> streams);
@Query("SELECT " + STREAM_ID + " FROM " + STREAM_TABLE + " WHERE " +
STREAM_URL + " = :url AND " +
STREAM_SERVICE_ID + " = :serviceId")
abstract Long getStreamIdInternal(long serviceId, String url);
@Transaction
public long upsert(StreamEntity stream) {
final Long streamIdCandidate = getStreamIdInternal(stream.getServiceId(), stream.getUrl());
if (streamIdCandidate == null) {
return insert(stream);
} else {
stream.setUid(streamIdCandidate);
update(stream);
return streamIdCandidate;
}
}
@Transaction
public List<Long> upsertAll(List<StreamEntity> streams) {
silentInsertAllInternal(streams);
final List<Long> streamIds = new ArrayList<>(streams.size());
for (StreamEntity stream : streams) {
final Long streamId = getStreamIdInternal(stream.getServiceId(), stream.getUrl());
if (streamId == null) {
throw new IllegalStateException("StreamID cannot be null just after insertion.");
}
streamIds.add(streamId);
stream.setUid(streamId);
}
update(streams);
return streamIds;
}
@Query("DELETE FROM " + STREAM_TABLE + " WHERE " + STREAM_ID +
" NOT IN " +
"(SELECT DISTINCT " + STREAM_ID + " FROM " + STREAM_TABLE +
" LEFT JOIN " + STREAM_HISTORY_TABLE +
" ON " + STREAM_ID + " = " +
StreamHistoryEntity.STREAM_HISTORY_TABLE + "." + StreamHistoryEntity.JOIN_STREAM_ID +
" LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE +
" ON " + STREAM_ID + " = " +
PlaylistStreamEntity.PLAYLIST_STREAM_JOIN_TABLE + "." + PlaylistStreamEntity.JOIN_STREAM_ID +
")")
public abstract int deleteOrphans();
}

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