Add filtering on the homepage by video category

HumourFragmentKiosk

This code is an Android fragment written in Kotlin, used in the NewPipe application to manage the display of a humor kiosk (a specific content section, like a video category). It inherits from KioskFragment, a base class that manages kiosks in NewPipe.

📌 Code Explanation

1. Dependencies and Imports

The code imports several elements:

  • io.reactivex.rxjava3: Used for asynchronous management with RxJava.

  • org.schabi.newpipe.extractor: Contains classes for extracting videos from services like YouTube.

  • ServiceHelper, Localization, ExtractorHelper, etc.: Provide tools to interact with services and retrieve information.


2. Definition of the HumourFragmentKiosk Class

kotlin
Copy
class HumourFragmentKiosk : KioskFragment() {
  • This class inherits from KioskFragment, which manages content displays in the form of a kiosk.

  • It is specifically dedicated to the humor kiosk.


3. onCreate(): Initialization

kotlin
Copy
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    if (serviceId < 0) {
        updateSelectedDefaultKiosk()
    }
}
  • Calls super.onCreate() to ensure normal fragment initialization.

  • Checks if serviceId is invalid (< 0):

    • If so, it calls updateSelectedDefaultKiosk(), which selects the default kiosk.


4. onResume(): Update When Returning to the Screen

kotlin
Copy
override fun onResume() {
    super.onResume()
    if (serviceId != ServiceHelper.getSelectedServiceId(requireContext())) {
        if (currentWorker != null) {
            currentWorker.dispose()
        }
        updateSelectedDefaultKiosk()
        reloadContent()
    }
}
  • Checks if the selected service has changed (serviceId ≠ current service).

  • If so:

    1. Cancels the current worker (currentWorker.dispose()).

    2. Updates the selected kiosk (updateSelectedDefaultKiosk()).

    3. Reloads the content (reloadContent()).


5. loadResult(): Retrieving Kiosk Data

kotlin
Copy
override fun loadResult(forceReload: Boolean): Single<KioskInfo>? {
    contentCountry = Localization.getPreferredContentCountry(requireContext())
    return ExtractorHelper.getKioskInfo(serviceId, url, forceReload)
}
  • Retrieves videos from the selected kiosk using ExtractorHelper.getKioskInfo().

  • Single<KioskInfo> is an RxJava object, which executes the request asynchronously.

  • contentCountry stores the user's country to adapt the content.


6. startLoading(): Loading the Kiosk

kotlin
Copy
override fun startLoading(forceLoad: Boolean) {
    super.startLoading(forceLoad)

    showListFooter(false)
    infoListAdapter.clearStreamItemList()

    currentInfo = null
    if (currentWorker != null) {
        currentWorker.dispose()
    }
    currentWorker = loadResult(forceLoad)
        ?.subscribeOn(io())
        ?.observeOn(AndroidSchedulers.mainThread())
        ?.subscribe(
            { result: KioskInfo ->
                isLoading.set(false)
                currentInfo = result
                currentNextPage = result.nextPage
                handleResult(result)
            },
            { throwable: Throwable? ->
                showError(
                    ErrorInfo(
                        throwable!!, errorUserAction,
                        "Start loading: $url", serviceId
                    )
                )
            }
        )
}
  • Clears the video list (infoListAdapter.clearStreamItemList()).

  • Cancels the previous loading (currentWorker.dispose()).

  • Loads new videos via loadResult(forceLoad).

  • Uses RxJava:

    • subscribeOn(io()): Executes in the background.

    • observeOn(AndroidSchedulers.mainThread()): Displays the result on the main thread.

    • On success, handleResult(result) processes the retrieved videos.

    • On error, showError() displays a message.


7. updateSelectedDefaultKiosk(): Selecting the Default Kiosk

