diff --git a/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java b/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java index fcad0b612..fde006a60 100644 --- a/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java +++ b/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java @@ -14,6 +14,7 @@ import org.schabi.newpipe.local.dialog.PlaylistDialog; import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueueItem; import org.schabi.newpipe.util.NavigationHelper; +import org.schabi.newpipe.util.SaveUploaderUrlHelper; import java.util.Collections; @@ -61,11 +62,13 @@ public final class QueueItemMenuUtil { return true; case R.id.menu_item_channel_details: - // An intent must be used here. - // Opening with FragmentManager transactions is not working, - // as PlayQueueActivity doesn't use fragments. - NavigationHelper.openChannelFragmentUsingIntent(context, item.getServiceId(), - item.getUploaderUrl(), item.getUploader()); + SaveUploaderUrlHelper.saveUploaderUrlIfNeeded(context, item, + // An intent must be used here. + // Opening with FragmentManager transactions is not working, + // as PlayQueueActivity doesn't use fragments. + uploaderUrl -> NavigationHelper.openChannelFragmentUsingIntent( + context, item.getServiceId(), uploaderUrl, item.getUploader() + )); return true; case R.id.menu_item_share: shareText(context, item.getTitle(), item.getUrl(), diff --git a/app/src/main/java/org/schabi/newpipe/util/SaveUploaderUrlHelper.java b/app/src/main/java/org/schabi/newpipe/util/SaveUploaderUrlHelper.java new file mode 100644 index 000000000..3c7b1ce91 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/util/SaveUploaderUrlHelper.java @@ -0,0 +1,94 @@ +package org.schabi.newpipe.util; + +import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; + +import android.content.Context; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import org.schabi.newpipe.NewPipeDatabase; +import org.schabi.newpipe.R; +import org.schabi.newpipe.error.ErrorInfo; +import org.schabi.newpipe.error.ErrorUtil; +import org.schabi.newpipe.error.UserAction; +import org.schabi.newpipe.extractor.stream.StreamInfoItem; +import org.schabi.newpipe.player.playqueue.PlayQueueItem; + +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.schedulers.Schedulers; + +/** + * Utility class for putting the uploader url into the database - when required. + */ +public final class SaveUploaderUrlHelper { + private SaveUploaderUrlHelper() { + } + + // Public functions which call the function that does + // the actual work with the correct parameters + public static void saveUploaderUrlIfNeeded(@NonNull final Fragment fragment, + @NonNull final StreamInfoItem infoItem, + @NonNull final SaveUploaderUrlCallback callback) { + saveUploaderUrlIfNeeded(fragment.requireContext(), + infoItem.getServiceId(), + infoItem.getUrl(), + infoItem.getUploaderUrl(), + callback); + } + public static void saveUploaderUrlIfNeeded(@NonNull final Context context, + @NonNull final PlayQueueItem queueItem, + @NonNull final SaveUploaderUrlCallback callback) { + saveUploaderUrlIfNeeded(context, + queueItem.getServiceId(), + queueItem.getUrl(), + queueItem.getUploaderUrl(), + callback); + } + + /** + * Fetches and saves the uploaderUrl if it is empty (meaning that it does + * not exist in the video item). The callback is called with either the + * fetched uploaderUrl, or the already saved uploaderUrl, but it is always + * called with a valid uploaderUrl that can be used to show channel details. + * + * @param context Context + * @param serviceId The serviceId of the item + * @param url The item url + * @param uploaderUrl The uploaderUrl of the item, if null or empty, it + * will be fetched using the item url. + * @param callback The callback that returns the fetched or existing + * uploaderUrl + */ + private static void saveUploaderUrlIfNeeded(@NonNull final Context context, + final int serviceId, + @NonNull final String url, + // Only used if not null or empty + @Nullable final String uploaderUrl, + @NonNull final SaveUploaderUrlCallback callback) { + if (isNullOrEmpty(uploaderUrl)) { + Toast.makeText(context, R.string.loading_channel_details, + Toast.LENGTH_SHORT).show(); + ExtractorHelper.getStreamInfo(serviceId, url, false) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(result -> { + NewPipeDatabase.getInstance(context).streamDAO() + .setUploaderUrl(serviceId, url, result.getUploaderUrl()) + .subscribeOn(Schedulers.io()).subscribe(); + callback.onCallback(result.getUploaderUrl()); + }, throwable -> ErrorUtil.createNotification(context, + new ErrorInfo(throwable, UserAction.REQUESTED_CHANNEL, + "Could not load channel details") + )); + } else { + callback.onCallback(uploaderUrl); + } + } + + public interface SaveUploaderUrlCallback { + void onCallback(@NonNull String uploaderUrl); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/util/StreamDialogEntry.java b/app/src/main/java/org/schabi/newpipe/util/StreamDialogEntry.java index bb1cbbeae..1b4c8046c 100644 --- a/app/src/main/java/org/schabi/newpipe/util/StreamDialogEntry.java +++ b/app/src/main/java/org/schabi/newpipe/util/StreamDialogEntry.java @@ -3,12 +3,10 @@ package org.schabi.newpipe.util; import android.content.Context; import android.net.Uri; import android.util.Log; -import android.widget.Toast; import androidx.fragment.app.Fragment; import androidx.preference.PreferenceManager; -import org.schabi.newpipe.NewPipeDatabase; import org.schabi.newpipe.R; import org.schabi.newpipe.database.stream.model.StreamEntity; import org.schabi.newpipe.extractor.stream.StreamInfoItem; @@ -27,36 +25,14 @@ import java.util.function.Consumer; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.schedulers.Schedulers; -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(); - 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 -> { - NewPipeDatabase.getInstance(fragment.requireContext()).streamDAO() - .setUploaderUrl(serviceId, url, result.getUploaderUrl()) - .subscribeOn(Schedulers.io()).subscribe(); - openChannelFragment(fragment, item, result.getUploaderUrl()); - }, throwable -> Toast.makeText( - // TODO: Open the Error Activity - fragment.getContext(), - R.string.error_show_channel_details, - Toast.LENGTH_SHORT - ).show()); - } else { - openChannelFragment(fragment, item, item.getUploaderUrl()); - } + SaveUploaderUrlHelper.saveUploaderUrlIfNeeded(fragment, item, + uploaderUrl -> openChannelFragment(fragment, item, uploaderUrl)); }), /**