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.