kotlin
Copy
private fun updateSelectedDefaultKiosk() {
    try {
        serviceId = ServiceHelper.getSelectedServiceId(requireContext())
        val kioskList = NewPipe.getService(serviceId).kioskList
        kioskId = kioskList.defaultKioskId
        url = kioskList.getListLinkHandlerFactoryByType(kioskId).fromId(kioskId).url
        kioskTranslatedName = KioskTranslator.getTranslatedKioskName(kioskId, requireContext())
        name = kioskTranslatedName
        currentInfo = null
        currentNextPage = null
    } catch (e: ExtractionException) {
        showError(
            ErrorInfo(
                e, UserAction.REQUESTED_KIOSK,
                "Loading default kiosk for selected service"
            )
        )
    }
}
  • Retrieves the active service ID (serviceId).

  • Loads the list of kiosks for this service.

  • Defines the default kiosk (kioskId and url).

  • Translates its name (kioskTranslatedName).

  • If an extraction error occurs (ExtractionException), it is caught and reported with showError().


🔍 Summary

  • This Android fragment displays a humor kiosk in NewPipe.

  • Uses RxJava to load videos asynchronously.

  • Dynamically updates the kiosk if the user changes the service.

  • Selects a default kiosk if none is defined.

  • Handles errors to avoid crashes.

It is a good example of modular and reactive implementation in an open-source Android application. 🚀


MusicFragmentKiosk

This code is an Android fragment in Kotlin for the NewPipe application. It defines a specific kiosk: MusicFragmentKiosk, which displays music trends (likely from YouTube).

It is very similar to HumourFragmentKiosk, but with one key difference: it directly loads a specific URL for music trends on YouTube.


📌 Detailed Code Explanation

1️⃣ Imports

kotlin
Copy
import android.os.Bundle
import android.text.TextUtils
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers.io
import org.schabi.newpipe.error.ErrorInfo
import org.schabi.newpipe.error.UserAction
import org.schabi.newpipe.extractor.NewPipe
import org.schabi.newpipe.extractor.exceptions.ExtractionException
import org.schabi.newpipe.extractor.kiosk.KioskInfo
import org.schabi.newpipe.util.ExtractorHelper
import org.schabi.newpipe.util.KioskTranslator
import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.ServiceHelper
  • RxJava 3 (io.reactivex.rxjava3): Allows asynchronous operations (loading videos in the background).

  • NewPipe Extractor (org.schabi.newpipe.extractor): Tool for extracting videos from YouTube.

  • ServiceHelper, KioskTranslator, Localization: Helper classes for managing services, translations, and localization.


2️⃣ Definition of MusicFragmentKiosk

kotlin
Copy
class MusicFragmentKiosk : KioskFragment() {
  • MusicFragmentKiosk inherits from KioskFragment, which manages the display of content kiosks.

  • It is used to display music trends.


3️⃣ onCreate(): Kiosk Initialization

kotlin
Copy
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    if (serviceId < 0) {
        updateSelectedDefaultKiosk()
    }
}
  • Calls super.onCreate() for fragment configuration.

  • Checks if serviceId is invalid (< 0):

    • If so, it loads a default kiosk via updateSelectedDefaultKiosk().


4️⃣ onResume(): Check on Resume

kotlin
Copy
override fun onResume() {
    super.onResume()
    if (serviceId != ServiceHelper.getSelectedServiceId(requireContext())) {
        if (currentWorker != null) {
            currentWorker.dispose()
        }
        updateSelectedDefaultKiosk()
        reloadContent()
    }
}
  • Checks if the selected service has changed (serviceId ≠ active service).

  • If so:

    1. Cancels the current loading (currentWorker.dispose()).

    2. Reloads the default kiosk (updateSelectedDefaultKiosk()).

    3. Reloads the content (reloadContent()).


5️⃣ loadResult(): Loading Music Trends

