mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-11-20 09:06:27 +01:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
442220debc
36
.github/CONTRIBUTING.md
vendored
Normal file
36
.github/CONTRIBUTING.md
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
NewPipe contribution guidelines
|
||||
===============================
|
||||
|
||||
READ THIS GUIDELINES CAREFULLY BEFORE CONTRIBUTING.
|
||||
|
||||
## Crash reporting
|
||||
|
||||
Do not report crashes in the GitHub issue tracker. NewPipe has an automated crash report system that will ask you to send a report if a crash occures.
|
||||
|
||||
## Issue reporting/feature request
|
||||
|
||||
* Search the [existing issues](https://github.com/theScrabi/NewPipe/issues) first to make sure your issue/feature hasn't been reported/requested before
|
||||
* Check if this issue/feature is already fixed/implemented in the repository
|
||||
* If you are an android/java developer you are always welcome to fix/implement an issue/a feature yourself
|
||||
|
||||
## Translation
|
||||
|
||||
* NewPipe can be translated on [weblate](https://hosted.weblate.org/projects/newpipe/strings/)
|
||||
|
||||
## Code contribution
|
||||
|
||||
* Stick to NewPipe style guidelines (just look the other code and than do it the same way :) )
|
||||
* Do not bring nonfree software/binary blobs into the project (keep it google free)
|
||||
* Stick to [f-droid contribution guidelines](https://f-droid.org/wiki/page/Inclusion_Policy)
|
||||
* Make changes on a separate branch, not on the master branch (Feature-branching)
|
||||
* When submitting changes, you agree that your code will be licensed under GPLv3
|
||||
* Please test (compile and run) your code before you submit changes!!!
|
||||
* Try to figure out you selves why CI fails, or why a merge request collides
|
||||
* Please maintain your code after you contributed it.
|
||||
* Respond yourselves if someone request changes or notifies issues
|
||||
|
||||
## Communication
|
||||
|
||||
* I hereby declare our Slack channel as dead!!! There are no plans on building a new chat, but if there is interest on creating one and keeping it alive, I'd be pleased to create one again.
|
||||
* If you want to get in contact with me or one of our other contributors you can send me an email at tnp(at)schabi.org
|
||||
* Feel free to post suggestions, changes, ideas etc!
|
2
.github/ISSUE_TEMPLATE.md
vendored
Normal file
2
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
- [ ] I carefully reed 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.
|
1
.github/PULL_REQUEST_TEAMPLATE.md
vendored
Normal file
1
.github/PULL_REQUEST_TEAMPLATE.md
vendored
Normal file
@ -0,0 +1 @@
|
||||
[ ] I carefully reed the [contribution guidelines](https://github.com/TeamNewPipe/NewPipe/blob/HEAD/.github/CONTRIBUTING.md) and agree to them.
|
@ -1,33 +0,0 @@
|
||||
#Contribution
|
||||
|
||||
This document contains guidelines on making contributions to NewPipe.
|
||||
|
||||
## Programming
|
||||
|
||||
* Follow the [Google Style Guidelines](https://google.github.io/styleguide/javaguide.html)
|
||||
* Make a new feature on a separate branch, not on the master branch
|
||||
* Make a [pull request](https://github.com/theScrabi/NewPipe/pulls) if you're done with your changes
|
||||
* When submitting changes, you agree that your code will be GPLv3 licensed
|
||||
|
||||
## Commit messages
|
||||
|
||||
* The subject line of your commit message shouldn't be longer than 72 characters
|
||||
* Try to keep each line of your commit message 72 characters to ensure proper
|
||||
compatibility with all git tools
|
||||
* [This guide](http://chris.beams.io/posts/git-commit/) goes more in depth on what makes a good commit message
|
||||
|
||||
## Translation
|
||||
|
||||
* NewPipe can be translated on [weblate](https://hosted.weblate.org/projects/newpipe/strings/)
|
||||
|
||||
## Issue reporting
|
||||
|
||||
* Search the [existing issues](https://github.com/theScrabi/NewPipe/issues) first to make sure your issue hasn't been reported before
|
||||
* Check if this issue is already fixed in the repository
|
||||
* When making bug reports, be sure to tell which version of NewPipe you are using and the steps to reproduce the problem
|
||||
* Please include a log if you can
|
||||
|
||||
## Communication
|
||||
|
||||
* For the time being, [Slack](https://newpipe.slack.com/) is being used for project communication. Ask [me](https://github.com/theScrabi) to sign up.
|
||||
* Feel free to post suggestions, changes, ideas etc!
|
14
README.md
14
README.md
@ -4,21 +4,19 @@ WARNING: PUTTING NEWPIPE OR ANY FORK OF IT INTO GOOGLE PLAYSTORE VIOLATES THEIR
|
||||
NewPipe: A free lightweight Youtube frontend for Android.
|
||||
|
||||
[![NewPipe](app/src/main/res/mipmap-xhdpi/ic_launcher.png)](https://newpipe.schabi.org)
|
||||
[![F-Droid](https://f-droid.org/wiki/images/0/06/F-Droid-button_get-it-on.png)](https://f-droid.org/repository/browse/?fdfilter=newpipe&fdid=org.schabi.newpipe)
|
||||
|
||||
|
||||
Project status:
|
||||
[![Translation Status](https://hosted.weblate.org/widgets/NewPipe/-/svg-badge.svg)](https://hosted.weblate.org/engage/NewPipe/)
|
||||
[![Build Status](https://travis-ci.org/theScrabi/NewPipe.svg)](https://travis-ci.org/theScrabi/NewPipe)
|
||||
|
||||
## Get NewPipe
|
||||
|
||||
[![F-Droid](https://f-droid.org/wiki/images/0/06/F-Droid-button_get-it-on.png)](https://f-droid.org/repository/browse/?fdfilter=newpipe&fdid=org.schabi.newpipe)
|
||||
[![Build Status](https://travis-ci.org/TeamNewPipe/NewPipe.svg)](https://travis-ci.org/TeamNewPipe/NewPipe)
|
||||
|
||||
## Donate
|
||||
![Bitcoin](https://bitcoin.org/img/icons/logotop.svg)
|
||||
`16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh`
|
||||
|
||||
![BitcoinQR](assets/16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh.png)
|
||||
|
||||
`16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh`
|
||||
|
||||
## Screenshots
|
||||
|
||||
[<img src="screenshots/screenshot_1.png" width=150>](screenshots/screenshot_1.png)
|
||||
@ -66,7 +64,7 @@ Although NewPipe only supports YouTube at the moment, it's designed to support m
|
||||
Whether you have ideas, translation, design changes, code cleaning, or real heavy code changes, help is always welcome.
|
||||
The more is done the better it gets!
|
||||
|
||||
If you'd like to get involved, check our [contribution notes](CONTRIBUTING.md).
|
||||
If you'd like to get involved, check our [contribution notes](.github/CONTRIBUTING.md).
|
||||
|
||||
## License
|
||||
[![GNU GPLv3 Image](https://www.gnu.org/graphics/gplv3-127x51.png)](http://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
@ -8,8 +8,8 @@ android {
|
||||
applicationId "org.schabi.newpipe"
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 24
|
||||
versionCode 18
|
||||
versionName "0.8.0"
|
||||
versionCode 19
|
||||
versionName "0.8.5"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
|
@ -133,7 +133,7 @@
|
||||
|
||||
<!-- giga get related -->
|
||||
<activity
|
||||
android:name=".download.MainActivity"
|
||||
android:name=".download.DownloadActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/AppTheme" />
|
||||
|
@ -26,6 +26,7 @@ import org.schabi.newpipe.extractor.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.ParsingException;
|
||||
import org.schabi.newpipe.extractor.ServiceList;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.info_list.InfoListAdapter;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
|
||||
@ -84,7 +85,7 @@ public class ChannelActivity extends AppCompatActivity {
|
||||
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.setAdapter(infoListAdapter);
|
||||
infoListAdapter.setOnItemSelectedListener(new InfoListAdapter.OnItemSelectedListener() {
|
||||
infoListAdapter.setOnItemSelectedListener(new InfoItemBuilder.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void selected(String url) {
|
||||
Intent detailIntent = new Intent(ChannelActivity.this, VideoItemDetailActivity.class);
|
||||
|
@ -16,7 +16,7 @@ import org.schabi.newpipe.settings.SettingsActivity;
|
||||
* Created by Christian Schabesberger on 02.08.16.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
||||
* MainActivity.java is part of NewPipe.
|
||||
* DownloadActivity.java is part of NewPipe.
|
||||
*
|
||||
* NewPipe is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -73,7 +73,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
return true;
|
||||
}
|
||||
case R.id.action_show_downloads: {
|
||||
Intent intent = new Intent(this, org.schabi.newpipe.download.MainActivity.class);
|
||||
Intent intent = new Intent(this, org.schabi.newpipe.download.DownloadActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ class ActionBarHandler {
|
||||
return true;
|
||||
case R.id.menu_item_downloads: {
|
||||
Intent intent =
|
||||
new Intent(activity, org.schabi.newpipe.download.MainActivity.class);
|
||||
new Intent(activity, org.schabi.newpipe.download.DownloadActivity.class);
|
||||
activity.startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.Html;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
@ -27,6 +26,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
@ -43,6 +43,8 @@ import java.util.Vector;
|
||||
|
||||
import org.schabi.newpipe.ActivityCommunicator;
|
||||
import org.schabi.newpipe.ChannelActivity;
|
||||
import org.schabi.newpipe.extractor.StreamPreviewInfo;
|
||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
import org.schabi.newpipe.ImageErrorLoadingListener;
|
||||
import org.schabi.newpipe.Localization;
|
||||
@ -53,7 +55,6 @@ import org.schabi.newpipe.extractor.MediaFormat;
|
||||
import org.schabi.newpipe.extractor.ServiceList;
|
||||
import org.schabi.newpipe.extractor.StreamInfo;
|
||||
import org.schabi.newpipe.extractor.VideoStream;
|
||||
import org.schabi.newpipe.info_list.InfoListAdapter;
|
||||
import org.schabi.newpipe.player.BackgroundPlayer;
|
||||
import org.schabi.newpipe.player.PlayVideoActivity;
|
||||
import org.schabi.newpipe.player.ExoPlayerActivity;
|
||||
@ -110,7 +111,7 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
private DisplayImageOptions displayImageOptions =
|
||||
new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
||||
|
||||
private InfoListAdapter similarStreamsAdapter = null;
|
||||
private InfoItemBuilder infoItemBuilder = null;
|
||||
|
||||
public interface OnInvokeCreateOptionsMenuListener {
|
||||
void createOptionsMenu();
|
||||
@ -119,47 +120,41 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
private OnInvokeCreateOptionsMenuListener onInvokeCreateOptionsMenuListener;
|
||||
|
||||
private void updateInfo(final StreamInfo info) {
|
||||
try {
|
||||
Activity a = getActivity();
|
||||
Activity a = getActivity();
|
||||
|
||||
RelativeLayout textContentLayout =
|
||||
(RelativeLayout) activity.findViewById(R.id.detail_text_content_layout);
|
||||
final TextView videoTitleView =
|
||||
(TextView) activity.findViewById(R.id.detail_video_title_view);
|
||||
TextView uploaderView = (TextView) activity.findViewById(R.id.detail_uploader_view);
|
||||
TextView viewCountView = (TextView) activity.findViewById(R.id.detail_view_count_view);
|
||||
TextView thumbsUpView = (TextView) activity.findViewById(R.id.detail_thumbs_up_count_view);
|
||||
TextView thumbsDownView =
|
||||
(TextView) activity.findViewById(R.id.detail_thumbs_down_count_view);
|
||||
TextView uploadDateView = (TextView) activity.findViewById(R.id.detail_upload_date_view);
|
||||
TextView descriptionView = (TextView) activity.findViewById(R.id.detail_description_view);
|
||||
RecyclerView nextStreamView =
|
||||
(RecyclerView) activity.findViewById(R.id.detail_next_stream_content);
|
||||
RelativeLayout nextVideoRootFrame =
|
||||
(RelativeLayout) activity.findViewById(R.id.detail_next_stream_root_layout);
|
||||
TextView similarTitle = (TextView) activity.findViewById(R.id.detail_similar_title);
|
||||
Button backgroundButton = (Button)
|
||||
activity.findViewById(R.id.detail_stream_thumbnail_window_background_button);
|
||||
View topView = activity.findViewById(R.id.detailTopView);
|
||||
Button channelButton = (Button) activity.findViewById(R.id.channel_button);
|
||||
RelativeLayout textContentLayout =
|
||||
(RelativeLayout) activity.findViewById(R.id.detail_text_content_layout);
|
||||
final TextView videoTitleView =
|
||||
(TextView) activity.findViewById(R.id.detail_video_title_view);
|
||||
TextView uploaderView = (TextView) activity.findViewById(R.id.detail_uploader_view);
|
||||
TextView viewCountView = (TextView) activity.findViewById(R.id.detail_view_count_view);
|
||||
TextView thumbsUpView = (TextView) activity.findViewById(R.id.detail_thumbs_up_count_view);
|
||||
TextView thumbsDownView =
|
||||
(TextView) activity.findViewById(R.id.detail_thumbs_down_count_view);
|
||||
TextView uploadDateView = (TextView) activity.findViewById(R.id.detail_upload_date_view);
|
||||
TextView descriptionView = (TextView) activity.findViewById(R.id.detail_description_view);
|
||||
RecyclerView nextStreamView =
|
||||
(RecyclerView) activity.findViewById(R.id.detail_next_stream_content);
|
||||
RelativeLayout nextVideoRootFrame =
|
||||
(RelativeLayout) activity.findViewById(R.id.detail_next_stream_root_layout);
|
||||
TextView similarTitle = (TextView) activity.findViewById(R.id.detail_similar_title);
|
||||
Button backgroundButton = (Button)
|
||||
activity.findViewById(R.id.detail_stream_thumbnail_window_background_button);
|
||||
View topView = activity.findViewById(R.id.detailTopView);
|
||||
Button channelButton = (Button) activity.findViewById(R.id.channel_button);
|
||||
|
||||
// prevents a crash if the activity/fragment was already left when the response came
|
||||
if(channelButton != null) {
|
||||
|
||||
progressBar.setVisibility(View.GONE);
|
||||
if(info.next_video != null) {
|
||||
InfoListAdapter adapter = new InfoListAdapter(a, rootView);
|
||||
nextStreamView.setAdapter(adapter);
|
||||
nextStreamView.setLayoutManager(new LinearLayoutManager(a));
|
||||
adapter.setOnItemSelectedListener(new InfoListAdapter.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void selected(String url) {
|
||||
openStreamUrl(url);
|
||||
}
|
||||
});
|
||||
if (info.next_video != null) {
|
||||
// todo: activate this function or remove it
|
||||
nextStreamView.setVisibility(View.GONE);
|
||||
} else {
|
||||
nextStreamView.setVisibility(View.GONE);
|
||||
activity.findViewById(R.id.detail_similar_title).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
||||
textContentLayout.setVisibility(View.VISIBLE);
|
||||
if (android.os.Build.VERSION.SDK_INT < 18) {
|
||||
playVideoButton.setVisibility(View.VISIBLE);
|
||||
@ -196,23 +191,23 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
// Since newpipe is designed to work even if certain information is not available,
|
||||
// the UI has to react on missing information.
|
||||
videoTitleView.setText(info.title);
|
||||
if(!info.uploader.isEmpty()) {
|
||||
if (!info.uploader.isEmpty()) {
|
||||
uploaderView.setText(info.uploader);
|
||||
} else {
|
||||
activity.findViewById(R.id.detail_uploader_view).setVisibility(View.GONE);
|
||||
}
|
||||
if(info.view_count >= 0) {
|
||||
if (info.view_count >= 0) {
|
||||
viewCountView.setText(Localization.localizeViewCount(info.view_count, a));
|
||||
} else {
|
||||
viewCountView.setVisibility(View.GONE);
|
||||
}
|
||||
if(info.dislike_count >= 0) {
|
||||
if (info.dislike_count >= 0) {
|
||||
thumbsDownView.setText(Localization.localizeNumber(info.dislike_count, a));
|
||||
} else {
|
||||
thumbsDownView.setVisibility(View.INVISIBLE);
|
||||
activity.findViewById(R.id.detail_thumbs_down_count_view).setVisibility(View.GONE);
|
||||
}
|
||||
if(info.like_count >= 0) {
|
||||
if (info.like_count >= 0) {
|
||||
thumbsUpView.setText(Localization.localizeNumber(info.like_count, a));
|
||||
} else {
|
||||
thumbsUpView.setVisibility(View.GONE);
|
||||
@ -220,12 +215,12 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
thumbsDownView.setVisibility(View.GONE);
|
||||
activity.findViewById(R.id.detail_thumbs_down_img_view).setVisibility(View.GONE);
|
||||
}
|
||||
if(!info.upload_date.isEmpty()) {
|
||||
if (!info.upload_date.isEmpty()) {
|
||||
uploadDateView.setText(Localization.localizeDate(info.upload_date, a));
|
||||
} else {
|
||||
uploadDateView.setVisibility(View.GONE);
|
||||
}
|
||||
if(!info.description.isEmpty()) {
|
||||
if (!info.description.isEmpty()) {
|
||||
descriptionView.setText(Html.fromHtml(info.description));
|
||||
} else {
|
||||
descriptionView.setVisibility(View.GONE);
|
||||
@ -243,11 +238,11 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
|
||||
textContentLayout.setVisibility(View.VISIBLE);
|
||||
|
||||
if(info.next_video == null) {
|
||||
if (info.next_video == null) {
|
||||
activity.findViewById(R.id.detail_next_stream_title).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(info.related_streams != null && !info.related_streams.isEmpty()) {
|
||||
if (info.related_streams != null && !info.related_streams.isEmpty()) {
|
||||
initSimilarVideos(info);
|
||||
} else {
|
||||
activity.findViewById(R.id.detail_similar_title).setVisibility(View.GONE);
|
||||
@ -256,7 +251,7 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
|
||||
setupActionBarHandler(info);
|
||||
|
||||
if(autoPlayEnabled) {
|
||||
if (autoPlayEnabled) {
|
||||
playVideo(info);
|
||||
}
|
||||
|
||||
@ -276,7 +271,7 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
|
||||
if(info.channel_url != null && info.channel_url != "") {
|
||||
if (info.channel_url != null && info.channel_url != "") {
|
||||
channelButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
@ -291,10 +286,6 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
}
|
||||
|
||||
initThumbnailViews(info);
|
||||
|
||||
} catch (java.lang.NullPointerException e) {
|
||||
Log.w(TAG, "updateInfo(): Fragment closed before thread ended work... or else");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,7 +294,7 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
ImageView uploaderThumb
|
||||
= (ImageView) activity.findViewById(R.id.detail_uploader_thumbnail_view);
|
||||
|
||||
if(info.thumbnail_url != null && !info.thumbnail_url.isEmpty()) {
|
||||
if (info.thumbnail_url != null && !info.thumbnail_url.isEmpty()) {
|
||||
imageLoader.displayImage(info.thumbnail_url, videoThumbnailView,
|
||||
displayImageOptions, new ImageLoadingListener() {
|
||||
@Override
|
||||
@ -331,7 +322,7 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
} else {
|
||||
videoThumbnailView.setImageResource(R.drawable.dummy_thumbnail_dark);
|
||||
}
|
||||
if(info.uploader_thumbnail_url != null && !info.uploader_thumbnail_url.isEmpty()) {
|
||||
if (info.uploader_thumbnail_url != null && !info.uploader_thumbnail_url.isEmpty()) {
|
||||
imageLoader.displayImage(info.uploader_thumbnail_url,
|
||||
uploaderThumb, displayImageOptions,
|
||||
new ImageErrorLoadingListener(activity, rootView, info.service_id));
|
||||
@ -431,7 +422,7 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
|
||||
if(info.audio_streams == null) {
|
||||
if (info.audio_streams == null) {
|
||||
actionBarHandler.showAudioAction(false);
|
||||
} else {
|
||||
actionBarHandler.setOnPlayAudioListener(new ActionBarHandler.OnActionListener() {
|
||||
@ -527,7 +518,16 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void initSimilarVideos(final StreamInfo info) {
|
||||
similarStreamsAdapter.addStreamItemList(info.related_streams);
|
||||
LinearLayout similarLayout = (LinearLayout) activity.findViewById(R.id.similar_streams_view);
|
||||
for (final StreamPreviewInfo item : info.related_streams) {
|
||||
similarLayout.addView(infoItemBuilder.buildView(similarLayout, item));
|
||||
}
|
||||
infoItemBuilder.setOnItemSelectedListener(new InfoItemBuilder.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void selected(String url) {
|
||||
openStreamUrl(url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onErrorBlockedByGema() {
|
||||
@ -640,6 +640,9 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
public void onActivityCreated(Bundle savedInstanceBundle) {
|
||||
super.onActivityCreated(savedInstanceBundle);
|
||||
Activity a = getActivity();
|
||||
|
||||
infoItemBuilder = new InfoItemBuilder(a, a.findViewById(android.R.id.content));
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT < 18) {
|
||||
playVideoButton = (FloatingActionButton) a.findViewById(R.id.play_video_button);
|
||||
}
|
||||
@ -681,17 +684,6 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
similarStreamsAdapter = new InfoListAdapter(getActivity(), rootView);
|
||||
RecyclerView rv = (RecyclerView) getActivity().findViewById(R.id.similar_streams_view);
|
||||
rv.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||
rv.setAdapter(similarStreamsAdapter);
|
||||
similarStreamsAdapter.setOnItemSelectedListener(new InfoListAdapter.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void selected(String url) {
|
||||
openStreamUrl(url);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
@ -41,13 +42,13 @@ import us.shandian.giga.ui.fragment.MissionsFragment;
|
||||
import us.shandian.giga.util.CrashHandler;
|
||||
import us.shandian.giga.util.Utility;
|
||||
|
||||
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{
|
||||
public class DownloadActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{
|
||||
|
||||
public static final String INTENT_DOWNLOAD = "us.shandian.giga.intent.DOWNLOAD";
|
||||
|
||||
public static final String INTENT_LIST = "us.shandian.giga.intent.LIST";
|
||||
|
||||
private static final String TAG = MainActivity.class.toString();
|
||||
private static final String TAG = DownloadActivity.class.toString();
|
||||
public static final String THREADS = "threads";
|
||||
|
||||
|
||||
@ -150,6 +151,8 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte
|
||||
final TextView tCount = Utility.findViewById(v, R.id.threads_count);
|
||||
final SeekBar threads = Utility.findViewById(v, R.id.threads);
|
||||
final Toolbar toolbar = Utility.findViewById(v, R.id.toolbar);
|
||||
final RadioButton audioButton = (RadioButton) Utility.findViewById(v, R.id.audio_button);
|
||||
|
||||
|
||||
threads.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
|
||||
@ -204,12 +207,16 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte
|
||||
File f = new File(mManager.getLocation() + "/" + fName);
|
||||
|
||||
if (f.exists()) {
|
||||
Toast.makeText(MainActivity.this, R.string.msg_exists, Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(DownloadActivity.this, R.string.msg_exists, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
|
||||
while (mBinder == null);
|
||||
|
||||
int res = mManager.startMission(getIntent().getData().toString(), fName, threads.getProgress() + 1);
|
||||
int res = mManager.startMission(
|
||||
getIntent().getData().toString(),
|
||||
fName,
|
||||
audioButton.isChecked(),
|
||||
threads.getProgress() + 1);
|
||||
mBinder.onMissionAdded(mManager.getMission(res));
|
||||
mFragment.notifyChange();
|
||||
|
||||
@ -258,7 +265,7 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte
|
||||
return true;
|
||||
}
|
||||
case R.id.action_report_error: {
|
||||
ErrorActivity.reportError(MainActivity.this, new Vector<Throwable>(),
|
||||
ErrorActivity.reportError(DownloadActivity.this, new Vector<Throwable>(),
|
||||
null, null,
|
||||
ErrorActivity.ErrorInfo.make(ErrorActivity.USER_REPORT,
|
||||
null,
|
@ -19,8 +19,8 @@ import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
@ -175,13 +175,15 @@ public class DownloadDialog extends DialogFragment {
|
||||
protected void checkDownloadOptions(){
|
||||
View view = getView();
|
||||
Bundle arguments = getArguments();
|
||||
CheckBox audio = (CheckBox) view.findViewById(R.id.audio);
|
||||
CheckBox video = (CheckBox) view.findViewById(R.id.video);
|
||||
RadioButton audioButton = (RadioButton) view.findViewById(R.id.audio_button);
|
||||
RadioButton videoButton = (RadioButton) view.findViewById(R.id.video_button);
|
||||
|
||||
if(arguments.getString(AUDIO_URL) == null) {
|
||||
audio.setVisibility(View.GONE);
|
||||
audioButton.setVisibility(View.GONE);
|
||||
videoButton.setChecked(true);
|
||||
} else if(arguments.getString(VIDEO_URL) == null) {
|
||||
video.setVisibility(View.GONE);
|
||||
videoButton.setVisibility(View.GONE);
|
||||
audioButton.setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,26 +213,28 @@ public class DownloadDialog extends DialogFragment {
|
||||
Bundle arguments = getArguments();
|
||||
final EditText name = (EditText) view.findViewById(R.id.file_name);
|
||||
final SeekBar threads = (SeekBar) view.findViewById(R.id.threads);
|
||||
CheckBox audio = (CheckBox) view.findViewById(R.id.audio);
|
||||
CheckBox video = (CheckBox) view.findViewById(R.id.video);
|
||||
RadioButton audioButton = (RadioButton) view.findViewById(R.id.audio_button);
|
||||
RadioButton videoButton = (RadioButton) view.findViewById(R.id.video_button);
|
||||
|
||||
String fName = name.getText().toString().trim();
|
||||
|
||||
// todo: add timeout? would be bad if the thread gets locked dueto this.
|
||||
while (mBinder == null);
|
||||
|
||||
if(audio.isChecked()){
|
||||
if(audioButton.isChecked()){
|
||||
int res = mManager.startMission(
|
||||
arguments.getString(AUDIO_URL),
|
||||
fName + arguments.getString(FILE_SUFFIX_AUDIO),
|
||||
audioButton.isChecked(),
|
||||
threads.getProgress() + 1);
|
||||
mBinder.onMissionAdded(mManager.getMission(res));
|
||||
}
|
||||
|
||||
if(video.isChecked()){
|
||||
if(videoButton.isChecked()){
|
||||
int res = mManager.startMission(
|
||||
arguments.getString(VIDEO_URL),
|
||||
fName + arguments.getString(FILE_SUFFIX_VIDEO),
|
||||
audioButton.isChecked(),
|
||||
threads.getProgress() + 1);
|
||||
mBinder.onMissionAdded(mManager.getMission(res));
|
||||
}
|
||||
@ -253,8 +257,8 @@ public class DownloadDialog extends DialogFragment {
|
||||
//we'll see later
|
||||
FileDownloader.downloadFile(getContext(), url, saveFilePath, title);
|
||||
} else {
|
||||
Intent intent = new Intent(getContext(), MainActivity.class);
|
||||
intent.setAction(MainActivity.INTENT_DOWNLOAD);
|
||||
Intent intent = new Intent(getContext(), DownloadActivity.class);
|
||||
intent.setAction(DownloadActivity.INTENT_DOWNLOAD);
|
||||
intent.setData(Uri.parse(url));
|
||||
intent.putExtra("fileName", createFileName(title) + fileSuffix);
|
||||
startActivity(intent);
|
||||
|
@ -1,7 +1,5 @@
|
||||
package org.schabi.newpipe.extractor;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
/**
|
||||
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
||||
* AbstractVideoInfo.java is part of NewPipe.
|
||||
@ -37,7 +35,6 @@ public abstract class AbstractVideoInfo {
|
||||
public String title = "";
|
||||
public String uploader = "";
|
||||
public String thumbnail_url = "";
|
||||
public Bitmap thumbnail;
|
||||
public String webpage_url = "";
|
||||
public String upload_date = "";
|
||||
public long view_count = -1;
|
||||
|
@ -1,7 +1,5 @@
|
||||
package org.schabi.newpipe.extractor;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package org.schabi.newpipe.extractor;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.HashMap;
|
||||
|
@ -1,7 +1,5 @@
|
||||
package org.schabi.newpipe.extractor;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.schabi.newpipe.extractor.services.youtube.YoutubeService;
|
||||
|
||||
/**
|
||||
|
@ -44,7 +44,6 @@ public class StreamInfo extends AbstractVideoInfo {
|
||||
this.title = avi.title;
|
||||
this.uploader = avi.uploader;
|
||||
this.thumbnail_url = avi.thumbnail_url;
|
||||
this.thumbnail = avi.thumbnail;
|
||||
this.webpage_url = avi.webpage_url;
|
||||
this.upload_date = avi.upload_date;
|
||||
this.upload_date = avi.upload_date;
|
||||
|
@ -19,8 +19,6 @@ import org.schabi.newpipe.extractor.UrlIdHandler;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 25.07.16.
|
||||
|
@ -1,17 +1,12 @@
|
||||
package org.schabi.newpipe.extractor.services.youtube;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.schabi.newpipe.extractor.AbstractVideoInfo;
|
||||
import org.schabi.newpipe.extractor.Downloader;
|
||||
import org.schabi.newpipe.extractor.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.Parser;
|
||||
import org.schabi.newpipe.extractor.ParsingException;
|
||||
import org.schabi.newpipe.extractor.SearchEngine;
|
||||
import org.schabi.newpipe.extractor.StreamPreviewInfoCollector;
|
||||
import org.schabi.newpipe.extractor.StreamPreviewInfoExtractor;
|
||||
import org.schabi.newpipe.extractor.StreamPreviewInfoSearchCollector;
|
||||
import org.schabi.newpipe.extractor.UrlIdHandler;
|
||||
|
@ -0,0 +1,174 @@
|
||||
package org.schabi.newpipe.info_list;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
|
||||
import org.schabi.newpipe.ImageErrorLoadingListener;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.AbstractVideoInfo;
|
||||
import org.schabi.newpipe.extractor.StreamPreviewInfo;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 26.09.16.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
||||
* InfoItemBuilder.java is part of NewPipe.
|
||||
*
|
||||
* NewPipe is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* NewPipe is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class InfoItemBuilder {
|
||||
|
||||
public interface OnItemSelectedListener {
|
||||
void selected(String url);
|
||||
}
|
||||
|
||||
private Activity activity = null;
|
||||
private View rootView = null;
|
||||
private ImageLoader imageLoader = ImageLoader.getInstance();
|
||||
private DisplayImageOptions displayImageOptions =
|
||||
new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
||||
private OnItemSelectedListener onItemSelectedListener;
|
||||
|
||||
public InfoItemBuilder(Activity a, View rootView) {
|
||||
activity = a;
|
||||
this.rootView = rootView;
|
||||
}
|
||||
|
||||
public void setOnItemSelectedListener(OnItemSelectedListener onItemSelectedListener) {
|
||||
this.onItemSelectedListener = onItemSelectedListener;
|
||||
}
|
||||
|
||||
public void buildByHolder(InfoItemHolder holder, final StreamPreviewInfo info) {
|
||||
// fill holder with information
|
||||
holder.itemVideoTitleView.setText(info.title);
|
||||
if(info.uploader != null && !info.uploader.isEmpty()) {
|
||||
holder.itemUploaderView.setText(info.uploader);
|
||||
} else {
|
||||
holder.itemUploaderView.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
if(info.duration > 0) {
|
||||
holder.itemDurationView.setText(getDurationString(info.duration));
|
||||
} else {
|
||||
if(info.stream_type == AbstractVideoInfo.StreamType.LIVE_STREAM) {
|
||||
holder.itemDurationView.setText(R.string.duration_live);
|
||||
} else {
|
||||
holder.itemDurationView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
if(info.view_count >= 0) {
|
||||
holder.itemViewCountView.setText(shortViewCount(info.view_count));
|
||||
} else {
|
||||
holder.itemViewCountView.setVisibility(View.GONE);
|
||||
}
|
||||
if(info.upload_date != null && !info.upload_date.isEmpty()) {
|
||||
holder.itemUploadDateView.setText(info.upload_date + " • ");
|
||||
}
|
||||
|
||||
holder.itemThumbnailView.setImageResource(R.drawable.dummy_thumbnail);
|
||||
if(info.thumbnail_url != null && !info.thumbnail_url.isEmpty()) {
|
||||
imageLoader.displayImage(info.thumbnail_url,
|
||||
holder.itemThumbnailView,
|
||||
displayImageOptions,
|
||||
new ImageErrorLoadingListener(activity, rootView, info.service_id));
|
||||
}
|
||||
|
||||
holder.itemButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
onItemSelectedListener.selected(info.webpage_url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public View buildView(ViewGroup parent, final StreamPreviewInfo info) {
|
||||
View streamPreviewView = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.video_item, parent, false);
|
||||
InfoItemHolder holder = new InfoItemHolder(streamPreviewView);
|
||||
buildByHolder(holder, info);
|
||||
return streamPreviewView;
|
||||
}
|
||||
|
||||
|
||||
public static String shortViewCount(Long viewCount){
|
||||
if(viewCount >= 1000000000){
|
||||
return Long.toString(viewCount/1000000000)+"B views";
|
||||
}else if(viewCount>=1000000){
|
||||
return Long.toString(viewCount/1000000)+"M views";
|
||||
}else if(viewCount>=1000){
|
||||
return Long.toString(viewCount/1000)+"K views";
|
||||
}else {
|
||||
return Long.toString(viewCount)+" views";
|
||||
}
|
||||
}
|
||||
|
||||
public static String getDurationString(int duration) {
|
||||
String output = "";
|
||||
int days = duration / (24 * 60 * 60); /* greater than a day */
|
||||
duration %= (24 * 60 * 60);
|
||||
int hours = duration / (60 * 60); /* greater than an hour */
|
||||
duration %= (60 * 60);
|
||||
int minutes = duration / 60;
|
||||
int seconds = duration % 60;
|
||||
|
||||
//handle days
|
||||
if(days > 0) {
|
||||
output = Integer.toString(days) + ":";
|
||||
}
|
||||
// handle hours
|
||||
if(hours > 0 || !output.isEmpty()) {
|
||||
if(hours > 0) {
|
||||
if(hours >= 10 || output.isEmpty()) {
|
||||
output += Integer.toString(hours);
|
||||
} else {
|
||||
output += "0" + Integer.toString(hours);
|
||||
}
|
||||
} else {
|
||||
output += "00";
|
||||
}
|
||||
output += ":";
|
||||
}
|
||||
//handle minutes
|
||||
if(minutes > 0 || !output.isEmpty()) {
|
||||
if(minutes > 0) {
|
||||
if(minutes >= 10 || output.isEmpty()) {
|
||||
output += Integer.toString(minutes);
|
||||
} else {
|
||||
output += "0" + Integer.toString(minutes);
|
||||
}
|
||||
} else {
|
||||
output += "00";
|
||||
}
|
||||
output += ":";
|
||||
}
|
||||
|
||||
//handle seconds
|
||||
if(output.isEmpty()) {
|
||||
output += "0:";
|
||||
}
|
||||
|
||||
if(seconds >= 10) {
|
||||
output += Integer.toString(seconds);
|
||||
} else {
|
||||
output += "0" + Integer.toString(seconds);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
@ -39,27 +39,16 @@ import java.util.Vector;
|
||||
|
||||
public class InfoListAdapter extends RecyclerView.Adapter<InfoItemHolder> {
|
||||
|
||||
public interface OnItemSelectedListener {
|
||||
void selected(String url);
|
||||
}
|
||||
|
||||
private Activity activity = null;
|
||||
private View rootView = null;
|
||||
private List<StreamPreviewInfo> streamList = new Vector<>();
|
||||
private ImageLoader imageLoader = ImageLoader.getInstance();
|
||||
private DisplayImageOptions displayImageOptions =
|
||||
new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
||||
private OnItemSelectedListener onItemSelectedListener;
|
||||
|
||||
|
||||
InfoItemBuilder infoItemBuilder = null;
|
||||
List<StreamPreviewInfo> streamList = new Vector<>();
|
||||
|
||||
public InfoListAdapter(Activity a, View rootView) {
|
||||
activity = a;
|
||||
this.rootView = rootView;
|
||||
infoItemBuilder = new InfoItemBuilder(a, rootView);
|
||||
}
|
||||
|
||||
public void setOnItemSelectedListener(OnItemSelectedListener onItemSelectedListener) {
|
||||
this.onItemSelectedListener = onItemSelectedListener;
|
||||
public void setOnItemSelectedListener
|
||||
(InfoItemBuilder.OnItemSelectedListener onItemSelectedListener) {
|
||||
infoItemBuilder.setOnItemSelectedListener(onItemSelectedListener);
|
||||
}
|
||||
|
||||
public void addStreamItemList(List<StreamPreviewInfo> videos) {
|
||||
@ -89,112 +78,6 @@ public class InfoListAdapter extends RecyclerView.Adapter<InfoItemHolder> {
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(InfoItemHolder holder, int i) {
|
||||
final StreamPreviewInfo info = streamList.get(i);
|
||||
// fill holder with information
|
||||
holder.itemVideoTitleView.setText(info.title);
|
||||
if(info.uploader != null && !info.uploader.isEmpty()) {
|
||||
holder.itemUploaderView.setText(info.uploader);
|
||||
} else {
|
||||
holder.itemUploaderView.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
if(info.duration > 0) {
|
||||
holder.itemDurationView.setText(getDurationString(info.duration));
|
||||
} else {
|
||||
if(info.stream_type == AbstractVideoInfo.StreamType.LIVE_STREAM) {
|
||||
holder.itemDurationView.setText(R.string.duration_live);
|
||||
} else {
|
||||
holder.itemDurationView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
if(info.view_count >= 0) {
|
||||
holder.itemViewCountView.setText(shortViewCount(info.view_count));
|
||||
} else {
|
||||
holder.itemViewCountView.setVisibility(View.GONE);
|
||||
}
|
||||
if(info.upload_date != null && !info.upload_date.isEmpty()) {
|
||||
holder.itemUploadDateView.setText(info.upload_date + " • ");
|
||||
}
|
||||
|
||||
holder.itemThumbnailView.setImageResource(R.drawable.dummy_thumbnail);
|
||||
if(info.thumbnail_url != null && !info.thumbnail_url.isEmpty()) {
|
||||
imageLoader.displayImage(info.thumbnail_url,
|
||||
holder.itemThumbnailView,
|
||||
displayImageOptions,
|
||||
new ImageErrorLoadingListener(activity, rootView, info.service_id));
|
||||
}
|
||||
|
||||
holder.itemButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
onItemSelectedListener.selected(info.webpage_url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static String shortViewCount(Long viewCount){
|
||||
if(viewCount >= 1000000000){
|
||||
return Long.toString(viewCount/1000000000)+"B views";
|
||||
}else if(viewCount>=1000000){
|
||||
return Long.toString(viewCount/1000000)+"M views";
|
||||
}else if(viewCount>=1000){
|
||||
return Long.toString(viewCount/1000)+"K views";
|
||||
}else {
|
||||
return Long.toString(viewCount)+" views";
|
||||
}
|
||||
}
|
||||
|
||||
public static String getDurationString(int duration) {
|
||||
String output = "";
|
||||
int days = duration / (24 * 60 * 60); /* greater than a day */
|
||||
duration %= (24 * 60 * 60);
|
||||
int hours = duration / (60 * 60); /* greater than an hour */
|
||||
duration %= (60 * 60);
|
||||
int minutes = duration / 60;
|
||||
int seconds = duration % 60;
|
||||
|
||||
//handle days
|
||||
if(days > 0) {
|
||||
output = Integer.toString(days) + ":";
|
||||
}
|
||||
// handle hours
|
||||
if(hours > 0 || !output.isEmpty()) {
|
||||
if(hours > 0) {
|
||||
if(hours >= 10 || output.isEmpty()) {
|
||||
output += Integer.toString(hours);
|
||||
} else {
|
||||
output += "0" + Integer.toString(hours);
|
||||
}
|
||||
} else {
|
||||
output += "00";
|
||||
}
|
||||
output += ":";
|
||||
}
|
||||
//handle minutes
|
||||
if(minutes > 0 || !output.isEmpty()) {
|
||||
if(minutes > 0) {
|
||||
if(minutes >= 10 || output.isEmpty()) {
|
||||
output += Integer.toString(minutes);
|
||||
} else {
|
||||
output += "0" + Integer.toString(minutes);
|
||||
}
|
||||
} else {
|
||||
output += "00";
|
||||
}
|
||||
output += ":";
|
||||
}
|
||||
|
||||
//handle seconds
|
||||
if(output.isEmpty()) {
|
||||
output += "0:";
|
||||
}
|
||||
|
||||
if(seconds >= 10) {
|
||||
output += Integer.toString(seconds);
|
||||
} else {
|
||||
output += "0" + Integer.toString(seconds);
|
||||
}
|
||||
|
||||
return output;
|
||||
infoItemBuilder.buildByHolder(holder, streamList.get(i));
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.detail.VideoItemDetailActivity;
|
||||
@ -189,7 +190,7 @@ public class SearchInfoItemFragment extends Fragment {
|
||||
|
||||
infoListAdapter = new InfoListAdapter(getActivity(),
|
||||
getActivity().findViewById(android.R.id.content));
|
||||
infoListAdapter.setOnItemSelectedListener(new InfoListAdapter.OnItemSelectedListener() {
|
||||
infoListAdapter.setOnItemSelectedListener(new InfoItemBuilder.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void selected(String url) {
|
||||
Intent i = new Intent(getActivity(), VideoItemDetailActivity.class);
|
||||
|
@ -89,14 +89,6 @@ public class NewPipeSettings {
|
||||
return downloadPath;
|
||||
}
|
||||
|
||||
public static String getDownloadPath(Context context, String fileName)
|
||||
{
|
||||
if(Utility.isVideoFile(fileName)) {
|
||||
return NewPipeSettings.getVideoDownloadPath(context);
|
||||
}
|
||||
return NewPipeSettings.getAudioDownloadPath(context);
|
||||
}
|
||||
|
||||
private static File getFolder(Context context, int keyID, String defaultDirectoryName) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
final String key = context.getString(keyID);
|
||||
|
@ -4,7 +4,7 @@ public interface DownloadManager
|
||||
{
|
||||
int BLOCK_SIZE = 512 * 1024;
|
||||
|
||||
int startMission(String url, String name, int threads);
|
||||
int startMission(String url, String name, boolean isAudio, int threads);
|
||||
void resumeMission(int id);
|
||||
void pauseMission(int id);
|
||||
void deleteMission(int id);
|
||||
|
@ -31,11 +31,15 @@ public class DownloadManagerImpl implements DownloadManager
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startMission(String url, String name, int threads) {
|
||||
public int startMission(String url, String name, boolean isAudio, int threads) {
|
||||
DownloadMission mission = new DownloadMission();
|
||||
mission.url = url;
|
||||
mission.name = name;
|
||||
mission.location = NewPipeSettings.getDownloadPath(mContext, name);
|
||||
if(isAudio) {
|
||||
mission.location = NewPipeSettings.getAudioDownloadPath(mContext);
|
||||
} else {
|
||||
mission.location = NewPipeSettings.getVideoDownloadPath(mContext);
|
||||
}
|
||||
mission.timestamp = System.currentTimeMillis();
|
||||
mission.threadCount = threads;
|
||||
new Initializer(mContext, mission).start();
|
||||
|
@ -14,12 +14,12 @@ import android.os.Message;
|
||||
import android.support.v4.app.NotificationCompat.Builder;
|
||||
import android.util.Log;
|
||||
|
||||
import org.schabi.newpipe.download.DownloadActivity;
|
||||
import org.schabi.newpipe.settings.NewPipeSettings;
|
||||
import org.schabi.newpipe.R;
|
||||
import us.shandian.giga.get.DownloadManager;
|
||||
import us.shandian.giga.get.DownloadManagerImpl;
|
||||
import us.shandian.giga.get.DownloadMission;
|
||||
import org.schabi.newpipe.download.MainActivity;
|
||||
import static org.schabi.newpipe.BuildConfig.DEBUG;
|
||||
|
||||
public class DownloadManagerService extends Service implements DownloadMission.MissionListener
|
||||
@ -53,7 +53,7 @@ public class DownloadManagerService extends Service implements DownloadMission.M
|
||||
|
||||
Intent i = new Intent();
|
||||
i.setAction(Intent.ACTION_MAIN);
|
||||
i.setClass(this, MainActivity.class);
|
||||
i.setClass(this, DownloadActivity.class);
|
||||
|
||||
Drawable icon = this.getResources().getDrawable(R.mipmap.ic_launcher);
|
||||
|
||||
@ -68,8 +68,8 @@ public class DownloadManagerService extends Service implements DownloadMission.M
|
||||
PendingIntent.getActivity(
|
||||
this,
|
||||
0,
|
||||
new Intent(this, MainActivity.class)
|
||||
.setAction(MainActivity.INTENT_LIST),
|
||||
new Intent(this, DownloadActivity.class)
|
||||
.setAction(DownloadActivity.INTENT_LIST),
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
);
|
||||
|
||||
|
@ -27,13 +27,8 @@ public class Utility
|
||||
{
|
||||
|
||||
public static enum FileType {
|
||||
APP,
|
||||
VIDEO,
|
||||
EXCEL,
|
||||
WORD,
|
||||
POWERPOINT,
|
||||
MUSIC,
|
||||
ARCHIVE,
|
||||
UNKNOWN
|
||||
}
|
||||
|
||||
@ -142,22 +137,11 @@ public class Utility
|
||||
}
|
||||
|
||||
public static FileType getFileType(String file) {
|
||||
if (file.endsWith(".apk")) {
|
||||
return FileType.APP;
|
||||
} else if (file.endsWith(".mp3") || file.endsWith(".wav") || file.endsWith(".flac") || file.endsWith(".m4a")) {
|
||||
if (file.endsWith(".mp3") || file.endsWith(".wav") || file.endsWith(".flac") || file.endsWith(".m4a")) {
|
||||
return FileType.MUSIC;
|
||||
} else if (file.endsWith(".mp4") || file.endsWith(".mpeg") || file.endsWith(".rm") || file.endsWith(".rmvb")
|
||||
|| file.endsWith(".flv") || file.endsWith(".webp") || file.endsWith(".webm")) {
|
||||
return FileType.VIDEO;
|
||||
} else if (file.endsWith(".doc") || file.endsWith(".docx")) {
|
||||
return FileType.WORD;
|
||||
} else if (file.endsWith(".xls") || file.endsWith(".xlsx")) {
|
||||
return FileType.EXCEL;
|
||||
} else if (file.endsWith(".ppt") || file.endsWith(".pptx")) {
|
||||
return FileType.POWERPOINT;
|
||||
} else if (file.endsWith(".zip") || file.endsWith(".rar") || file.endsWith(".7z") || file.endsWith(".gz")
|
||||
|| file.endsWith("tar") || file.endsWith(".bz")) {
|
||||
return FileType.ARCHIVE;
|
||||
} else {
|
||||
return FileType.UNKNOWN;
|
||||
}
|
||||
|
@ -265,12 +265,13 @@
|
||||
android:text="@string/similar_videos_btn_text"
|
||||
android:layout_below="@id/detail_next_stream_content"
|
||||
android:textAllCaps="true" />
|
||||
<android.support.v7.widget.RecyclerView
|
||||
<LinearLayout
|
||||
android:id="@+id/similar_streams_view"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/detail_similar_title"/>
|
||||
android:layout_below="@id/detail_similar_title">
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
@ -58,15 +58,21 @@
|
||||
android:layout_marginBottom="24dp"
|
||||
android:gravity="left"
|
||||
android:orientation="horizontal">
|
||||
<CheckBox android:id="@+id/video"
|
||||
<RadioGroup
|
||||
android:id="@+id/video_audio_group"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
<RadioButton android:id="@+id/video_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/video"
|
||||
android:checked="true"/>
|
||||
<CheckBox android:id="@+id/audio"
|
||||
<RadioButton android:id="@+id/audio_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/audio" />
|
||||
</RadioGroup>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
@ -267,12 +267,13 @@
|
||||
android:text="@string/similar_videos_btn_text"
|
||||
android:layout_below="@id/detail_next_stream_content"
|
||||
android:textAllCaps="true" />
|
||||
<android.support.v7.widget.RecyclerView
|
||||
<LinearLayout
|
||||
android:id="@+id/similar_streams_view"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/detail_similar_title"/>
|
||||
android:layout_below="@id/detail_similar_title">
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
Loading…
Reference in New Issue
Block a user