NewPipe/app/src/main/java/org/schabi/newpipe/util/StreamDialogEntry.java

263 lines
10 KiB
Java
Raw Normal View History

package org.schabi.newpipe.util;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import android.widget.Toast;
2019-10-04 12:59:08 +00:00
import androidx.fragment.app.Fragment;
import androidx.preference.PreferenceManager;
import org.schabi.newpipe.NewPipeDatabase;
import org.schabi.newpipe.R;
2021-10-09 16:46:20 +00:00
import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
2021-10-09 16:46:20 +00:00
import org.schabi.newpipe.local.dialog.PlaylistDialog;
2021-07-27 02:51:41 +00:00
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import org.schabi.newpipe.util.external_communication.KoreUtils;
import org.schabi.newpipe.util.external_communication.ShareUtils;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
2021-07-27 02:51:41 +00:00
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.schedulers.Schedulers;
2021-07-27 02:51:41 +00:00
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
public enum StreamDialogEntry {
//////////////////////////////////////
// enum values with DEFAULT actions //
//////////////////////////////////////
show_channel_details(R.string.show_channel_details, (fragment, item) -> {
if (isNullOrEmpty(item.getUploaderUrl())) {
final int serviceId = item.getServiceId();
final String url = item.getUrl();
2021-08-21 01:30:40 +00:00
Toast.makeText(fragment.getContext(), R.string.loading_channel_details,
Toast.LENGTH_SHORT).show();
ExtractorHelper.getStreamInfo(serviceId, url, false)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
Add play next to long press menu & refactor enqueue methods (#6872) * added mvp play next button in long press menu; new intent handling, new long press dialog entry, new dialog functions, new strings * changed line length for checkstyle pass * cleaned comments, moved strings * Update app/src/main/res/values/strings.xml to make long press entry more descriptive Co-authored-by: opusforlife2 <53176348+opusforlife2@users.noreply.github.com> * Update app/src/main/res/values/strings.xml Co-authored-by: Stypox <stypox@pm.me> * replace redundant nextOnVideoPlayer methods Co-authored-by: Stypox <stypox@pm.me> * add enqueueNextOnPlayer and enqueueOnPlayer without selectOnAppend and RESUME_PLAYBACK/ deprecate enqueueNextOn*Player and enqueueOn*Player methods add getPlayerIntent, getPlayerEnqueueIntent and getPlayerEnqueueNextIntent without selectOnAppend and RESUME_PLAYBACK/ deprecate those with add section comments * removed deprecated methods removed redundant methods * removed deprecated methods removed redundant methods * replaced APPEND_ONLY, removed SELECT_ON_APPEND / replaced remaining enqueueOn*Player methods * now works with playlists * renamed dialog entry * checking for >1 items in the queue using the PlayerHolder * making enqueue*OnPlayer safe to call when no video is playing (defaulting to audio) * corrected strings * improve getQueueSize in PlayerHolder * long press to enqueue only if queue isnt empty * add Whitespace Co-authored-by: Stypox <stypox@pm.me> * clarify comments / add spaces * PlayerType as parameter of the enqueueOnPlayer method add Helper method * using the helper function everywhere (except for the background and popup long-press actions (also on playlists, history, ...)), so basically nowhere / passing checkstyle * assimilated the enqueue*OnPlayer methods * removed redundant comment, variable * simplify code line Co-authored-by: Stypox <stypox@pm.me> * move if * replace workaround for isPlayerOpen() Co-authored-by: Stypox <stypox@pm.me> * replaced workarounds (getType), corrected static access with getInstance * remove unused imports * changed method call to original, new method doesnt exist yet. * Use getter method instead of property access syntax. * improve conditional for play next entry Co-authored-by: Stypox <stypox@pm.me> * show play next btn in feed fragment Co-authored-by: Stypox <stypox@pm.me> * add play next to local playlist and statistics fragment Co-authored-by: Stypox <stypox@pm.me> * formating Co-authored-by: Stypox <stypox@pm.me> * correcting logic Co-authored-by: Stypox <stypox@pm.me> * remove 2 year old unused string, formating Co-authored-by: Stypox <stypox@pm.me> * correct enqueue (next) conditionals, default to background if no player is open. Dont generally default to background play. * remove player open checks from button long press enqueue actions * improve log msg * Rename next to enqueue_next * Refactor kotlin Co-authored-by: opusforlife2 <53176348+opusforlife2@users.noreply.github.com> Co-authored-by: Stypox <stypox@pm.me>
2021-09-18 09:22:49 +00:00
NewPipeDatabase.getInstance(fragment.requireContext()).streamDAO()
.setUploaderUrl(serviceId, url, result.getUploaderUrl())
.subscribeOn(Schedulers.io()).subscribe();
2021-08-14 09:32:38 +00:00
openChannelFragment(fragment, item, result.getUploaderUrl());
2021-08-24 13:17:08 +00:00
}, throwable -> Toast.makeText(
// TODO: Open the Error Activity
fragment.getContext(),
2021-08-14 07:38:57 +00:00
R.string.error_show_channel_details,
Toast.LENGTH_SHORT
).show());
} else {
2021-08-14 09:32:38 +00:00
openChannelFragment(fragment, item, item.getUploaderUrl());
}
}),
/**
* Enqueues the stream automatically to the current PlayerType.<br>
* <br>
* Info: Add this entry within showStreamDialog.
*/
enqueue(R.string.enqueue_stream, (fragment, item) -> {
fetchItemInfoIfSparse(fragment, item, fullItem ->
NavigationHelper.enqueueOnPlayer(fragment.getContext(), fullItem));
Add play next to long press menu & refactor enqueue methods (#6872) * added mvp play next button in long press menu; new intent handling, new long press dialog entry, new dialog functions, new strings * changed line length for checkstyle pass * cleaned comments, moved strings * Update app/src/main/res/values/strings.xml to make long press entry more descriptive Co-authored-by: opusforlife2 <53176348+opusforlife2@users.noreply.github.com> * Update app/src/main/res/values/strings.xml Co-authored-by: Stypox <stypox@pm.me> * replace redundant nextOnVideoPlayer methods Co-authored-by: Stypox <stypox@pm.me> * add enqueueNextOnPlayer and enqueueOnPlayer without selectOnAppend and RESUME_PLAYBACK/ deprecate enqueueNextOn*Player and enqueueOn*Player methods add getPlayerIntent, getPlayerEnqueueIntent and getPlayerEnqueueNextIntent without selectOnAppend and RESUME_PLAYBACK/ deprecate those with add section comments * removed deprecated methods removed redundant methods * removed deprecated methods removed redundant methods * replaced APPEND_ONLY, removed SELECT_ON_APPEND / replaced remaining enqueueOn*Player methods * now works with playlists * renamed dialog entry * checking for >1 items in the queue using the PlayerHolder * making enqueue*OnPlayer safe to call when no video is playing (defaulting to audio) * corrected strings * improve getQueueSize in PlayerHolder * long press to enqueue only if queue isnt empty * add Whitespace Co-authored-by: Stypox <stypox@pm.me> * clarify comments / add spaces * PlayerType as parameter of the enqueueOnPlayer method add Helper method * using the helper function everywhere (except for the background and popup long-press actions (also on playlists, history, ...)), so basically nowhere / passing checkstyle * assimilated the enqueue*OnPlayer methods * removed redundant comment, variable * simplify code line Co-authored-by: Stypox <stypox@pm.me> * move if * replace workaround for isPlayerOpen() Co-authored-by: Stypox <stypox@pm.me> * replaced workarounds (getType), corrected static access with getInstance * remove unused imports * changed method call to original, new method doesnt exist yet. * Use getter method instead of property access syntax. * improve conditional for play next entry Co-authored-by: Stypox <stypox@pm.me> * show play next btn in feed fragment Co-authored-by: Stypox <stypox@pm.me> * add play next to local playlist and statistics fragment Co-authored-by: Stypox <stypox@pm.me> * formating Co-authored-by: Stypox <stypox@pm.me> * correcting logic Co-authored-by: Stypox <stypox@pm.me> * remove 2 year old unused string, formating Co-authored-by: Stypox <stypox@pm.me> * correct enqueue (next) conditionals, default to background if no player is open. Dont generally default to background play. * remove player open checks from button long press enqueue actions * improve log msg * Rename next to enqueue_next * Refactor kotlin Co-authored-by: opusforlife2 <53176348+opusforlife2@users.noreply.github.com> Co-authored-by: Stypox <stypox@pm.me>
2021-09-18 09:22:49 +00:00
}),
enqueue_next(R.string.enqueue_next_stream, (fragment, item) -> {
fetchItemInfoIfSparse(fragment, item, fullItem ->
NavigationHelper.enqueueNextOnPlayer(fragment.getContext(), fullItem));
}),
start_here_on_background(R.string.start_here_on_background, (fragment, item) -> {
fetchItemInfoIfSparse(fragment, item, fullItem ->
NavigationHelper.playOnBackgroundPlayer(fragment.getContext(), fullItem, true));
}),
start_here_on_popup(R.string.start_here_on_popup, (fragment, item) -> {
fetchItemInfoIfSparse(fragment, item, fullItem ->
NavigationHelper.playOnPopupPlayer(fragment.getContext(), fullItem, true));
}),
set_as_playlist_thumbnail(R.string.set_as_playlist_thumbnail, (fragment, item) -> {
}), // has to be set manually
delete(R.string.delete, (fragment, item) -> {
}), // has to be set manually
append_playlist(R.string.add_to_playlist, (fragment, item) -> {
2021-10-09 16:46:20 +00:00
PlaylistDialog.createCorrespondingDialog(
fragment.getContext(),
Collections.singletonList(new StreamEntity(item)),
dialog -> dialog.show(
fragment.getParentFragmentManager(),
"StreamDialogEntry@"
+ (dialog instanceof PlaylistAppendDialog ? "append" : "create")
+ "_playlist"
)
);
}),
2020-12-30 22:40:21 +00:00
play_with_kodi(R.string.play_with_kodi_title, (fragment, item) -> {
final Uri videoUrl = Uri.parse(item.getUrl());
try {
NavigationHelper.playWithKore(fragment.requireContext(), videoUrl);
} catch (final Exception e) {
Add play next to long press menu & refactor enqueue methods (#6872) * added mvp play next button in long press menu; new intent handling, new long press dialog entry, new dialog functions, new strings * changed line length for checkstyle pass * cleaned comments, moved strings * Update app/src/main/res/values/strings.xml to make long press entry more descriptive Co-authored-by: opusforlife2 <53176348+opusforlife2@users.noreply.github.com> * Update app/src/main/res/values/strings.xml Co-authored-by: Stypox <stypox@pm.me> * replace redundant nextOnVideoPlayer methods Co-authored-by: Stypox <stypox@pm.me> * add enqueueNextOnPlayer and enqueueOnPlayer without selectOnAppend and RESUME_PLAYBACK/ deprecate enqueueNextOn*Player and enqueueOn*Player methods add getPlayerIntent, getPlayerEnqueueIntent and getPlayerEnqueueNextIntent without selectOnAppend and RESUME_PLAYBACK/ deprecate those with add section comments * removed deprecated methods removed redundant methods * removed deprecated methods removed redundant methods * replaced APPEND_ONLY, removed SELECT_ON_APPEND / replaced remaining enqueueOn*Player methods * now works with playlists * renamed dialog entry * checking for >1 items in the queue using the PlayerHolder * making enqueue*OnPlayer safe to call when no video is playing (defaulting to audio) * corrected strings * improve getQueueSize in PlayerHolder * long press to enqueue only if queue isnt empty * add Whitespace Co-authored-by: Stypox <stypox@pm.me> * clarify comments / add spaces * PlayerType as parameter of the enqueueOnPlayer method add Helper method * using the helper function everywhere (except for the background and popup long-press actions (also on playlists, history, ...)), so basically nowhere / passing checkstyle * assimilated the enqueue*OnPlayer methods * removed redundant comment, variable * simplify code line Co-authored-by: Stypox <stypox@pm.me> * move if * replace workaround for isPlayerOpen() Co-authored-by: Stypox <stypox@pm.me> * replaced workarounds (getType), corrected static access with getInstance * remove unused imports * changed method call to original, new method doesnt exist yet. * Use getter method instead of property access syntax. * improve conditional for play next entry Co-authored-by: Stypox <stypox@pm.me> * show play next btn in feed fragment Co-authored-by: Stypox <stypox@pm.me> * add play next to local playlist and statistics fragment Co-authored-by: Stypox <stypox@pm.me> * formating Co-authored-by: Stypox <stypox@pm.me> * correcting logic Co-authored-by: Stypox <stypox@pm.me> * remove 2 year old unused string, formating Co-authored-by: Stypox <stypox@pm.me> * correct enqueue (next) conditionals, default to background if no player is open. Dont generally default to background play. * remove player open checks from button long press enqueue actions * improve log msg * Rename next to enqueue_next * Refactor kotlin Co-authored-by: opusforlife2 <53176348+opusforlife2@users.noreply.github.com> Co-authored-by: Stypox <stypox@pm.me>
2021-09-18 09:22:49 +00:00
KoreUtils.showInstallKoreDialog(fragment.requireActivity());
}
}),
share(R.string.share, (fragment, item) ->
Add play next to long press menu & refactor enqueue methods (#6872) * added mvp play next button in long press menu; new intent handling, new long press dialog entry, new dialog functions, new strings * changed line length for checkstyle pass * cleaned comments, moved strings * Update app/src/main/res/values/strings.xml to make long press entry more descriptive Co-authored-by: opusforlife2 <53176348+opusforlife2@users.noreply.github.com> * Update app/src/main/res/values/strings.xml Co-authored-by: Stypox <stypox@pm.me> * replace redundant nextOnVideoPlayer methods Co-authored-by: Stypox <stypox@pm.me> * add enqueueNextOnPlayer and enqueueOnPlayer without selectOnAppend and RESUME_PLAYBACK/ deprecate enqueueNextOn*Player and enqueueOn*Player methods add getPlayerIntent, getPlayerEnqueueIntent and getPlayerEnqueueNextIntent without selectOnAppend and RESUME_PLAYBACK/ deprecate those with add section comments * removed deprecated methods removed redundant methods * removed deprecated methods removed redundant methods * replaced APPEND_ONLY, removed SELECT_ON_APPEND / replaced remaining enqueueOn*Player methods * now works with playlists * renamed dialog entry * checking for >1 items in the queue using the PlayerHolder * making enqueue*OnPlayer safe to call when no video is playing (defaulting to audio) * corrected strings * improve getQueueSize in PlayerHolder * long press to enqueue only if queue isnt empty * add Whitespace Co-authored-by: Stypox <stypox@pm.me> * clarify comments / add spaces * PlayerType as parameter of the enqueueOnPlayer method add Helper method * using the helper function everywhere (except for the background and popup long-press actions (also on playlists, history, ...)), so basically nowhere / passing checkstyle * assimilated the enqueue*OnPlayer methods * removed redundant comment, variable * simplify code line Co-authored-by: Stypox <stypox@pm.me> * move if * replace workaround for isPlayerOpen() Co-authored-by: Stypox <stypox@pm.me> * replaced workarounds (getType), corrected static access with getInstance * remove unused imports * changed method call to original, new method doesnt exist yet. * Use getter method instead of property access syntax. * improve conditional for play next entry Co-authored-by: Stypox <stypox@pm.me> * show play next btn in feed fragment Co-authored-by: Stypox <stypox@pm.me> * add play next to local playlist and statistics fragment Co-authored-by: Stypox <stypox@pm.me> * formating Co-authored-by: Stypox <stypox@pm.me> * correcting logic Co-authored-by: Stypox <stypox@pm.me> * remove 2 year old unused string, formating Co-authored-by: Stypox <stypox@pm.me> * correct enqueue (next) conditionals, default to background if no player is open. Dont generally default to background play. * remove player open checks from button long press enqueue actions * improve log msg * Rename next to enqueue_next * Refactor kotlin Co-authored-by: opusforlife2 <53176348+opusforlife2@users.noreply.github.com> Co-authored-by: Stypox <stypox@pm.me>
2021-09-18 09:22:49 +00:00
ShareUtils.shareText(fragment.requireContext(), item.getName(), item.getUrl(),
item.getThumbnailUrl())),
open_in_browser(R.string.open_in_browser, (fragment, item) ->
Add play next to long press menu & refactor enqueue methods (#6872) * added mvp play next button in long press menu; new intent handling, new long press dialog entry, new dialog functions, new strings * changed line length for checkstyle pass * cleaned comments, moved strings * Update app/src/main/res/values/strings.xml to make long press entry more descriptive Co-authored-by: opusforlife2 <53176348+opusforlife2@users.noreply.github.com> * Update app/src/main/res/values/strings.xml Co-authored-by: Stypox <stypox@pm.me> * replace redundant nextOnVideoPlayer methods Co-authored-by: Stypox <stypox@pm.me> * add enqueueNextOnPlayer and enqueueOnPlayer without selectOnAppend and RESUME_PLAYBACK/ deprecate enqueueNextOn*Player and enqueueOn*Player methods add getPlayerIntent, getPlayerEnqueueIntent and getPlayerEnqueueNextIntent without selectOnAppend and RESUME_PLAYBACK/ deprecate those with add section comments * removed deprecated methods removed redundant methods * removed deprecated methods removed redundant methods * replaced APPEND_ONLY, removed SELECT_ON_APPEND / replaced remaining enqueueOn*Player methods * now works with playlists * renamed dialog entry * checking for >1 items in the queue using the PlayerHolder * making enqueue*OnPlayer safe to call when no video is playing (defaulting to audio) * corrected strings * improve getQueueSize in PlayerHolder * long press to enqueue only if queue isnt empty * add Whitespace Co-authored-by: Stypox <stypox@pm.me> * clarify comments / add spaces * PlayerType as parameter of the enqueueOnPlayer method add Helper method * using the helper function everywhere (except for the background and popup long-press actions (also on playlists, history, ...)), so basically nowhere / passing checkstyle * assimilated the enqueue*OnPlayer methods * removed redundant comment, variable * simplify code line Co-authored-by: Stypox <stypox@pm.me> * move if * replace workaround for isPlayerOpen() Co-authored-by: Stypox <stypox@pm.me> * replaced workarounds (getType), corrected static access with getInstance * remove unused imports * changed method call to original, new method doesnt exist yet. * Use getter method instead of property access syntax. * improve conditional for play next entry Co-authored-by: Stypox <stypox@pm.me> * show play next btn in feed fragment Co-authored-by: Stypox <stypox@pm.me> * add play next to local playlist and statistics fragment Co-authored-by: Stypox <stypox@pm.me> * formating Co-authored-by: Stypox <stypox@pm.me> * correcting logic Co-authored-by: Stypox <stypox@pm.me> * remove 2 year old unused string, formating Co-authored-by: Stypox <stypox@pm.me> * correct enqueue (next) conditionals, default to background if no player is open. Dont generally default to background play. * remove player open checks from button long press enqueue actions * improve log msg * Rename next to enqueue_next * Refactor kotlin Co-authored-by: opusforlife2 <53176348+opusforlife2@users.noreply.github.com> Co-authored-by: Stypox <stypox@pm.me>
2021-09-18 09:22:49 +00:00
ShareUtils.openUrlInBrowser(fragment.requireContext(), item.getUrl())),
2021-07-27 02:51:41 +00:00
2021-07-27 19:26:51 +00:00
mark_as_watched(R.string.mark_as_watched, (fragment, item) -> {
2021-07-27 02:51:41 +00:00
new HistoryRecordManager(fragment.getContext())
2021-07-27 19:26:51 +00:00
.markAsWatched(item)
2021-07-27 02:51:41 +00:00
.onErrorComplete()
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
});
///////////////
// variables //
///////////////
private static StreamDialogEntry[] enabledEntries;
private final int resource;
private final StreamDialogEntryAction defaultAction;
private StreamDialogEntryAction customAction;
StreamDialogEntry(final int resource, final StreamDialogEntryAction defaultAction) {
this.resource = resource;
this.defaultAction = defaultAction;
this.customAction = null;
}
///////////////////////////////////////////////////////
// non-static methods to initialize and edit entries //
///////////////////////////////////////////////////////
public static void setEnabledEntries(final List<StreamDialogEntry> entries) {
setEnabledEntries(entries.toArray(new StreamDialogEntry[0]));
}
/**
* To be called before using {@link #setCustomAction(StreamDialogEntryAction)}.
*
* @param entries the entries to be enabled
*/
public static void setEnabledEntries(final StreamDialogEntry... entries) {
// cleanup from last time StreamDialogEntry was used
2020-08-16 08:24:58 +00:00
for (final StreamDialogEntry streamDialogEntry : values()) {
streamDialogEntry.customAction = null;
}
enabledEntries = entries;
}
public static String[] getCommands(final Context context) {
2020-08-16 08:24:58 +00:00
final String[] commands = new String[enabledEntries.length];
for (int i = 0; i != enabledEntries.length; ++i) {
commands[i] = context.getResources().getString(enabledEntries[i].resource);
}
return commands;
}
////////////////////////////////////////////////
// static methods that act on enabled entries //
////////////////////////////////////////////////
public static void clickOn(final int which, final Fragment fragment,
final StreamInfoItem infoItem) {
if (enabledEntries[which].customAction == null) {
enabledEntries[which].defaultAction.onClick(fragment, infoItem);
} else {
enabledEntries[which].customAction.onClick(fragment, infoItem);
}
}
/**
* Can be used after {@link #setEnabledEntries(StreamDialogEntry...)} has been called.
*
* @param action the action to be set
*/
public void setCustomAction(final StreamDialogEntryAction action) {
this.customAction = action;
}
public interface StreamDialogEntryAction {
void onClick(Fragment fragment, StreamInfoItem infoItem);
}
2021-08-14 09:32:38 +00:00
public static boolean shouldAddMarkAsWatched(final StreamType streamType,
final Context context) {
final boolean isWatchHistoryEnabled = PreferenceManager
.getDefaultSharedPreferences(context)
.getBoolean(context.getString(R.string.enable_watch_history_key), false);
return streamType != StreamType.AUDIO_LIVE_STREAM
&& streamType != StreamType.LIVE_STREAM
&& isWatchHistoryEnabled;
}
2021-08-14 09:32:38 +00:00
/////////////////////////////////////////////
// private method to open channel fragment //
/////////////////////////////////////////////
private static void openChannelFragment(final Fragment fragment,
final StreamInfoItem item,
final String uploaderUrl) {
// For some reason `getParentFragmentManager()` doesn't work, but this does.
NavigationHelper.openChannelFragment(
fragment.requireActivity().getSupportFragmentManager(),
item.getServiceId(), uploaderUrl, item.getUploaderName());
}
/////////////////////////////////////////////
// helper functions //
/////////////////////////////////////////////
private static void fetchItemInfoIfSparse(final Fragment fragment,
final StreamInfoItem item,
final Consumer<SinglePlayQueue> callback) {
if (!(item.getStreamType() == StreamType.LIVE_STREAM
|| item.getStreamType() == StreamType.AUDIO_LIVE_STREAM)
&& item.getDuration() < 0) {
// Sparse item: fetched by fast fetch
ExtractorHelper.getStreamInfo(
item.getServiceId(),
item.getUrl(),
false
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
final HistoryRecordManager recordManager =
new HistoryRecordManager(fragment.getContext());
recordManager.saveStreamState(result, 0)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError(throwable -> Log.e("StreamDialogEntry",
throwable.toString()))
.subscribe();
callback.accept(new SinglePlayQueue(result));
}, throwable -> Log.e("StreamDialogEntry", throwable.toString()));
} else {
callback.accept(new SinglePlayQueue(item));
}
}
}