kotlin
Copy
override fun loadResult(forceReload: Boolean): Single<KioskInfo>? {
    contentCountry = Localization.getPreferredContentCountry(requireContext())
    url = "https://www.youtube.com/feed/trending?bp=4gINGgt5dG1hX2NoYXJ0cw%3D%3D"
    return ExtractorHelper.getKioskInfo(serviceId, "https://www.youtube.com/feed/trending?bp=4gINGgt5dG1hX2NoYXJ0cw%3D%3D", forceReload)
}
  • Sets contentCountry to adapt the content to the user's location.

  • Fixes the URL of the YouTube page containing music trends (/feed/trending?bp=...).

  • Calls ExtractorHelper.getKioskInfo() to retrieve the associated videos.

🟢 Difference with HumourFragmentKiosk:

  • Here, the URL is fixed, whereas in HumourFragmentKiosk, it is determined dynamically.


6️⃣ startLoading(): Starting the Loading

kotlin
Copy
override fun startLoading(forceLoad: Boolean) {
    super.startLoading(forceLoad)
    showListFooter(false)
    infoListAdapter.clearStreamItemList()

    currentInfo = null
    if (currentWorker != null) {
        currentWorker.dispose()
    }
    currentWorker = loadResult(forceLoad)
        ?.subscribeOn(io())
        ?.observeOn(AndroidSchedulers.mainThread())
        ?.subscribe(
            { result: KioskInfo ->
                isLoading.set(false)
                currentNextPage = result.nextPage
                handleResult(result)
            },
            { throwable: Throwable? ->
                showError(
                    ErrorInfo(
                        throwable!!, errorUserAction,
                        "Start loading: $url", serviceId
                    )
                )
            }
        )
}
  • Clears the video list (infoListAdapter.clearStreamItemList()).

  • Cancels an ongoing loading (currentWorker.dispose()).

  • Loads videos with loadResult(forceLoad), executed asynchronously:

    • subscribeOn(io()): Executes in the background.

    • observeOn(AndroidSchedulers.mainThread()): Updates the UI on the main thread.

    • On success: handleResult(result) displays the videos.

    • On error: showError() displays a message.


7️⃣ setInitialData(): Initial Configuration

kotlin
Copy
override fun setInitialData(sid: Int, u: String?, title: String?) {
    serviceId = sid
    url = u
    name = if (!TextUtils.isEmpty(title)) title else ""
}
  • Allows initializing the fragment with:

    • sid: The service ID.

    • u: The kiosk URL.

    • title: The displayed name (empty if null).


8️⃣ updateSelectedDefaultKiosk(): Defining the Default Kiosk

kotlin
Copy
private fun updateSelectedDefaultKiosk() {
    try {
        serviceId = ServiceHelper.getSelectedServiceId(requireContext())
        val kioskList = NewPipe.getService(serviceId).kioskList
        kioskId = kioskList.defaultKioskId
        url = kioskList.getListLinkHandlerFactoryByType(kioskId).fromId(kioskId).url
        kioskTranslatedName = KioskTranslator.getTranslatedKioskName(kioskId, requireContext())
        name = kioskTranslatedName
        currentInfo = null
        currentNextPage = null
    } catch (e: ExtractionException) {
        showError(
            ErrorInfo(
                e, UserAction.REQUESTED_KIOSK,
                "Loading default kiosk for selected service"
            )
        )
    }
}
  • Retrieves the selected service ID (serviceId).

  • Loads the list of kiosks.

  • Selects a default kiosk (kioskId and url).

  • Translates its name (kioskTranslatedName).

  • Resets content variables (currentInfo, currentNextPage).

  • On error (ExtractionException), it is reported with showError().


🔍 Differences with HumourFragmentKiosk

Feature HumourFragmentKiosk MusicFragmentKiosk
Content Type Humor Music
URL Determination Dynamic via NewPipe.getService() Fixed (https://www.youtube.com/feed/trending?bp=...)
setInitialData() ❌ (Absent) ✅ (Present)

💡 Conclusion

  • MusicFragmentKiosk is a specialization of KioskFragment to display music trends.

  • It uses a fixed URL, unlike other kiosks that are dynamic.

  • It works with RxJava to load videos asynchronously.

  • It manages service selection and updates the content accordingly.

In summary, this fragment allows displaying YouTube music trends in NewPipe! 🚀


OutingFragment.java

This code is a Java class OutingsFragment, part of the NewPipe project, an open-source Android application for watching YouTube videos without ads or tracking. This class is a fragment that displays a list of videos related to initial content, and it interacts with an external API (Cocktail Culturel) to retrieve video suggestions.


🔍 Summary of Code Functionality

  1. Fragment Lifecycle Management

    • onCreateView(), onDestroyView(), onSaveInstanceState(), onRestoreInstanceState()

    • setInitialData(StreamInfo info): Initializes the fragment's data with video stream information.

  2. Display and Management of the Video List

    • handleResult(RelatedItemInfo result): Handles results and updates the video list.

    • getListHeaderSupplier(): Creates the list header with an autoplay option (disabled in this code).

  3. Request to an External API (Cocktail Culturel)

    • getCocktailResults(RelatedItemInfo result): Performs an HTTP request to the API http://api.cocktail-culturel.com to get video recommendations based on the current video.

    • onResponse(): Retrieves JSON data from the API and extracts information to create StreamInfoItem objects.

  4. Use of RxJava and OkHttp

    • loadResult(), loadMoreItemsLogic(): Manage item loading with RxJava.

    • OkHttpClient is used for background network requests.


📌 Detailed Code Explanation

1️⃣ Definition and Management of the Fragment

  • OutingsFragment inherits from BaseListInfoFragment<InfoItem, RelatedItemInfo>, a class that manages a list of video items.

  • getInstance(StreamInfo info): Creates an instance of the fragment and initializes firstCreation.

2️⃣ Lifecycle

  • onCreateView(): Loads the view from the fragment_outings.xml file.

  • onDestroyView(): Cleans up headerBinding and the suggestions list.

3️⃣ List Management and Display

  • handleResult(RelatedItemInfo result):

    • Clears the current list.

    • Retrieves new suggestions via the Cocktail Culturel API (getCocktailResults()).

    • Displays the results in infoListAdapter.

  • getListHeaderSupplier():

    • Loads a header for the list (disabled here).

    • Retrieves an autoplay parameter from shared preferences.

4️⃣ HTTP Request to the Cocktail Culturel API

  • getCocktailResults(RelatedItemInfo result): Executes an HTTP request to retrieve related videos.

  • onResponse():

    • Parses the received JSON.

    • Creates StreamInfoItem objects and adds them to suggestions.

Example URL used:

java
Copy
String url = apiUrl + "/videos/" + videoId;

→ Allows obtaining videos related to a given video ID.

5️⃣ Error Handling and Fragment State

  • onItemError(Throwable exception): Handles search errors.

  • setTitle(String title): Disabled here to avoid modifying the interface title.


🚀 Why is this code useful?

  • It allows displaying a list of relevant videos based on initial content.

  • It retrieves videos from an external API, offering an enriched experience.

  • It uses RxJava and OkHttp to efficiently manage network requests.


💡 In summary:

  • This fragment displays a list of video suggestions.

  • It queries the Cocktail Culturel API to enrich recommendations.

  • It uses RxJava for asynchronous loading and OkHttp for network requests.


Rajoute un filtrage en page d'accueil par catégorie de vidéo

HumourFragmentKiosk

Ce code est un fragment Android écrit en Kotlin, utilisé dans l'application NewPipe pour gérer l'affichage d'un kiosque d'humour (une section spécifique de contenu, comme une catégorie de vidéos). Il hérite de KioskFragment, une classe de base gérant des kiosques dans NewPipe.

📌 Explication du code

1. Dépendances et Imports

Le code importe plusieurs éléments :

  • io.reactivex.rxjava3 : Utilisé pour la gestion asynchrone avec RxJava.
  • org.schabi.newpipe.extractor : Contient des classes permettant d'extraire des vidéos de services comme YouTube.
  • ServiceHelper, Localization, ExtractorHelper, etc. : Fournissent des outils pour interagir avec les services et récupérer des informations.

2. Définition de la classe HumourFragmentKiosk

class HumourFragmentKiosk : KioskFragment() {
  • Cette classe hérite de KioskFragment, qui gère des affichages de contenu sous forme de kiosque.
  • Elle est spécifiquement dédiée au kiosque d'humour.

3. onCreate() : Initialisation

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    if (serviceId < 0) {
        updateSelectedDefaultKiosk()
    }
}
  • Appelle super.onCreate() pour assurer l'initialisation normale du fragment.
  • Vérifie si serviceId est invalide (< 0) :
    • Si oui, elle appelle updateSelectedDefaultKiosk(), qui sélectionne le kiosque par défaut.

4. onResume() : Mise à jour au retour à l'écran

override fun onResume() {
    super.onResume()
    if (serviceId != ServiceHelper.getSelectedServiceId(requireContext())) {
        if (currentWorker != null) {
            currentWorker.dispose()
        }
        updateSelectedDefaultKiosk()
        reloadContent()
    }
}
  • Vérifie si le service sélectionné a changé (serviceId ≠ service en cours).
  • Si oui :
    1. Annule le travailleur en cours (currentWorker.dispose()).
    2. Met à jour le kiosque sélectionné (updateSelectedDefaultKiosk()).
    3. Recharge le contenu (reloadContent()).

5. loadResult() : Récupération des données du kiosque

override fun loadResult(forceReload: Boolean): Single<KioskInfo>? {
    contentCountry = Localization.getPreferredContentCountry(requireContext())
    return ExtractorHelper.getKioskInfo(serviceId, url, forceReload)
}
  • Récupère les vidéos du kiosque sélectionné en utilisant ExtractorHelper.getKioskInfo().
  • Single<KioskInfo> est un objet RxJava, qui exécute la requête de manière asynchrone.
  • contentCountry stocke le pays de l'utilisateur pour adapter le contenu.

6. startLoading() : Chargement du kiosque

override fun startLoading(forceLoad: Boolean) {
    super.startLoading(forceLoad)

    showListFooter(false)
    infoListAdapter.clearStreamItemList()

    currentInfo = null
    if (currentWorker != null) {
        currentWorker.dispose()
    }
    currentWorker = loadResult(forceLoad)
        ?.subscribeOn(io())
        ?.observeOn(AndroidSchedulers.mainThread())
        ?.subscribe(
            { result: KioskInfo ->
                isLoading.set(false)
                currentInfo = result
                currentNextPage = result.nextPage
                handleResult(result)
            },
            { throwable: Throwable? ->
                showError(
                    ErrorInfo(
                        throwable!!, errorUserAction,
                        "Start loading: $url", serviceId
                    )
                )
            }
        )
}
  • Efface la liste des vidéos (infoListAdapter.clearStreamItemList()).
  • Annule le chargement précédent (currentWorker.dispose()).
  • Charge les nouvelles vidéos via loadResult(forceLoad).
  • Utilise RxJava :
    • subscribeOn(io()) : Exécute en tâche de fond.
    • observeOn(AndroidSchedulers.mainThread()) : Affiche le résultat sur le thread principal.
    • En cas de succès, handleResult(result) traite les vidéos récupérées.
    • En cas d'erreur, showError() affiche un message.

7. updateSelectedDefaultKiosk() : Sélection du kiosque par défaut

private fun updateSelectedDefaultKiosk() {
    try {
        serviceId = ServiceHelper.getSelectedServiceId(requireContext())
        val kioskList = NewPipe.getService(serviceId).kioskList
        kioskId = kioskList.defaultKioskId
        url = kioskList.getListLinkHandlerFactoryByType(kioskId).fromId(kioskId).url
        kioskTranslatedName = KioskTranslator.getTranslatedKioskName(kioskId, requireContext())
        name = kioskTranslatedName
        currentInfo = null
        currentNextPage = null
    } catch (e: ExtractionException) {
        showError(
            ErrorInfo(
                e, UserAction.REQUESTED_KIOSK,
                "Loading default kiosk for selected service"
            )
        )
    }
}
  • Récupère l'ID du service actif (serviceId).
  • Charge la liste des kiosques de ce service.
  • Définit le kiosque par défaut (kioskId et url).
  • Traduit son nom (kioskTranslatedName).
  • Si une erreur d'extraction se produit (ExtractionException), elle est capturée et signalée avec showError().

🔍 Résumé

  • Ce fragment Android affiche un kiosque d'humour dans NewPipe.
  • Utilise RxJava pour charger les vidéos de manière asynchrone.
  • Met à jour dynamiquement le kiosque si l'utilisateur change de service.
  • Sélectionne un kiosque par défaut si aucun n'est défini.
  • Gère les erreurs pour éviter les crashs.

C'est un bon exemple d'implémentation modulaire et réactive dans une application open-source Android. 🚀

MusicFragmentKiosk

Ce code est un fragment Android en Kotlin pour l'application NewPipe. Il définit un kiosque spécifique : MusicFragmentKiosk, qui affiche les tendances musicales (probablement depuis YouTube).

Il ressemble beaucoup à HumourFragmentKiosk, mais avec une différence clé : il charge directement une URL spécifique vers les tendances musicales sur YouTube.


📌 Explication détaillée du code

1️⃣ Importations

import android.os.Bundle
import android.text.TextUtils
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers.io
import org.schabi.newpipe.error.ErrorInfo
import org.schabi.newpipe.error.UserAction
import org.schabi.newpipe.extractor.NewPipe
import org.schabi.newpipe.extractor.exceptions.ExtractionException
import org.schabi.newpipe.extractor.kiosk.KioskInfo
import org.schabi.newpipe.util.ExtractorHelper
import org.schabi.newpipe.util.KioskTranslator
import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.ServiceHelper
  • RxJava 3 (io.reactivex.rxjava3) : Permet d'exécuter des opérations asynchrones (chargement des vidéos en arrière-plan).
  • NewPipe Extractor (org.schabi.newpipe.extractor) : Outil pour extraire des vidéos depuis YouTube.
  • ServiceHelper, KioskTranslator, Localization : Classes d'aide pour gérer les services, traductions et localisation.

2️⃣ Définition de MusicFragmentKiosk

class MusicFragmentKiosk : KioskFragment() {
  • MusicFragmentKiosk hérite de KioskFragment, qui gère l'affichage de kiosques de contenu.
  • Il est utilisé pour afficher les tendances musicales.

3️⃣ onCreate() : Initialisation du kiosque

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    if (serviceId < 0) {
        updateSelectedDefaultKiosk()
    }
}
  • Appelle super.onCreate() pour la configuration du fragment.
  • Vérifie si serviceId est invalide (< 0) :
    • Si oui, il charge un kiosque par défaut via updateSelectedDefaultKiosk().

4️⃣ onResume() : Vérification à la reprise

override fun onResume() {
    super.onResume()
    if (serviceId != ServiceHelper.getSelectedServiceId(requireContext())) {
        if (currentWorker != null) {
            currentWorker.dispose()
        }
        updateSelectedDefaultKiosk()
        reloadContent()
    }
}
  • Vérifie si le service sélectionné a changé (serviceId ≠ service actif).
  • Si oui :
    1. Annule le chargement en cours (currentWorker.dispose()).
    2. Recharge le kiosque par défaut (updateSelectedDefaultKiosk()).
    3. Recharge le contenu (reloadContent()).

5️⃣ loadResult() : Chargement des tendances musicales

override fun loadResult(forceReload: Boolean): Single<KioskInfo>? {
    contentCountry = Localization.getPreferredContentCountry(requireContext())
    url = "https://www.youtube.com/feed/trending?bp=4gINGgt5dG1hX2NoYXJ0cw%3D%3D"
    return ExtractorHelper.getKioskInfo(serviceId, "https://www.youtube.com/feed/trending?bp=4gINGgt5dG1hX2NoYXJ0cw%3D%3D", forceReload)
}
  • Définit contentCountry pour adapter le contenu à la localisation de l'utilisateur.
  • Fixe l'URL de la page YouTube contenant les tendances musicales (/feed/trending?bp=...).
  • Appelle ExtractorHelper.getKioskInfo() pour récupérer les vidéos associées.

🟢 Différence avec HumourFragmentKiosk :

  • Ici, l'URL est fixe, alors que dans HumourFragmentKiosk, elle est déterminée dynamiquement.

6️⃣ startLoading() : Lancement du chargement

override fun startLoading(forceLoad: Boolean) {
    super.startLoading(forceLoad)
    showListFooter(false)
    infoListAdapter.clearStreamItemList()

    currentInfo = null
    if (currentWorker != null) {
        currentWorker.dispose()
    }
    currentWorker = loadResult(forceLoad)
        ?.subscribeOn(io())
        ?.observeOn(AndroidSchedulers.mainThread())
        ?.subscribe(
            { result: KioskInfo ->
                isLoading.set(false)
                currentNextPage = result.nextPage
                handleResult(result)
            },
            { throwable: Throwable? ->
                showError(
                    ErrorInfo(
                        throwable!!, errorUserAction,
                        "Start loading: $url", serviceId
                    )
                )
            }
        )
}
  • Efface la liste des vidéos (infoListAdapter.clearStreamItemList()).
  • Annule un chargement en cours (currentWorker.dispose()).
  • Charge les vidéos avec loadResult(forceLoad), exécuté de manière asynchrone :
    • subscribeOn(io()) : Exécution en tâche de fond.
    • observeOn(AndroidSchedulers.mainThread()) : Mise à jour de l'UI sur le thread principal.
    • En cas de succès : handleResult(result) affiche les vidéos.
    • En cas d'erreur : showError() affiche un message.

7️⃣ setInitialData() : Configuration initiale

override fun setInitialData(sid: Int, u: String?, title: String?) {
    serviceId = sid
    url = u
    name = if (!TextUtils.isEmpty(title)) title else ""
}
  • Permet d'initialiser le fragment avec :
    • sid : l'ID du service.
    • u : l'URL du kiosque.
    • title : le nom affiché (vide si null).

8️⃣ updateSelectedDefaultKiosk() : Définition du kiosque par défaut

private fun updateSelectedDefaultKiosk() {
    try {
        serviceId = ServiceHelper.getSelectedServiceId(requireContext())
        val kioskList = NewPipe.getService(serviceId).kioskList
        kioskId = kioskList.defaultKioskId
        url = kioskList.getListLinkHandlerFactoryByType(kioskId).fromId(kioskId).url
        kioskTranslatedName = KioskTranslator.getTranslatedKioskName(kioskId, requireContext())
        name = kioskTranslatedName
        currentInfo = null
        currentNextPage = null
    } catch (e: ExtractionException) {
        showError(
            ErrorInfo(
                e, UserAction.REQUESTED_KIOSK,
                "Loading default kiosk for selected service"
            )
        )
    }
}
  • Récupère l'ID du service sélectionné (serviceId).
  • Charge la liste des kiosques.
  • Sélectionne un kiosque par défaut (kioskId et url).
  • Traduit son nom (kioskTranslatedName).
  • Réinitialise les variables de contenu (currentInfo, currentNextPage).
  • En cas d'erreur (ExtractionException), elle est signalée avec showError().

🔍 Différences avec HumourFragmentKiosk

Fonctionnalité HumourFragmentKiosk MusicFragmentKiosk
Type de contenu Humour Musique
Détermination de l'URL Dynamique via NewPipe.getService() Fixe (https://www.youtube.com/feed/trending?bp=...)
setInitialData() ❌ (Absente) ✅ (Présente)

💡 Conclusion

  • MusicFragmentKiosk est une spécialisation de KioskFragment pour afficher les tendances musicales.
  • Il utilise une URL fixe, contrairement à d'autres kiosques qui sont dynamiques.
  • Il fonctionne avec RxJava pour charger les vidéos de manière asynchrone.
  • Il gère la sélection du service et met à jour le contenu en conséquence.

En résumé, ce fragment permet d'afficher les tendances musicales de YouTube dans NewPipe ! 🚀

OutingFragment.java

Ce code est une classe Java OutingsFragment, qui fait partie du projet NewPipe, une application Android open-source pour regarder des vidéos YouTube sans publicité ni suivi. Cette classe est un fragment qui affiche une liste de vidéos en relation avec un contenu initial, et elle interagit avec une API externe (Cocktail Culturel) pour récupérer des suggestions de vidéos.


🔍 Résumé du fonctionnement du code

  1. Gestion du cycle de vie du fragment

    • onCreateView(), onDestroyView(), onSaveInstanceState(), onRestoreInstanceState()
    • setInitialData(StreamInfo info): Initialise les données du fragment avec des infos sur un flux vidéo.
  2. Affichage et gestion de la liste de vidéos

    • handleResult(RelatedItemInfo result): Gère les résultats et met à jour la liste des vidéos.
    • getListHeaderSupplier(): Crée l'en-tête de la liste avec une option d'autoplay (désactivée dans ce code).
  3. Requête à une API externe (Cocktail Culturel)

    • getCocktailResults(RelatedItemInfo result): Effectue une requête HTTP à l'API http://api.cocktail-culturel.com pour obtenir des recommandations de vidéos en fonction de la vidéo en cours.
    • onResponse(): Récupère les données JSON de l'API et extrait les informations pour créer des objets StreamInfoItem.
  4. Utilisation de RxJava et OkHttp

    • loadResult(), loadMoreItemsLogic(): Gèrent le chargement des éléments avec RxJava.
    • OkHttpClient est utilisé pour la requête réseau en arrière-plan.

📌 Explication détaillée du code

1️⃣ Définition et gestion du fragment

  • OutingsFragment hérite de BaseListInfoFragment<InfoItem, RelatedItemInfo>, une classe qui gère une liste d'éléments vidéo.
  • getInstance(StreamInfo info): Crée une instance du fragment et initialise firstCreation.

2️⃣ Cycle de vie

  • onCreateView(): Charge la vue à partir du fichier fragment_outings.xml.
  • onDestroyView(): Nettoie headerBinding et la liste suggestions.

3️⃣ Gestion de la liste et affichage

  • handleResult(RelatedItemInfo result):

    • Efface la liste actuelle.
    • Récupère de nouvelles suggestions via l'API Cocktail Culturel (getCocktailResults()).
    • Affiche les résultats dans infoListAdapter.
  • getListHeaderSupplier():

    • Charge un en-tête pour la liste (désactivé ici).
    • Récupère un paramètre autoplay depuis les préférences partagées.

4️⃣ Requête HTTP à l'API Cocktail Culturel

  • getCocktailResults(RelatedItemInfo result): Exécute une requête HTTP pour récupérer des vidéos liées.
  • onResponse():
    • Parse le JSON reçu.
    • Crée des objets StreamInfoItem et les ajoute à suggestions.

Exemple d'URL utilisée :

String url = apiUrl + "/videos/" + videoId;

→ Permet d'obtenir des vidéos liées à un ID vidéo donné.

5️⃣ Gestion des erreurs et état du fragment

  • onItemError(Throwable exception): Gère les erreurs de recherche.
  • setTitle(String title): Désactivé ici pour ne pas modifier le titre de l'interface.

🚀 Pourquoi ce code est utile ?

  • Il permet d'afficher une liste de vidéos pertinentes en fonction d'un contenu initial.
  • Il récupère des vidéos depuis une API externe, offrant ainsi une expérience enrichie.
  • Il utilise RxJava et OkHttp pour gérer les requêtes réseau efficacement.

💡 En résumé :

  • Ce fragment affiche une liste de suggestions vidéo.
  • Il interroge l'API Cocktail Culturel pour enrichir les recommandations.
  • Il utilise RxJava pour le chargement asynchrone et OkHttp pour les requêtes réseau.