From 19905510d8caf298d077f201feecfabd68905620 Mon Sep 17 00:00:00 2001 From: Michele Granato Date: Tue, 6 Jan 2026 13:30:59 +0100 Subject: [PATCH 01/20] android auto RC1 --- app/build.gradle.kts | 5 + app/src/main/AndroidManifest.xml | 27 +- .../cloudstream3/services/CSCarAppService.kt | 16 + .../cloudstream3/ui/car/BookmarksScreen.kt | 69 +++ .../cloudstream3/ui/car/CarSession.kt | 26 + .../cloudstream3/ui/car/CategoryScreen.kt | 101 ++++ .../cloudstream3/ui/car/DetailsScreen.kt | 260 ++++++++++ .../ui/car/EpisodeDetailScreen.kt | 117 +++++ .../cloudstream3/ui/car/EpisodeListScreen.kt | 83 ++++ .../cloudstream3/ui/car/HistoryScreen.kt | 158 ++++++ .../cloudstream3/ui/car/LibraryCarScreen.kt | 43 ++ .../cloudstream3/ui/car/MainCarScreen.kt | 172 +++++++ .../cloudstream3/ui/car/PlayerCarScreen.kt | 460 ++++++++++++++++++ .../cloudstream3/ui/car/ProviderCarScreen.kt | 41 ++ .../cloudstream3/ui/car/SearchCarScreen.kt | 85 ++++ .../ui/car/TvSeriesDetailScreen.kt | 249 ++++++++++ app/src/main/res/xml/automotive_app_desc.xml | 6 + gradle/libs.versions.toml | 2 + 18 files changed, 1919 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/lagradost/cloudstream3/services/CSCarAppService.kt create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/CarSession.kt create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/CategoryScreen.kt create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/DetailsScreen.kt create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeDetailScreen.kt create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeListScreen.kt create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/LibraryCarScreen.kt create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/ProviderCarScreen.kt create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/SearchCarScreen.kt create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/TvSeriesDetailScreen.kt create mode 100644 app/src/main/res/xml/automotive_app_desc.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e8a07b571df..b2af926a198 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -66,6 +66,8 @@ android { versionName = "4.6.1" resValue("string", "commit_hash", getGitCommitHash()) + + resourceConfigurations.addAll(listOf("en", "it")) manifestPlaceholders["target_sdk_version"] = libs.versions.targetSdk.get() @@ -152,6 +154,8 @@ android { resValues = true } + + namespace = "com.lagradost.cloudstream3" } @@ -171,6 +175,7 @@ dependencies { implementation(libs.fragment.ktx) implementation(libs.bundles.lifecycle) implementation(libs.bundles.navigation) + implementation(libs.car.app) // Design & UI implementation(libs.preference.ktx) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9e1bc9ac978..d73ad9fdcf7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,7 +11,7 @@ - + @@ -22,6 +22,10 @@ android:name="android.permission.QUERY_ALL_PACKAGES" tools:ignore="QueryAllPackagesPermission" /> + + + + + + + + + + + + @@ -231,6 +247,15 @@ android:foregroundServiceType="dataSync" android:exported="false" /> + + + + + + + + builder.addItem( + Row.Builder() + .setTitle(item.name) + .setOnClickListener { + val type = item.type + if (type == TvType.TvSeries || type == TvType.Anime || type == TvType.OVA) { + screenManager.push(TvSeriesDetailScreen(carContext, item)) + } else { + screenManager.push(DetailsScreen(carContext, item)) + } + } + // .setImage(...) Removed as per user request + .build() + ) + } + itemList = builder.build() + + invalidate() + // Async image loading removed + } + } + + override fun onGetTemplate(): Template { + return ListTemplate.Builder() + .setSingleList(itemList ?: ItemList.Builder().setNoItemsMessage("Loading...").build()) + .setTitle("Bookmarks") + .setHeaderAction(Action.BACK) + .build() + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/CarSession.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/CarSession.kt new file mode 100644 index 00000000000..9315e99f519 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/CarSession.kt @@ -0,0 +1,26 @@ +package com.lagradost.cloudstream3.ui.car + +import android.content.Intent +import androidx.car.app.Screen +import androidx.car.app.Session +import com.lagradost.cloudstream3.plugins.PluginManager +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +class CarSession : Session() { + init { + CoroutineScope(Dispatchers.IO).launch { + try { + @Suppress("DEPRECATION_ERROR") + PluginManager.___DO_NOT_CALL_FROM_A_PLUGIN_loadAllOnlinePlugins(carContext) + } catch (e: Exception) { + e.printStackTrace() + } + } + } + + override fun onCreateScreen(intent: Intent): Screen { + return MainCarScreen(carContext) + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/CategoryScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/CategoryScreen.kt new file mode 100644 index 00000000000..3f0dbb3c4ff --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/CategoryScreen.kt @@ -0,0 +1,101 @@ +package com.lagradost.cloudstream3.ui.car + +import androidx.car.app.CarContext +import androidx.car.app.Screen +import androidx.car.app.model.Action +import androidx.car.app.model.CarIcon +import androidx.car.app.model.GridItem +import androidx.car.app.model.GridTemplate +import androidx.car.app.model.ListTemplate // Added +import androidx.car.app.model.Row // Added +import androidx.car.app.model.ItemList +import androidx.car.app.model.Template +import androidx.core.graphics.drawable.IconCompat +import com.lagradost.cloudstream3.HomePageList +import com.lagradost.cloudstream3.R +import coil3.request.ImageRequest +import coil3.SingletonImageLoader +import coil3.asDrawable +import androidx.core.graphics.drawable.toBitmap +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import kotlinx.coroutines.Job +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll + +class CategoryScreen( + carContext: CarContext, + private val homePageList: HomePageList +) : Screen(carContext) { + + private val scope = CoroutineScope(Dispatchers.IO + Job()) + private var itemList: ItemList? = null + + init { + loadData() + } + + private fun loadData() { + scope.launch { + val listBuilder = ItemList.Builder() + val listItems = homePageList.list.map { item -> + async { + val image = try { + if (!item.posterUrl.isNullOrEmpty()) { + val request = ImageRequest.Builder(carContext) + .data(item.posterUrl) + .size(256, 256) // Increased size for IMAGE_TYPE_LARGE + .build() + val result = SingletonImageLoader.get(carContext).execute(request) + val bitmap = result.image?.asDrawable(carContext.resources)?.toBitmap() + if (bitmap != null) { + CarIcon.Builder(IconCompat.createWithBitmap(bitmap)).build() + } else null + } else null + } catch (e: Exception) { + null + } ?: CarIcon.Builder(IconCompat.createWithResource(carContext, R.mipmap.ic_launcher)).build() + + Row.Builder() + .setTitle(item.name) + .setImage(image, Row.IMAGE_TYPE_LARGE) + .setOnClickListener { + val type = item.type + if (type == com.lagradost.cloudstream3.TvType.TvSeries || + type == com.lagradost.cloudstream3.TvType.Anime || + type == com.lagradost.cloudstream3.TvType.Cartoon || + type == com.lagradost.cloudstream3.TvType.OVA || + type == com.lagradost.cloudstream3.TvType.AsianDrama || + type == com.lagradost.cloudstream3.TvType.Documentary) { + screenManager.push(TvSeriesDetailScreen(carContext, item)) + } else { + screenManager.push(DetailsScreen(carContext, item)) + } + } + .build() + } + }.awaitAll() + + listItems.forEach { listBuilder.addItem(it) } + itemList = listBuilder.build() + invalidate() + } + } + + override fun onGetTemplate(): Template { + val builder = ListTemplate.Builder() + .setTitle(homePageList.name) + .setHeaderAction(Action.BACK) + + if (itemList == null) { + builder.setLoading(true) + } else { + builder.setLoading(false) + builder.setSingleList(itemList!!) + } + + return builder.build() + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/DetailsScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/DetailsScreen.kt new file mode 100644 index 00000000000..b612a00a8c5 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/DetailsScreen.kt @@ -0,0 +1,260 @@ +package com.lagradost.cloudstream3.ui.car + +import androidx.car.app.CarContext +import androidx.car.app.Screen +import androidx.car.app.model.Action +import androidx.car.app.model.CarColor +import androidx.car.app.model.Pane +import androidx.car.app.model.PaneTemplate +import androidx.car.app.model.Row +import androidx.car.app.model.Template +import com.lagradost.cloudstream3.SearchResponse +import com.lagradost.cloudstream3.ui.player.DownloadedPlayerActivity +import android.content.Intent +import android.net.Uri +import android.text.SpannableString +import android.text.Spanned +import androidx.car.app.model.CarIcon +import androidx.car.app.model.ForegroundCarColorSpan +import androidx.core.graphics.drawable.IconCompat +import androidx.core.graphics.drawable.toBitmap +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import coil3.asDrawable +import coil3.request.ImageRequest +import coil3.SingletonImageLoader +import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull +import com.lagradost.cloudstream3.LoadResponse +import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.mvvm.Resource +import com.lagradost.cloudstream3.ui.APIRepository +import com.lagradost.cloudstream3.utils.DataStoreHelper +import com.lagradost.cloudstream3.ui.result.ResultViewModel2 +import com.lagradost.cloudstream3.utils.DataStoreHelper.FavoritesData + +class DetailsScreen( + carContext: CarContext, + private val item: SearchResponse +) : Screen(carContext) { + + private var fullDetails: LoadResponse? = null + private var isLoading = true + private var errorMessage: String? = null + + private var posterBitmap: android.graphics.Bitmap? = null + private var isFavorite: Boolean = false + private val scope = CoroutineScope(Dispatchers.IO + Job()) + + init { + loadData() + } + + private fun loadData() { + scope.launch { + try { + // Load Image + if (!item.posterUrl.isNullOrEmpty()) { + try { + val request = ImageRequest.Builder(carContext) + .data(item.posterUrl) + .data(item.posterUrl) + .size(600, 900) // Higher resolution for hero image + .build() + val result = SingletonImageLoader.get(carContext).execute(request) + posterBitmap = result.image?.asDrawable(carContext.resources)?.toBitmap() + } catch (e: Exception) { + e.printStackTrace() + } + } + + // Load Details + val api = getApiFromNameNull(item.apiName) + if (api != null) { + val repo = APIRepository(api) + when (val result = repo.load(item.url)) { + is Resource.Success -> { + fullDetails = result.value + // Check ID logic matches standard + val id = result.value.url.replace(api.mainUrl, "").replace("/", "").hashCode() + isFavorite = DataStoreHelper.getFavoritesData(id) != null + isLoading = false + } + is Resource.Failure -> { + errorMessage = result.errorString + isLoading = false + } + is Resource.Loading -> {} + } + } else { + errorMessage = "Provider non trovato" + isLoading = false + } + } catch (e: Exception) { + errorMessage = e.message + isLoading = false + } + invalidate() + } + } + + override fun onGetTemplate(): Template { + val paneBuilder = Pane.Builder() + + if (isLoading) { + paneBuilder.setLoading(true) + } else { + val details = fullDetails + + // Header: Title +// ... (Skipping context lines that are not changing to avoid huge chunks, focusing on modification) +// Wait, I need to match TARGET content exactly. I will split this into two replacements if possible or include context. +// Let's target the Play Action block specifically. + + paneBuilder.addRow( + Row.Builder() + .setTitle(details?.name ?: item.name) + .build() + ) + + // Set Hero Image on the Pane itself for maximum size + posterBitmap?.let { + paneBuilder.setImage(CarIcon.Builder(IconCompat.createWithBitmap(it)).build()) + } ?: run { + paneBuilder.setImage(CarIcon.Builder(IconCompat.createWithResource(carContext, R.mipmap.ic_launcher)).build()) + } + + if (details != null) { + // Meta Row: Year • Rating • Duration + val metaStringBuilder = StringBuilder() + details.year?.let { metaStringBuilder.append("$it") } + + // Add Score if available + val score = details.score + if (score != null) { + if (metaStringBuilder.isNotEmpty()) metaStringBuilder.append(" • ") + metaStringBuilder.append(String.format("%.1f/10", score.toDouble(10))) + } + // Note: 'score' is the new field but might be complex. Using what we strictly have or user requested. + // User asked for "Rating". Let's check 'rating' which is Int (0-100 usually or 0-10) or 'score' + + details.duration?.let { + if (metaStringBuilder.isNotEmpty()) metaStringBuilder.append(" • ") + metaStringBuilder.append("${it}m") + } + + if (metaStringBuilder.isNotEmpty()) { + paneBuilder.addRow( + Row.Builder() + .setTitle(metaStringBuilder.toString()) + .build() + ) + } + + // Plot Row + if (!details.plot.isNullOrEmpty()) { + paneBuilder.addRow( + Row.Builder() + .setTitle("Trama") + .addText(details.plot!!) + .build() + ) + } + + // Cast Row + if (!details.actors.isNullOrEmpty()) { + val castList = details.actors!!.groupBy { it.roleString }.flatMap { it.value }.take(5).joinToString(", ") { it.actor.name } + if (castList.isNotEmpty()) { + val s = SpannableString(castList) + s.setSpan( + ForegroundCarColorSpan.create(CarColor.SECONDARY), + 0, + s.length, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + + paneBuilder.addRow( + Row.Builder() + .setTitle("Cast") + .addText(s) + .build() + ) + } + } + } else if (errorMessage != null) { + paneBuilder.addRow(Row.Builder().setTitle("Errore dettagli: $errorMessage").build()) + } + } + + // Play Button: White background (simulated/requested) with Black Icon + val playIcon = IconCompat.createWithResource(carContext, android.R.drawable.ic_media_play) + .setTint(android.graphics.Color.BLACK) + + val playAction = Action.Builder() + .setIcon(CarIcon.Builder(playIcon).build()) + //.setTitle("Play") // No title as requested + .setBackgroundColor(CarColor.createCustom(android.graphics.Color.WHITE, android.graphics.Color.WHITE)) + .setOnClickListener { + screenManager.push(PlayerCarScreen(carContext, item)) + } + .build() + + val favoriteIconRes = if (isFavorite) R.drawable.ic_baseline_favorite_24 else R.drawable.ic_baseline_favorite_border_24 + val favoriteIcon = IconCompat.createWithResource(carContext, favoriteIconRes) + if (isFavorite) { + favoriteIcon.setTint(0xFFFF0000.toInt()) // Red + } else { + favoriteIcon.setTint(android.graphics.Color.WHITE) // White + } + + val favoriteAction = Action.Builder() + .setIcon(CarIcon.Builder(favoriteIcon).build()) + .setOnClickListener { + toggleFavorite() + } + .build() + + paneBuilder.addAction(playAction) + paneBuilder.addAction(favoriteAction) + + return PaneTemplate.Builder(paneBuilder.build()) + .setTitle(fullDetails?.name ?: item.name) + .setHeaderAction(Action.BACK) + .build() + } + + private fun toggleFavorite() { + val details = fullDetails ?: return + val api = getApiFromNameNull(details.apiName) ?: return + val id = details.url.replace(api.mainUrl, "").replace("/", "").hashCode() + + if (isFavorite) { + DataStoreHelper.removeFavoritesData(id) + isFavorite = false + androidx.car.app.CarToast.makeText(carContext, "Rimosso dai preferiti", androidx.car.app.CarToast.LENGTH_SHORT).show() + } else { + val favoritesData = FavoritesData( + favoritesTime = System.currentTimeMillis(), + id = id, + latestUpdatedTime = System.currentTimeMillis(), + name = details.name, + url = details.url, + apiName = details.apiName, + type = details.type, + posterUrl = details.posterUrl, + year = details.year, + quality = null, + posterHeaders = details.posterHeaders, + plot = details.plot, + score = details.score, + tags = details.tags + ) + DataStoreHelper.setFavoritesData(id, favoritesData) + isFavorite = true + androidx.car.app.CarToast.makeText(carContext, "Aggiunto ai preferiti", androidx.car.app.CarToast.LENGTH_SHORT).show() + } + invalidate() + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeDetailScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeDetailScreen.kt new file mode 100644 index 00000000000..3d65749d5ee --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeDetailScreen.kt @@ -0,0 +1,117 @@ +package com.lagradost.cloudstream3.ui.car + +import androidx.car.app.CarContext +import androidx.car.app.Screen +import androidx.car.app.model.Action +import androidx.car.app.model.CarColor +import androidx.car.app.model.CarIcon +import androidx.car.app.model.Pane +import androidx.car.app.model.PaneTemplate +import androidx.car.app.model.Row +import androidx.car.app.model.Template +import androidx.core.graphics.drawable.IconCompat +import androidx.core.graphics.drawable.toBitmap +import coil3.asDrawable +import coil3.request.ImageRequest +import coil3.SingletonImageLoader +import com.lagradost.cloudstream3.Episode +import com.lagradost.cloudstream3.TvSeriesLoadResponse +import com.lagradost.cloudstream3.R +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch + +class EpisodeDetailScreen( + carContext: CarContext, + private val seriesDetails: TvSeriesLoadResponse, + private val episode: Episode, + private val playlist: List +) : Screen(carContext) { + + private val scope = CoroutineScope(Dispatchers.IO + Job()) + private var posterBitmap: android.graphics.Bitmap? = null + private var isLoadingImage = true + + init { + loadImage() + } + + private fun loadImage() { + scope.launch { + // Try episode poster first, then series poster + val url = episode.posterUrl ?: seriesDetails.posterUrl + if (!url.isNullOrEmpty()) { + try { + val request = ImageRequest.Builder(carContext) + .data(url) + .size(600, 900) + .build() + val result = SingletonImageLoader.get(carContext).execute(request) + posterBitmap = result.image?.asDrawable(carContext.resources)?.toBitmap() + } catch (e: Exception) { + e.printStackTrace() + } + } + isLoadingImage = false + invalidate() + } + } + + override fun onGetTemplate(): Template { + val paneBuilder = Pane.Builder() + + // Title Row + val title = "${episode.episode}. ${episode.name ?: "Episodio ${episode.episode}"}" + paneBuilder.addRow( + Row.Builder() + .setTitle(title) + .addText("Stagione ${episode.season ?: "?"}") + .build() + ) + + // Image + posterBitmap?.let { + paneBuilder.setImage(CarIcon.Builder(IconCompat.createWithBitmap(it)).build()) + } ?: run { + // Fallback icon if no image loaded yet or error + paneBuilder.setImage(CarIcon.Builder(IconCompat.createWithResource(carContext, R.mipmap.ic_launcher)).build()) + } + + // Description Row + if (!episode.description.isNullOrEmpty()) { + paneBuilder.addRow( + Row.Builder() + .setTitle("Trama") + .addText(episode.description!!) + .build() + ) + } + + // Play Button actions + val playIcon = IconCompat.createWithResource(carContext, android.R.drawable.ic_media_play) + .setTint(android.graphics.Color.BLACK) + + val playAction = Action.Builder() + .setIcon(CarIcon.Builder(playIcon).build()) + .setBackgroundColor(CarColor.createCustom(android.graphics.Color.WHITE, android.graphics.Color.WHITE)) + .setOnClickListener { + screenManager.push( + PlayerCarScreen( + carContext = carContext, + loadResponse = seriesDetails, + selectedEpisode = episode, + playlist = playlist + ) + ) + } + .build() + + paneBuilder.addAction(playAction) + + return PaneTemplate.Builder(paneBuilder.build()) + .setTitle(seriesDetails.name) // Header Title is Series Name + .setHeaderAction(Action.BACK) + .build() + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeListScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeListScreen.kt new file mode 100644 index 00000000000..ab20c963024 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeListScreen.kt @@ -0,0 +1,83 @@ +package com.lagradost.cloudstream3.ui.car + +import androidx.car.app.CarContext +import androidx.car.app.Screen +import androidx.car.app.model.Action +import androidx.car.app.model.ActionStrip +import androidx.car.app.model.CarIcon +import androidx.car.app.model.ItemList +import androidx.car.app.model.ListTemplate +import androidx.car.app.model.Row +import androidx.car.app.model.Template +import androidx.core.graphics.drawable.IconCompat +import com.lagradost.cloudstream3.TvSeriesLoadResponse +import com.lagradost.cloudstream3.R + +class EpisodeListScreen( + carContext: CarContext, + private val details: TvSeriesLoadResponse +) : Screen(carContext) { + + private val availableSeasons: List = details.episodes.mapNotNull { it.season }.distinct().sorted() + private var currentSeasonIndex: Int = 0 // Index in availableSeasons list + + override fun onGetTemplate(): Template { + if (availableSeasons.isEmpty()) { + return ListTemplate.Builder() + .setTitle(details.name) + .setHeaderAction(Action.BACK) + .setSingleList(ItemList.Builder().addItem(Row.Builder().setTitle("Nessun episodio trovato").build()).build()) + .build() + } + + val currentSeason = availableSeasons[currentSeasonIndex] + val seasonEpisodes = details.episodes.filter { it.season == currentSeason }.sortedBy { it.episode } + + val listBuilder = ItemList.Builder() + + seasonEpisodes.forEach { episode -> + val title = "${episode.episode}. ${episode.name ?: "Episodio ${episode.episode}"}" + val rowBuilder = Row.Builder() + .setTitle(title) + .setTitle(title) + .setOnClickListener { + screenManager.push( + EpisodeDetailScreen( + carContext = carContext, + seriesDetails = details, + episode = episode, + playlist = seasonEpisodes + ) + ) + } + + episode.description?.let { + // Truncate to avoid huge texts, though AA handles some wrapping + val desc = if (it.length > 100) it.substring(0, 97) + "..." else it + rowBuilder.addText(desc) + } + + listBuilder.addItem(rowBuilder.build()) + } + + val seasonAction = Action.Builder() + .setTitle("Stagione $currentSeason") + .setOnClickListener { + // Cycle through seasons + currentSeasonIndex = (currentSeasonIndex + 1) % availableSeasons.size + invalidate() + } + .build() + + return ListTemplate.Builder() + .setTitle("${details.name} - Stagione $currentSeason") + .setHeaderAction(Action.BACK) + .setSingleList(listBuilder.build()) + .setActionStrip( + ActionStrip.Builder() + .addAction(seasonAction) + .build() + ) + .build() + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt new file mode 100644 index 00000000000..c86811073b4 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt @@ -0,0 +1,158 @@ +package com.lagradost.cloudstream3.ui.car + +import androidx.car.app.CarContext +import androidx.car.app.Screen +import androidx.car.app.model.Action +import androidx.car.app.model.ItemList +import androidx.car.app.model.ListTemplate +import androidx.car.app.model.Row +import androidx.car.app.model.Template +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import com.lagradost.cloudstream3.utils.DataStoreHelper.getAllResumeStateIds +import com.lagradost.cloudstream3.utils.DataStoreHelper.getLastWatched +import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos +import com.lagradost.cloudstream3.utils.VideoDownloadHelper +import com.lagradost.cloudstream3.utils.DOWNLOAD_HEADER_CACHE +import com.lagradost.cloudstream3.CloudStreamApp.Companion.getKey +import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull +import com.lagradost.cloudstream3.ui.APIRepository +import com.lagradost.cloudstream3.mvvm.Resource +import com.lagradost.cloudstream3.TvSeriesLoadResponse +import com.lagradost.cloudstream3.SearchResponse +import com.lagradost.cloudstream3.newMovieSearchResponse +import com.lagradost.cloudstream3.newTvSeriesSearchResponse +import com.lagradost.cloudstream3.isMovieType +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class HistoryScreen(carContext: CarContext) : Screen(carContext), DefaultLifecycleObserver { + private val scope = CoroutineScope(Dispatchers.IO) + private var itemList: ItemList? = null + + init { + lifecycle.addObserver(this) + } + + override fun onStart(owner: LifecycleOwner) { + loadHistory() + } + + private fun loadHistory() { + scope.launch { + // Strict logic copied from HomeViewModel.getResumeWatching() + val resumeWatchingResult = withContext(Dispatchers.IO) { + getAllResumeStateIds()?.mapNotNull { id -> + getLastWatched(id) + }?.sortedBy { -it.updateTime }?.mapNotNull { resume -> + val data = getKey( + DOWNLOAD_HEADER_CACHE, + resume.parentId.toString() + ) ?: return@mapNotNull null + + // Mapping to a local helper or using the result directly + // We need the resume object for the episodeId/parentId/pos + Pair(resume, data) + } + } + + val builder = ItemList.Builder() + + if (resumeWatchingResult.isNullOrEmpty()) { + builder.setNoItemsMessage("Nessun elemento 'Continua a guardare' trovato") + } else { + resumeWatchingResult.forEach { (resume, cachedData) -> + val title = cachedData.name + val subtitle = if (resume.episode != null && resume.season != null) { + "S${resume.season}:E${resume.episode}" + } else { + cachedData.apiName + } + + builder.addItem( + Row.Builder() + .setTitle(title) + .addText(subtitle) + .setOnClickListener { + playResumeItem(resume, cachedData) + } + .build() + ) + } + } + + itemList = builder.build() + invalidate() + } + } + + private fun playResumeItem(resume: VideoDownloadHelper.ResumeWatching, cachedData: VideoDownloadHelper.DownloadHeaderCached) { + scope.launch { + withContext(Dispatchers.Main) { + androidx.car.app.CarToast.makeText(carContext, "Riprendo ${cachedData.name}...", androidx.car.app.CarToast.LENGTH_LONG).show() + } + + val api = getApiFromNameNull(cachedData.apiName) ?: return@launch + val repo = APIRepository(api) + + val loadResult = when(val result = repo.load(cachedData.url)) { + is Resource.Success -> result.value + else -> null + } ?: return@launch + + val startTime = getViewPos(resume.episodeId)?.position ?: 0L + + // Prepare SearchResponse item for PlayerCarScreen + val item: SearchResponse = if (cachedData.type.isMovieType()) { + api.newMovieSearchResponse( + name = cachedData.name, + url = cachedData.url, + type = cachedData.type, + ) { + this.posterUrl = cachedData.poster + } + } else { + api.newTvSeriesSearchResponse( + name = cachedData.name, + url = cachedData.url, + type = cachedData.type, + ) { + this.posterUrl = cachedData.poster + } + } + + // Resolve Episode for TV Series + var selectedEpisode: com.lagradost.cloudstream3.Episode? = null + + if (loadResult is TvSeriesLoadResponse) { + selectedEpisode = loadResult.episodes.firstOrNull { + it.episode == resume.episode && it.season == resume.season + } + } + + withContext(Dispatchers.Main) { + screenManager.push( + PlayerCarScreen( + carContext = carContext, + item = item, + loadResponse = loadResult, + selectedEpisode = selectedEpisode, + startTime = startTime + ) + ) + } + } + } + + override fun onGetTemplate(): Template { + val list = itemList ?: ItemList.Builder().setNoItemsMessage("Caricamento cronologia...").build() + + return ListTemplate.Builder() + .setTitle("Cronologia") + .setHeaderAction(Action.BACK) + .setSingleList(list) + .build() + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/LibraryCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/LibraryCarScreen.kt new file mode 100644 index 00000000000..bcb0dd616b4 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/LibraryCarScreen.kt @@ -0,0 +1,43 @@ +package com.lagradost.cloudstream3.ui.car + +import androidx.car.app.CarContext +import androidx.car.app.Screen +import androidx.car.app.model.Action +import androidx.car.app.model.ItemList +import androidx.car.app.model.ListTemplate +import androidx.car.app.model.Row +import androidx.car.app.model.Template +import com.lagradost.cloudstream3.utils.DataStoreHelper +import com.lagradost.cloudstream3.utils.DataStoreHelper.getBookmarkedData +import com.lagradost.cloudstream3.utils.DataStoreHelper.getLastWatched +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +class LibraryCarScreen(carContext: CarContext) : Screen(carContext) { + + override fun onGetTemplate(): Template { + return ListTemplate.Builder() + .setSingleList( + ItemList.Builder() + .addItem( + Row.Builder() + .setTitle("Bookmarks") + .setOnClickListener { screenManager.push(BookmarksScreen(carContext)) } + .setBrowsable(true) + .build() + ) + .addItem( + Row.Builder() + .setTitle("History") + .setOnClickListener { screenManager.push(HistoryScreen(carContext)) } + .setBrowsable(true) + .build() + ) + .build() + ) + .setTitle("Library") + .setHeaderAction(Action.BACK) + .build() + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt new file mode 100644 index 00000000000..80475eb196d --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt @@ -0,0 +1,172 @@ +package com.lagradost.cloudstream3.ui.car + +import androidx.car.app.CarContext +import androidx.car.app.Screen +import androidx.car.app.model.Action +import androidx.car.app.model.CarIcon +import androidx.car.app.model.ItemList +import androidx.car.app.model.ListTemplate +import androidx.car.app.model.Row +import androidx.car.app.model.SectionedItemList +import androidx.car.app.model.Template +import androidx.core.graphics.drawable.IconCompat +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull +import com.lagradost.cloudstream3.HomePageList +import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.mvvm.Resource +import com.lagradost.cloudstream3.ui.APIRepository +import com.lagradost.cloudstream3.utils.DataStoreHelper +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +class MainCarScreen(carContext: CarContext) : Screen(carContext), DefaultLifecycleObserver { + private var homePageLists: List = emptyList() + private var isLoading = true + private var errorMessage: String? = null + private var currentApiName: String = "" + + init { + lifecycle.addObserver(this) + } + + override fun onResume(owner: LifecycleOwner) { + super.onResume(owner) + // Reload data on resume to catch provider changes + loadData() + } + + private fun loadData() { + isLoading = true + errorMessage = null + currentApiName = DataStoreHelper.currentHomePage ?: "" + invalidate() + + CoroutineScope(Dispatchers.IO).launch { + try { + var api = getApiFromNameNull(currentApiName) + var attempts = 0 + // Retry for up to 10 seconds (20 * 500ms) waiting for plugins to load + while (api == null && attempts < 20) { + kotlinx.coroutines.delay(500) + api = getApiFromNameNull(currentApiName) + attempts++ + } + + if (api == null) { + errorMessage = "Provider not found: $currentApiName" + isLoading = false + invalidate() + return@launch + } + + val repo = APIRepository(api) + when (val result = repo.getMainPage(1, null)) { + is Resource.Success -> { + homePageLists = result.value.filterNotNull().flatMap { it.items } + isLoading = false + } + is Resource.Failure -> { + errorMessage = result.errorString ?: "Error loading content" + isLoading = false + } + is Resource.Loading -> {} + } + } catch (e: Exception) { + errorMessage = e.message + isLoading = false + } + invalidate() + } + } + + override fun onGetTemplate(): Template { + // 1. Menu Section Builder + val menuListBuilder = ItemList.Builder() + + menuListBuilder.addItem( + Row.Builder() + .setTitle("Libreria") + .addText("Preferiti, Cronologia") + .setImage(CarIcon.Builder(IconCompat.createWithResource(carContext, android.R.drawable.ic_menu_gallery)).build()) + .setOnClickListener { screenManager.push(LibraryCarScreen(carContext)) } + .setBrowsable(true) + .build() + ) + + menuListBuilder.addItem( + Row.Builder() + .setTitle("Provider") + .addText("Attuale: $currentApiName") + .setImage(CarIcon.Builder(IconCompat.createWithResource(carContext, android.R.drawable.ic_menu_manage)).build()) + .setOnClickListener { screenManager.push(ProviderCarScreen(carContext)) } + .setBrowsable(true) + .build() + ) + + + + // 2. Content Section Builder + val contentListBuilder = ItemList.Builder() + + if (isLoading) { + contentListBuilder.addItem(Row.Builder().setTitle("Caricamento contenuti...").setBrowsable(false).build()) + } else if (errorMessage != null) { + contentListBuilder.addItem(Row.Builder().setTitle("Errore: $errorMessage").setBrowsable(false).build()) + } else if (homePageLists.isEmpty()) { + contentListBuilder.addItem(Row.Builder().setTitle("Nessun contenuto dal provider").setBrowsable(false).build()) + } else { + homePageLists.forEach { homePageList -> + contentListBuilder.addItem( + Row.Builder() + .setTitle(homePageList.name) + .setOnClickListener { + screenManager.push(CategoryScreen(carContext, homePageList)) + } + .setBrowsable(true) + .build() + ) + } + } + + // 3. Assemble ListTemplate + return ListTemplate.Builder() + .setTitle(carContext.getString(R.string.app_name)) + //.setHeaderAction(Action.APP_ICON) // Removed to prevent action limit crash + .addSectionedList( + SectionedItemList.create( + menuListBuilder.build(), + "Menu" + ) + ) + .addSectionedList( + SectionedItemList.create( + contentListBuilder.build(), + "Contenuti Home" + ) + ) + .setActionStrip( + androidx.car.app.model.ActionStrip.Builder() + .addAction( + Action.Builder() + .setIcon(CarIcon.Builder(IconCompat.createWithResource(carContext, android.R.drawable.ic_menu_search)).build()) + .setOnClickListener { + screenManager.push(SearchCarScreen(carContext)) + } + .build() + ) + .addAction( + Action.Builder() + .setIcon(CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_refresh)).build()) + .setOnClickListener { + loadData() + } + .build() + ) + .build() + ) + .build() + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt new file mode 100644 index 00000000000..9a2548e6707 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt @@ -0,0 +1,460 @@ +package com.lagradost.cloudstream3.ui.car + +import android.view.Surface +import androidx.car.app.AppManager +import androidx.car.app.CarContext +import androidx.car.app.Screen +import androidx.car.app.SurfaceCallback +import androidx.car.app.SurfaceContainer +import androidx.car.app.model.Action +import androidx.car.app.model.ActionStrip +import androidx.car.app.model.CarColor +import androidx.car.app.model.Template +import androidx.car.app.navigation.model.NavigationTemplate +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.LifecycleOwner +import androidx.media3.common.AudioAttributes +import androidx.media3.common.C +import androidx.media3.common.MediaItem +import androidx.media3.common.MimeTypes +import androidx.media3.common.Player +import androidx.media3.exoplayer.ExoPlayer +import androidx.media3.session.MediaSession +import androidx.car.app.model.CarIcon +import androidx.core.graphics.drawable.IconCompat +import com.lagradost.cloudstream3.R +import androidx.media3.common.C.VIDEO_SCALING_MODE_SCALE_TO_FIT +import androidx.media3.common.C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING +import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull +import com.lagradost.cloudstream3.SearchResponse +import com.lagradost.cloudstream3.mvvm.Resource +import com.lagradost.cloudstream3.ui.APIRepository +import com.lagradost.cloudstream3.utils.ExtractorLink +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import android.util.Log + +import com.lagradost.cloudstream3.LoadResponse +import com.lagradost.cloudstream3.Episode +import com.lagradost.cloudstream3.TvSeriesLoadResponse +import com.lagradost.cloudstream3.AnimeLoadResponse +import com.lagradost.cloudstream3.MovieLoadResponse +import com.lagradost.cloudstream3.utils.DataStoreHelper +import com.lagradost.cloudstream3.utils.DataStoreHelper.fixVisual +import com.lagradost.cloudstream3.TvType +import kotlinx.coroutines.delay + +class PlayerCarScreen( + carContext: CarContext, + val item: SearchResponse? = null, + val loadResponse: LoadResponse? = null, + val selectedEpisode: Episode? = null, + val playlist: List? = null, + val startTime: Long = 0L +) : Screen(carContext), SurfaceCallback { + + private val scope = CoroutineScope(Dispatchers.IO + Job()) + private var player: ExoPlayer? = null + private var surface: Surface? = null + private var mediaSession: MediaSession? = null + private var isPlaying = true + + private var resizeMode = VIDEO_SCALING_MODE_SCALE_TO_FIT + + private var currentEpisodeId: Int? = null + private var currentParentId: Int? = null + private var saveProgressJob: Job? = null + private var showSeekControls = false + + init { + lifecycle.addObserver(object : LifecycleEventObserver { + override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) { + when (event) { + Lifecycle.Event.ON_START -> { + carContext.getCarService(AppManager::class.java).setSurfaceCallback(this@PlayerCarScreen) + player?.playWhenReady = true + } + Lifecycle.Event.ON_STOP -> { + player?.playWhenReady = false + saveProgress() + carContext.getCarService(AppManager::class.java).setSurfaceCallback(null) + } + Lifecycle.Event.ON_DESTROY -> { + mediaSession?.release() + mediaSession = null + player?.release() + player = null + scope.cancel() + } + else -> {} + } + } + }) + } + + override fun onSurfaceAvailable(surfaceContainer: SurfaceContainer) { + val newSurface = surfaceContainer.surface + if (newSurface != null) { + surface = newSurface + player?.setVideoSurface(newSurface) + } + } + + override fun onSurfaceDestroyed(surfaceContainer: SurfaceContainer) { + surface = null + player?.setVideoSurface(null) + } + + private fun loadMedia(url: String?) { + updateStatus("Caricamento...") + scope.launch { + // If we already have the LoadResponse (passed from Details), use it. + // Otherwise, fetch it using item.url + val data: LoadResponse? = if (loadResponse != null) { + loadResponse + } else if (item != null) { + val apiName = item.apiName + val api = getApiFromNameNull(apiName) ?: return@launch + val repo = APIRepository(api) + when(val result = repo.load(item.url)) { + is Resource.Success -> result.value + else -> null + } + } else { + null + } + + if (data == null) { + showToast("Impossibile caricare i dettagli") + return@launch + } + + val apiName = data.apiName + val api = getApiFromNameNull(apiName) ?: return@launch + + val links = mutableListOf() + try { + val urlToLoad = when { + selectedEpisode != null -> selectedEpisode.data + data is com.lagradost.cloudstream3.TvSeriesLoadResponse -> { + // Auto-select first episode if none selected + data.episodes.firstOrNull()?.data + } + data is com.lagradost.cloudstream3.AnimeLoadResponse -> { + // Auto-select first episode from first available category + data.episodes.values.flatten().firstOrNull()?.data + } + data is com.lagradost.cloudstream3.MovieLoadResponse -> { + data.dataUrl + } + else -> data.url + } + + if (urlToLoad == null) { + showToast("Nessun contenuto riproducibile trovato") + return@launch + } + + // Load links using the API + val success = api.loadLinks(urlToLoad, false, {}, { link -> + links.add(link) + }) + + if(links.isNotEmpty()) { + val bestLink = links.sortedByDescending { it.quality }.first() + startPlayback(bestLink) + } else { + showToast("Nessun link trovato") + } + } catch (e: Exception) { + showToast("Errore caricamento link: ${e.message}") + e.printStackTrace() + } + + // Resolve IDs for syncing (Exact match to Main App's ResultViewModel2.getLoadResponseIdFromUrl) + // Logic: url.replace(mainUrl, "").replace("/", "").hashCode() + + val mainUrl = api.mainUrl + val idFromUrl = data.url.replace(mainUrl, "").replace("/", "").hashCode() + + // Priority: 1. Item ID (if available from Home/Search and valid) + // 2. Data URL Hashcode (using strict cleaning logic) + currentParentId = item?.id ?: idFromUrl + + if (data is TvSeriesLoadResponse && selectedEpisode != null) { + // Episode doesn't have an ID property, so we use the data (url) hashcode + // Note: Episodes might not use the mainUrl cleanup in the same way, but usually depend on their own data string. + // In PlayerGeneratorViewModel/RepoLinkGenerator, episodes use 'current.id' which comes from ResultEpisode. + // ResultEpisode is built using 'id' from LoadResponse. + // So we should apply the same cleaning to episode data if it's a URL. + // However, selectedEpisode.data is usually the direct link. + // Let's stick to .hashCode() of the data string for episodes as a reasonable unique key if explicit ID is known to be missing. + currentEpisodeId = selectedEpisode.data.hashCode() + } else { + // For movies, we use the parent ID + currentEpisodeId = currentParentId + } + + Log.d("PlayerCarScreen", "Resolved IDs (STRICT) - Name: ${data.name} | Parent: $currentParentId | Episode: $currentEpisodeId | Type: ${data.javaClass.simpleName} | ItemID: ${item?.id} | IdFromUrl: $idFromUrl") + } + } + + private fun saveProgress() { + val p = player ?: return + val pos = p.currentPosition + val dur = p.duration + + Log.d("PlayerCarScreen", "saveProgress - Pos: $pos, Dur: $dur, IsPlaying: $isPlaying") + + if (dur <= 0) return + + // 1. Save detailed position (setViewPos) + // Only if we have a valid ID. For Movies, currentEpisodeId might be enough. + // For Episodes, we need the specific episode ID. + if (currentEpisodeId != null) { + DataStoreHelper.setViewPos(currentEpisodeId, pos, dur) + Log.d("PlayerCarScreen", "Called setViewPos for EpisodeID: $currentEpisodeId") + } else { + Log.d("PlayerCarScreen", "Skipping setViewPos (EpisodeID is null)") + } + + // 2. Save "Last Watched" for Continue Watching list + // This requires parentId. + if (currentParentId != null) { + // Logic to check if finished (95% rule) + val percentage = pos * 100L / dur + if (percentage > 95) { + // Mark as finished / remove from resume + DataStoreHelper.removeLastWatched(currentParentId) + Log.d("PlayerCarScreen", "Removed Last Watched (Finished)") + } else { + // Update resume state + val epNum = selectedEpisode?.episode + val seasonNum = selectedEpisode?.season + + DataStoreHelper.setLastWatched( + parentId = currentParentId, + episodeId = currentEpisodeId, + episode = epNum, + season = seasonNum, + isFromDownload = false, + updateTime = System.currentTimeMillis() + ) + Log.d("PlayerCarScreen", "Set Last Watched for ParentID: $currentParentId") + } + } else { + Log.d("PlayerCarScreen", "Skipping setLastWatched (ParentID is null)") + } + } + + private suspend fun startPlayback(link: Any) { + val url = when(link) { + is ExtractorLink -> link.url + is String -> link + else -> return + } + + withContext(Dispatchers.Main) { + updateStatus("Avvio riproduzione...") + if (player == null) { + player = ExoPlayer.Builder(carContext).build().apply { + val audioAttributes = AudioAttributes.Builder() + .setUsage(C.USAGE_MEDIA) + .setContentType(C.AUDIO_CONTENT_TYPE_MOVIE) + .build() + setAudioAttributes(audioAttributes, true) + } + } + player?.let { p -> + // Initialize MediaSession + if (mediaSession == null) { + mediaSession = MediaSession.Builder(carContext, p) + .setCallback(object : MediaSession.Callback { + override fun onConnect( + session: MediaSession, + controller: MediaSession.ControllerInfo + ): MediaSession.ConnectionResult { + return MediaSession.ConnectionResult.AcceptedResultBuilder(session).build() + } + }) + .build() + } + + p.addListener(object : Player.Listener { + override fun onIsPlayingChanged(isPlaying: Boolean) { + this@PlayerCarScreen.isPlaying = isPlaying + invalidate() + } + }) + + surface?.let { p.setVideoSurface(it) } + p.videoScalingMode = resizeMode + + val mediaItemBuilder = MediaItem.Builder().setUri(url) + if (link is ExtractorLink && link.isM3u8) { + mediaItemBuilder.setMimeType(MimeTypes.APPLICATION_M3U8) + } + + p.setMediaItem(mediaItemBuilder.build()) + p.prepare() + if (startTime > 0L) { + p.seekTo(startTime) + } + p.play() + updateStatus("In riproduzione") + + // Start periodic save loop + // startSaveLoop() + } + } + } + + private fun startSaveLoop() { + saveProgressJob?.cancel() + saveProgressJob = scope.launch { + Log.d("PlayerCarScreen", "Starting Save Loop") + while (true) { + delay(15_000) // Save every 15 seconds + if (isPlaying) { + withContext(Dispatchers.Main) { + saveProgress() + } + } + } + } + } + + private fun showToast(msg: String) { + androidx.car.app.CarToast.makeText(carContext, msg, androidx.car.app.CarToast.LENGTH_LONG).show() + } + + // Using a minimal Navigation Template to get the surface + // Using a minimal Navigation Template to get the surface + override fun onGetTemplate(): Template { + val playPauseAction = Action.Builder() + .setIcon( + CarIcon.Builder( + IconCompat.createWithResource( + carContext, + if (isPlaying) R.drawable.ic_baseline_pause_24 else R.drawable.ic_baseline_play_arrow_24 + ) + ).build() + ) + .setOnClickListener { + if (isPlaying) { + player?.pause() + saveProgress() // Save immediately when pausing + } else { + player?.play() + } + } + .build() + + val actionStripBuilder = ActionStrip.Builder() + + if (showSeekControls) { + // SEEK MODE: [Back (to menu)], [-10], [Play], [+30] + + val backToMenuAction = Action.Builder() + .setIcon(CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_baseline_arrow_back_24)).build()) + .setOnClickListener { + showSeekControls = false + invalidate() + } + .build() + + val seekBackAction = Action.Builder() + .setIcon(CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.go_back_30)).build()) + .setOnClickListener { seekBack() } + .build() + + val seekForwardAction = Action.Builder() + .setIcon(CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.go_forward_30)).build()) + .setOnClickListener { seekForward() } + .build() + + actionStripBuilder.addAction(backToMenuAction) + .addAction(seekBackAction) + .addAction(playPauseAction) + .addAction(seekForwardAction) + + } else { + // DEFAULT MODE: [Back (Exit)], [Play], [Resize], [Seek Controls] + + val exitAction = Action.Builder() + .setIcon(CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_baseline_arrow_back_24)).build()) + .setOnClickListener { screenManager.pop() } + .build() + + val resizeAction = Action.Builder() + .setIcon(CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_baseline_aspect_ratio_24)).build()) + .setOnClickListener { + resizeMode = if (resizeMode == VIDEO_SCALING_MODE_SCALE_TO_FIT) { + VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING + } else { + VIDEO_SCALING_MODE_SCALE_TO_FIT + } + player?.videoScalingMode = resizeMode + showToast(if (resizeMode == VIDEO_SCALING_MODE_SCALE_TO_FIT) "Adatta allo schermo" else "Riempi schermo") + } + .build() + + val seekBackAction = Action.Builder() + .setIcon(CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.go_back_30)).build()) + .setOnClickListener { + seekBack() + } + .build() + + val openSeekAction = Action.Builder() + .setIcon(CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_baseline_tune_24)).build()) + .setOnClickListener { + showSeekControls = true + invalidate() + } + .build() + + actionStripBuilder.addAction(exitAction) + .addAction(playPauseAction) + .addAction(resizeAction) + .addAction(openSeekAction) + } + + return NavigationTemplate.Builder() + .setActionStrip(actionStripBuilder.build()) + .setBackgroundColor(CarColor.createCustom(android.graphics.Color.BLACK, android.graphics.Color.BLACK)) + .build() + } + + private fun seekBack() { + player?.let { p -> + val newPos = p.currentPosition - 30_000 // -30 seconds + p.seekTo(if (newPos < 0) 0 else newPos) + updateStatus("-30s") + } + } + + private fun seekForward() { + player?.let { p -> + val newPos = p.currentPosition + 30_000 // +30 seconds + val duration = p.duration + p.seekTo(if (newPos > duration) duration else newPos) + updateStatus("+30s") + } + } + + private fun updateStatus(status: String) { + if(status != "Playing") { + showToast(status) + } + } + + init { + loadMedia(item?.url) + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/ProviderCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/ProviderCarScreen.kt new file mode 100644 index 00000000000..fd730dbe2f8 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/ProviderCarScreen.kt @@ -0,0 +1,41 @@ +package com.lagradost.cloudstream3.ui.car + +import androidx.car.app.CarContext +import androidx.car.app.Screen +import androidx.car.app.model.Action +import androidx.car.app.model.ItemList +import androidx.car.app.model.ListTemplate +import androidx.car.app.model.Row +import androidx.car.app.model.Template +import com.lagradost.cloudstream3.APIHolder.apis +import com.lagradost.cloudstream3.utils.DataStoreHelper + +class ProviderCarScreen(carContext: CarContext) : Screen(carContext) { + override fun onGetTemplate(): Template { + val listBuilder = ItemList.Builder() + + // Filter APIs mostly for simplicity, or show all + val current = DataStoreHelper.currentHomePage + + apis.forEach { api -> + val row = Row.Builder() + .setTitle(api.name) + .setOnClickListener { + DataStoreHelper.currentHomePage = api.name + screenManager.pop() // Go back to Home which will reload + } + + if (api.name == current) { + row.addText("Selected") + } + + listBuilder.addItem(row.build()) + } + + return ListTemplate.Builder() + .setSingleList(listBuilder.build()) + .setTitle("Select Provider") + .setHeaderAction(Action.BACK) + .build() + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/SearchCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/SearchCarScreen.kt new file mode 100644 index 00000000000..b97f24a0232 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/SearchCarScreen.kt @@ -0,0 +1,85 @@ +package com.lagradost.cloudstream3.ui.car + +import androidx.car.app.CarContext +import androidx.car.app.Screen +import androidx.car.app.model.Action +import androidx.car.app.model.CarIcon +import androidx.car.app.model.ItemList +import androidx.car.app.model.Row +import androidx.car.app.model.SearchTemplate +import androidx.car.app.model.Template +import androidx.core.graphics.drawable.IconCompat +import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull +import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.mvvm.Resource +import com.lagradost.cloudstream3.ui.APIRepository +import com.lagradost.cloudstream3.utils.DataStoreHelper +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.launch +import androidx.car.app.CarToast + +class SearchCarScreen(carContext: CarContext) : Screen(carContext) { + + private var itemList: ItemList? = null + private var searchJob: Job? = null + + private val searchCallback = object : SearchTemplate.SearchCallback { + override fun onSearchTextChanged(searchText: String) { + // Optional: Implement autocomplete here + } + + override fun onSearchSubmitted(searchText: String) { + performSearch(searchText) + } + } + + private fun performSearch(query: String) { + searchJob?.cancel() + searchJob = CoroutineScope(Dispatchers.IO).launch { + val apiName = DataStoreHelper.currentHomePage ?: return@launch + val api = getApiFromNameNull(apiName) ?: return@launch + val repo = APIRepository(api) + + // Check if search requires page + when(val result = repo.search(query, 1)) { + is Resource.Success -> { + val builder = ItemList.Builder() + val items = result.value.items + if (items.isEmpty()) { + builder.setNoItemsMessage("Nessun risultato trovato") + } + + // Text-only results + items.forEach { item -> + builder.addItem( + Row.Builder() + .setTitle(item.name) + .setOnClickListener { screenManager.push(DetailsScreen(carContext, item)) } + .build() + ) + } + + itemList = builder.build() + invalidate() + } + is Resource.Failure -> { + // Handle error + } + else -> {} + } + } + } + + override fun onGetTemplate(): Template { + return SearchTemplate.Builder(searchCallback) + .setSearchHint("Cerca film e serie TV...") + .setHeaderAction(Action.BACK) + .setShowKeyboardByDefault(true) + .setItemList(itemList ?: ItemList.Builder().build()) + .build() + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/TvSeriesDetailScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/TvSeriesDetailScreen.kt new file mode 100644 index 00000000000..82f786c034e --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/TvSeriesDetailScreen.kt @@ -0,0 +1,249 @@ +package com.lagradost.cloudstream3.ui.car + +import androidx.car.app.CarContext +import androidx.car.app.Screen +import androidx.car.app.model.Action +import androidx.car.app.model.CarColor +import androidx.car.app.model.CarIcon +import androidx.car.app.model.ForegroundCarColorSpan +import androidx.car.app.model.Pane +import androidx.car.app.model.PaneTemplate +import androidx.car.app.model.Row +import androidx.car.app.model.Template +import androidx.core.graphics.drawable.IconCompat +import androidx.core.graphics.drawable.toBitmap +import coil3.asDrawable +import coil3.request.ImageRequest +import coil3.SingletonImageLoader +import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull +import com.lagradost.cloudstream3.LoadResponse +import com.lagradost.cloudstream3.SearchResponse +import com.lagradost.cloudstream3.TvSeriesLoadResponse +import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.mvvm.Resource +import com.lagradost.cloudstream3.ui.APIRepository +import com.lagradost.cloudstream3.utils.DataStoreHelper +import com.lagradost.cloudstream3.utils.DataStoreHelper.FavoritesData +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import android.text.SpannableString +import android.text.Spanned + +class TvSeriesDetailScreen( + carContext: CarContext, + private val item: SearchResponse +) : Screen(carContext) { + + private val scope = CoroutineScope(Dispatchers.IO + Job()) + private var fullDetails: TvSeriesLoadResponse? = null + private var isLoading = true + private var errorMessage: String? = null + private var posterBitmap: android.graphics.Bitmap? = null + private var isFavorite: Boolean = false + + init { + loadDetails() + } + + private fun loadDetails() { + scope.launch { + // Load header image + if (!item.posterUrl.isNullOrEmpty()) { + try { + val request = ImageRequest.Builder(carContext) + .data(item.posterUrl) + .size(600, 900) + .build() + val result = SingletonImageLoader.get(carContext).execute(request) + posterBitmap = result.image?.asDrawable(carContext.resources)?.toBitmap() + } catch (e: Exception) { + e.printStackTrace() + } + } + + // Load full details + val api = getApiFromNameNull(item.apiName) + if (api != null) { + val repo = APIRepository(api) + when (val result = repo.load(item.url)) { + is Resource.Success -> { + val data = result.value + if (data is TvSeriesLoadResponse) { + fullDetails = data + // Check Favorite status + val id = data.url.replace(api.mainUrl, "").replace("/", "").hashCode() + isFavorite = DataStoreHelper.getFavoritesData(id) != null + } else { + errorMessage = "Non è una serie TV" + } + isLoading = false + } + is Resource.Failure -> { + errorMessage = result.errorString ?: "Errore caricamento dettagli" + isLoading = false + } + is Resource.Loading -> {} + } + } else { + errorMessage = "Provider non trovato" + isLoading = false + } + invalidate() + } + } + + private fun toggleFavorite() { + val details = fullDetails ?: return + val api = getApiFromNameNull(details.apiName) ?: return + val id = details.url.replace(api.mainUrl, "").replace("/", "").hashCode() + + if (isFavorite) { + DataStoreHelper.removeFavoritesData(id) + isFavorite = false + androidx.car.app.CarToast.makeText(carContext, "Rimosso dai preferiti", androidx.car.app.CarToast.LENGTH_SHORT).show() + } else { + val favoritesData = FavoritesData( + favoritesTime = System.currentTimeMillis(), + id = id, + latestUpdatedTime = System.currentTimeMillis(), + name = details.name, + url = details.url, + apiName = details.apiName, + type = details.type, + posterUrl = details.posterUrl, + year = details.year, + quality = null, + posterHeaders = details.posterHeaders, + plot = details.plot, + score = details.score, + tags = details.tags + ) + DataStoreHelper.setFavoritesData(id, favoritesData) + isFavorite = true + androidx.car.app.CarToast.makeText(carContext, "Aggiunto ai preferiti", androidx.car.app.CarToast.LENGTH_SHORT).show() + } + invalidate() + } + + override fun onGetTemplate(): Template { + val paneBuilder = Pane.Builder() + + if (isLoading) { + paneBuilder.setLoading(true) + } else { + val details = fullDetails + + // Header: Title + paneBuilder.addRow( + Row.Builder() + .setTitle(details?.name ?: item.name) + .build() + ) + + // Include Hero Image if available + posterBitmap?.let { + paneBuilder.setImage(CarIcon.Builder(IconCompat.createWithBitmap(it)).build()) + } ?: run { + paneBuilder.setImage(CarIcon.Builder(IconCompat.createWithResource(carContext, R.mipmap.ic_launcher)).build()) + } + + if (details != null) { + // Meta Row: Year • Score • Duration/Seasons + val metaStringBuilder = StringBuilder() + details.year?.let { metaStringBuilder.append("$it") } + + val score = details.score + if (score != null) { + if (metaStringBuilder.isNotEmpty()) metaStringBuilder.append(" • ") + metaStringBuilder.append(String.format("%.1f/10", score.toDouble(10))) + } + + // Show season count in meta + // details.seasonNames could be used, or just aggregating episodes + val seasonCount = details.episodes.mapNotNull { it.season }.distinct().count() + if (metaStringBuilder.isNotEmpty()) metaStringBuilder.append(" • ") + metaStringBuilder.append("$seasonCount Stagioni") + + if (metaStringBuilder.isNotEmpty()) { + paneBuilder.addRow( + Row.Builder() + .setTitle(metaStringBuilder.toString()) + .build() + ) + } + + // Favorite Action + val favoriteIconRes = if (isFavorite) R.drawable.ic_baseline_favorite_24 else R.drawable.ic_baseline_favorite_border_24 + val favoriteIcon = IconCompat.createWithResource(carContext, favoriteIconRes) + if (isFavorite) { + favoriteIcon.setTint(0xFFFF0000.toInt()) // Red + } else { + favoriteIcon.setTint(android.graphics.Color.WHITE) // White + } + + val favoriteAction = Action.Builder() + .setIcon(CarIcon.Builder(favoriteIcon).build()) + .setOnClickListener { + toggleFavorite() + } + .build() + + // Episodes Button Action + // "Episode List >" + paneBuilder.addAction( + Action.Builder() + .setTitle("Lista Episodi") + .setBackgroundColor(CarColor.PRIMARY) + .setOnClickListener { + screenManager.push(EpisodeListScreen(carContext, details)) + } + .build() + ) + + paneBuilder.addAction(favoriteAction) + + // Plot Row + if (!details.plot.isNullOrEmpty()) { + paneBuilder.addRow( + Row.Builder() + .setTitle("Trama") + .addText(details.plot!!) + .build() + ) + } + + // Cast Row + if (!details.actors.isNullOrEmpty()) { + val castList = details.actors!!.groupBy { it.roleString }.flatMap { it.value }.take(5).joinToString(", ") { it.actor.name } + if (castList.isNotEmpty()) { + val s = SpannableString(castList) + s.setSpan( + ForegroundCarColorSpan.create(CarColor.SECONDARY), + 0, + s.length, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + + paneBuilder.addRow( + Row.Builder() + .setTitle("Cast") + .addText(s) + .build() + ) + } + } + + } else if (errorMessage != null) { + paneBuilder.addRow(Row.Builder().setTitle("Errore: $errorMessage").build()) + } + } + + return PaneTemplate.Builder(paneBuilder.build()) + .setTitle(item.name) + .setHeaderAction(Action.BACK) + .build() + } +} diff --git a/app/src/main/res/xml/automotive_app_desc.xml b/app/src/main/res/xml/automotive_app_desc.xml new file mode 100644 index 00000000000..c601d28ff79 --- /dev/null +++ b/app/src/main/res/xml/automotive_app_desc.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f03f2d86866..c2d290f2c21 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,6 +6,7 @@ androidGradlePlugin = "8.13.2" appcompat = "1.7.1" biometric = "1.4.0-alpha04" buildkonfigGradlePlugin = "0.17.1" +carApp = "1.7.0-rc01" coil = "3.3.0" colorpicker = "6b46b49bd5" conscryptAndroid = { strictly = "2.5.2" } # 2.5.3 crashes everything @@ -57,6 +58,7 @@ targetSdk = "36" activity-ktx = { module = "androidx.activity:activity-ktx", version.ref = "activityKtx" } appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" } biometric = { module = "androidx.biometric:biometric", version.ref = "biometric" } +car-app = { module = "androidx.car.app:app", version.ref = "carApp" } coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" } coil-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coil" } colorpicker = { module = "com.github.recloudstream:color-picker-android", version.ref = "colorpicker" } From 7a1d015e813df91b6494d24e79bca60a4a488967 Mon Sep 17 00:00:00 2001 From: Michele Granato Date: Sat, 10 Jan 2026 21:30:59 +0100 Subject: [PATCH 02/20] =?UTF-8?q?prova=20risoluzione=20problema=20navigazi?= =?UTF-8?q?one=20da=20android=20auto=20mentre=20l'auto=20=C3=A8=20in=20mov?= =?UTF-8?q?imento=20riducendo=20livelli=20di=20profondit=C3=A0=20(massimi?= =?UTF-8?q?=20consentiti=20sono=205)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - rimossa sezione libreria: voci di menu dirette (preferiti, cronologia) - cronologia e preferiti: per le serie tv ridotti step di navigazione. cronologia - titolo - lista episodi - play episodio - cambio approcio caricamento preferiti e cronologia per attesa caricamento --- app/build.gradle.kts | 2 +- .../cloudstream3/ui/car/BookmarksScreen.kt | 40 ++++++++-- .../cloudstream3/ui/car/EpisodeListScreen.kt | 29 ++++--- .../cloudstream3/ui/car/HistoryScreen.kt | 77 ++++++++++--------- .../cloudstream3/ui/car/MainCarScreen.kt | 16 +++- 5 files changed, 108 insertions(+), 56 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b2af926a198..49d05c3ea5a 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -63,7 +63,7 @@ android { minSdk = libs.versions.minSdk.get().toInt() targetSdk = libs.versions.targetSdk.get().toInt() versionCode = 67 - versionName = "4.6.1" + versionName = "4.6.2" resValue("string", "commit_hash", getGitCommitHash()) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt index 28155c40156..fdc180b30b1 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt @@ -14,6 +14,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import com.lagradost.cloudstream3.TvType import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import coil3.SingletonImageLoader import coil3.request.ImageRequest import coil3.asDrawable @@ -43,18 +44,47 @@ class BookmarksScreen(carContext: CarContext) : Screen(carContext) { .setOnClickListener { val type = item.type if (type == TvType.TvSeries || type == TvType.Anime || type == TvType.OVA) { - screenManager.push(TvSeriesDetailScreen(carContext, item)) + androidx.car.app.CarToast.makeText(carContext, "Caricamento episodi...", androidx.car.app.CarToast.LENGTH_SHORT).show() + CoroutineScope(Dispatchers.IO).launch { + val api = com.lagradost.cloudstream3.APIHolder.getApiFromNameNull(item.apiName) + if (api != null) { + val repo = com.lagradost.cloudstream3.ui.APIRepository(api) + when (val result = repo.load(item.url)) { + is com.lagradost.cloudstream3.mvvm.Resource.Success -> { + val data = result.value + kotlinx.coroutines.withContext(Dispatchers.Main) { + if (data is com.lagradost.cloudstream3.TvSeriesLoadResponse) { + screenManager.push(EpisodeListScreen(carContext, data, isExpressMode = true)) + } else { + screenManager.push(DetailsScreen(carContext, item)) + } + } + } + is com.lagradost.cloudstream3.mvvm.Resource.Failure -> { + kotlinx.coroutines.withContext(Dispatchers.Main) { + androidx.car.app.CarToast.makeText(carContext, "Errore: ${result.errorString}", androidx.car.app.CarToast.LENGTH_LONG).show() + } + } + else -> {} + } + } else { + kotlinx.coroutines.withContext(Dispatchers.Main) { + androidx.car.app.CarToast.makeText(carContext, "Provider non trovato", androidx.car.app.CarToast.LENGTH_SHORT).show() + } + } + } } else { screenManager.push(DetailsScreen(carContext, item)) } } - // .setImage(...) Removed as per user request .build() ) } - itemList = builder.build() - - invalidate() + val builtList = builder.build() + withContext(Dispatchers.Main) { + itemList = builtList + invalidate() + } // Async image loading removed } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeListScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeListScreen.kt index ab20c963024..1ee601ce35a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeListScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeListScreen.kt @@ -15,7 +15,8 @@ import com.lagradost.cloudstream3.R class EpisodeListScreen( carContext: CarContext, - private val details: TvSeriesLoadResponse + private val details: TvSeriesLoadResponse, + private val isExpressMode: Boolean = false ) : Screen(carContext) { private val availableSeasons: List = details.episodes.mapNotNull { it.season }.distinct().sorted() @@ -38,17 +39,27 @@ class EpisodeListScreen( seasonEpisodes.forEach { episode -> val title = "${episode.episode}. ${episode.name ?: "Episodio ${episode.episode}"}" val rowBuilder = Row.Builder() - .setTitle(title) .setTitle(title) .setOnClickListener { - screenManager.push( - EpisodeDetailScreen( - carContext = carContext, - seriesDetails = details, - episode = episode, - playlist = seasonEpisodes + if (isExpressMode) { + screenManager.push( + PlayerCarScreen( + carContext = carContext, + loadResponse = details, + selectedEpisode = episode, + playlist = seasonEpisodes + ) + ) + } else { + screenManager.push( + EpisodeDetailScreen( + carContext = carContext, + seriesDetails = details, + episode = episode, + playlist = seasonEpisodes + ) ) - ) + } } episode.description?.let { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt index c86811073b4..d96b8ab9c62 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt @@ -83,8 +83,11 @@ class HistoryScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc } } - itemList = builder.build() - invalidate() + val builtList = builder.build() + withContext(Dispatchers.Main) { + itemList = builtList + invalidate() + } } } @@ -102,46 +105,46 @@ class HistoryScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc else -> null } ?: return@launch - val startTime = getViewPos(resume.episodeId)?.position ?: 0L - - // Prepare SearchResponse item for PlayerCarScreen - val item: SearchResponse = if (cachedData.type.isMovieType()) { - api.newMovieSearchResponse( - name = cachedData.name, - url = cachedData.url, - type = cachedData.type, - ) { - this.posterUrl = cachedData.poster + if (loadResult is TvSeriesLoadResponse) { + withContext(Dispatchers.Main) { + screenManager.push(EpisodeListScreen(carContext, loadResult, isExpressMode = true)) } } else { - api.newTvSeriesSearchResponse( - name = cachedData.name, - url = cachedData.url, - type = cachedData.type, - ) { - this.posterUrl = cachedData.poster - } - } - - // Resolve Episode for TV Series - var selectedEpisode: com.lagradost.cloudstream3.Episode? = null - - if (loadResult is TvSeriesLoadResponse) { - selectedEpisode = loadResult.episodes.firstOrNull { - it.episode == resume.episode && it.season == resume.season + val startTime = getViewPos(resume.episodeId)?.position ?: 0L + + // Prepare SearchResponse item for PlayerCarScreen + val item: SearchResponse = if (cachedData.type.isMovieType()) { + api.newMovieSearchResponse( + name = cachedData.name, + url = cachedData.url, + type = cachedData.type, + ) { + this.posterUrl = cachedData.poster + } + } else { + api.newTvSeriesSearchResponse( + name = cachedData.name, + url = cachedData.url, + type = cachedData.type, + ) { + this.posterUrl = cachedData.poster + } } - } - withContext(Dispatchers.Main) { - screenManager.push( - PlayerCarScreen( - carContext = carContext, - item = item, - loadResponse = loadResult, - selectedEpisode = selectedEpisode, - startTime = startTime + // Resolve Episode for TV Series (Not needed if we skip player for series here, but kept for non-TvSeriesLoadResponse logic if any?) + // Actually, if it's NOT TvSeriesLoadResponse, selectedEpisode is likely null or irrelevant for Movie + + withContext(Dispatchers.Main) { + screenManager.push( + PlayerCarScreen( + carContext = carContext, + item = item, + loadResponse = loadResult, + selectedEpisode = null, // movies don't have episodes usually or logic differs + startTime = startTime + ) ) - ) + } } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt index 80475eb196d..91c700d7441 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt @@ -88,10 +88,18 @@ class MainCarScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc menuListBuilder.addItem( Row.Builder() - .setTitle("Libreria") - .addText("Preferiti, Cronologia") - .setImage(CarIcon.Builder(IconCompat.createWithResource(carContext, android.R.drawable.ic_menu_gallery)).build()) - .setOnClickListener { screenManager.push(LibraryCarScreen(carContext)) } + .setTitle("Preferiti") + .setImage(CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_baseline_favorite_24)).build()) + .setOnClickListener { screenManager.push(BookmarksScreen(carContext)) } + .setBrowsable(true) + .build() + ) + + menuListBuilder.addItem( + Row.Builder() + .setTitle("Cronologia") + .setImage(CarIcon.Builder(IconCompat.createWithResource(carContext, android.R.drawable.ic_menu_recent_history)).build()) + .setOnClickListener { screenManager.push(HistoryScreen(carContext)) } .setBrowsable(true) .build() ) From 7645d6e7abe7711dd4d6f4388f0ca85b1f25fc98 Mon Sep 17 00:00:00 2001 From: Michele Granato Date: Sun, 11 Jan 2026 10:25:55 +0100 Subject: [PATCH 03/20] ANDROID AUTO RC2 - introdotta sezione "Download" - cronologia e preferiti sono voci di menu principali - preferiti: salto rapido per serie tv (evito errore path lunghi per android auto) --- app/build.gradle.kts | 2 +- .../cloudstream3/ui/car/DownloadsScreen.kt | 153 ++++++++++++++++++ .../cloudstream3/ui/car/MainCarScreen.kt | 9 ++ .../cloudstream3/ui/car/PlayerCarScreen.kt | 17 +- 4 files changed, 176 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 49d05c3ea5a..a1cc0145de7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -63,7 +63,7 @@ android { minSdk = libs.versions.minSdk.get().toInt() targetSdk = libs.versions.targetSdk.get().toInt() versionCode = 67 - versionName = "4.6.2" + versionName = "4.6.3" resValue("string", "commit_hash", getGitCommitHash()) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt new file mode 100644 index 00000000000..0e9e5baf2c0 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt @@ -0,0 +1,153 @@ +package com.lagradost.cloudstream3.ui.car + +import androidx.car.app.CarContext +import androidx.car.app.Screen +import androidx.car.app.model.Action +import androidx.car.app.model.ItemList +import androidx.car.app.model.ListTemplate +import androidx.car.app.model.Row +import androidx.car.app.model.Template +import com.lagradost.cloudstream3.utils.VideoDownloadHelper +import com.lagradost.cloudstream3.utils.VideoDownloadManager +import com.lagradost.cloudstream3.utils.DataStore.getKey +import com.lagradost.cloudstream3.utils.DataStore.getKeys +import com.lagradost.cloudstream3.utils.DataStoreHelper +import com.lagradost.cloudstream3.utils.DOWNLOAD_HEADER_CACHE +import com.lagradost.cloudstream3.utils.DOWNLOAD_EPISODE_CACHE +import com.lagradost.cloudstream3.utils.DataStore.getFolderName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import com.lagradost.cloudstream3.isEpisodeBased + +class DownloadsScreen(carContext: CarContext) : Screen(carContext) { + private val scope = CoroutineScope(Dispatchers.IO) + private var itemList: ItemList? = null + + init { + loadDownloads() + } + + private fun loadDownloads() { + scope.launch { + val headers = carContext.getKeys(DOWNLOAD_HEADER_CACHE) + .mapNotNull { carContext.getKey(it) } + .sortedBy { it.name } + + val builder = ItemList.Builder() + + // Filter and find valid items + val validHeaders = headers.filter { header -> + val context = carContext + val id = header.id + + // Get all children (episodes or movies) for this header + val children = context.getKeys(DOWNLOAD_EPISODE_CACHE) + .mapNotNull { context.getKey(it) } + .filter { it.parentId == id } + + // Check if AT LEAST ONE child is valid (> 0 bytes) + children.any { child -> + val info = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(context, child.id) + (info?.fileLength ?: 0L) > 0 + } + } + + if (validHeaders.isEmpty()) { + builder.setNoItemsMessage("Nessun download completato trovato") + } else { + validHeaders.forEach { header -> + builder.addItem( + Row.Builder() + .setTitle(header.name) + .setOnClickListener { + playDownload(header) + } + .build() + ) + } + } + + val builtList = builder.build() + withContext(Dispatchers.Main) { + itemList = builtList + invalidate() + } + } + } + + private fun playDownload(header: VideoDownloadHelper.DownloadHeaderCached) { + scope.launch { + val context = carContext + val id = header.id + + // Logic to find THE BEST item to play (Resume or First) + + val children = context.getKeys(DOWNLOAD_EPISODE_CACHE) + .mapNotNull { context.getKey(it) } + .filter { it.parentId == id } + // Only consider valid downloads + .filter { + val info = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(context, it.id) + (info?.fileLength ?: 0L) > 0 + } + + if (children.isEmpty()) { + withContext(Dispatchers.Main) { + androidx.car.app.CarToast.makeText(carContext, "Nessun episodio valido trovato", androidx.car.app.CarToast.LENGTH_SHORT).show() + } + return@launch + } + + var episodeIdToPlay: Int? = null + + if (header.type.isEpisodeBased()) { + // Series: Check Resume + val lastWatched = DataStoreHelper.getLastWatched(id) + val lastEpisodeId = lastWatched?.episodeId + + // If last watched episode exists and is valid (downloaded), pick it + if (lastEpisodeId != null && children.any { it.id == lastEpisodeId }) { + episodeIdToPlay = lastEpisodeId + } else { + // Otherwise pick first sorted by season/episode + episodeIdToPlay = children.sortedWith(compareBy({ it.season }, { it.episode })).firstOrNull()?.id + } + } else { + // Movie: Just pick the first (and likely only) one + episodeIdToPlay = children.firstOrNull()?.id + } + + if (episodeIdToPlay == null) return@launch + + // Get file info + val fileInfo = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(context, episodeIdToPlay) + if (fileInfo?.path == null) { + withContext(Dispatchers.Main) { + androidx.car.app.CarToast.makeText(carContext, "File non trovato", androidx.car.app.CarToast.LENGTH_SHORT).show() + } + return@launch + } + + withContext(Dispatchers.Main) { + screenManager.push( + PlayerCarScreen( + carContext = carContext, + fileUri = fileInfo.path.toString(), + videoId = episodeIdToPlay, + parentId = header.id + ) + ) + } + } + } + + override fun onGetTemplate(): Template { + return ListTemplate.Builder() + .setTitle("Download") + .setHeaderAction(Action.BACK) + .setSingleList(itemList ?: ItemList.Builder().setNoItemsMessage("Caricamento...").build()) + .build() + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt index 91c700d7441..179e62ac8ba 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt @@ -104,6 +104,15 @@ class MainCarScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc .build() ) + menuListBuilder.addItem( + Row.Builder() + .setTitle("Download") + .setImage(CarIcon.Builder(IconCompat.createWithResource(carContext, android.R.drawable.stat_sys_download)).build()) + .setOnClickListener { screenManager.push(DownloadsScreen(carContext)) } + .setBrowsable(true) + .build() + ) + menuListBuilder.addItem( Row.Builder() .setTitle("Provider") diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt index 9a2548e6707..f06249d3f16 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt @@ -55,7 +55,10 @@ class PlayerCarScreen( val loadResponse: LoadResponse? = null, val selectedEpisode: Episode? = null, val playlist: List? = null, - val startTime: Long = 0L + val startTime: Long = 0L, + val fileUri: String? = null, + val videoId: Int? = null, + val parentId: Int? = null ) : Screen(carContext), SurfaceCallback { private val scope = CoroutineScope(Dispatchers.IO + Job()) @@ -95,6 +98,14 @@ class PlayerCarScreen( } } }) + + if (fileUri != null) { + currentEpisodeId = videoId + currentParentId = parentId + scope.launch { startPlayback(fileUri) } + } else { + loadMedia(item?.url) + } } override fun onSurfaceAvailable(surfaceContainer: SurfaceContainer) { @@ -454,7 +465,5 @@ class PlayerCarScreen( } } - init { - loadMedia(item?.url) - } + } From 976679b7c7ab4e36331c2345e405c06716a2901d Mon Sep 17 00:00:00 2001 From: Michele Granato Date: Sun, 11 Jan 2026 18:12:39 +0100 Subject: [PATCH 04/20] nuovo approccio per caricamento bookmarks e history (rimaneva scritta caricamento) --- app/build.gradle.kts | 2 +- .../cloudstream3/ui/car/BookmarksScreen.kt | 134 +++++++++++------- .../cloudstream3/ui/car/HistoryScreen.kt | 108 ++++++++------ 3 files changed, 147 insertions(+), 97 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a1cc0145de7..a195e598da4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -63,7 +63,7 @@ android { minSdk = libs.versions.minSdk.get().toInt() targetSdk = libs.versions.targetSdk.get().toInt() versionCode = 67 - versionName = "4.6.3" + versionName = "4.6.4" resValue("string", "commit_hash", getGitCommitHash()) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt index fdc180b30b1..d89a34b17db 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt @@ -15,84 +15,112 @@ import kotlinx.coroutines.Dispatchers import com.lagradost.cloudstream3.TvType import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import kotlinx.coroutines.delay import coil3.SingletonImageLoader import coil3.request.ImageRequest import coil3.asDrawable -class BookmarksScreen(carContext: CarContext) : Screen(carContext) { +class BookmarksScreen(carContext: CarContext) : Screen(carContext), androidx.lifecycle.DefaultLifecycleObserver { private var itemList: ItemList? = null init { + lifecycle.addObserver(this) + } + + override fun onStart(owner: androidx.lifecycle.LifecycleOwner) { loadBookmarks() } - private fun loadBookmarks() { + private fun loadBookmarks(retryCount: Int = 0) { CoroutineScope(Dispatchers.IO).launch { - // Fetch only Favorites (Heart icon) - val favorites = com.lagradost.cloudstream3.utils.DataStoreHelper.getAllFavorites() - .sortedByDescending { it.favoritesTime } - - val builder = ItemList.Builder() - if (favorites.isEmpty()) { - builder.setNoItemsMessage("No bookmarks (Favorites) found") + withContext(Dispatchers.Main) { + itemList = null + invalidate() } - - favorites.forEach { item -> - builder.addItem( - Row.Builder() - .setTitle(item.name) - .setOnClickListener { - val type = item.type - if (type == TvType.TvSeries || type == TvType.Anime || type == TvType.OVA) { - androidx.car.app.CarToast.makeText(carContext, "Caricamento episodi...", androidx.car.app.CarToast.LENGTH_SHORT).show() - CoroutineScope(Dispatchers.IO).launch { - val api = com.lagradost.cloudstream3.APIHolder.getApiFromNameNull(item.apiName) - if (api != null) { - val repo = com.lagradost.cloudstream3.ui.APIRepository(api) - when (val result = repo.load(item.url)) { - is com.lagradost.cloudstream3.mvvm.Resource.Success -> { - val data = result.value - kotlinx.coroutines.withContext(Dispatchers.Main) { - if (data is com.lagradost.cloudstream3.TvSeriesLoadResponse) { - screenManager.push(EpisodeListScreen(carContext, data, isExpressMode = true)) - } else { - screenManager.push(DetailsScreen(carContext, item)) + try { + // Fetch only Favorites (Heart icon) + val favorites = com.lagradost.cloudstream3.utils.DataStoreHelper.getAllFavorites() + .sortedByDescending { it.favoritesTime } + + val builder = ItemList.Builder() + if (favorites.isEmpty()) { + builder.setNoItemsMessage("Nessun preferito trovato") + } else { + favorites.forEach { item -> + builder.addItem( + Row.Builder() + .setTitle(item.name) + .setOnClickListener { + val type = item.type + if (type == TvType.TvSeries || type == TvType.Anime || type == TvType.OVA) { + androidx.car.app.CarToast.makeText(carContext, "Caricamento episodi...", androidx.car.app.CarToast.LENGTH_SHORT).show() + CoroutineScope(Dispatchers.IO).launch { + val api = com.lagradost.cloudstream3.APIHolder.getApiFromNameNull(item.apiName) + if (api != null) { + val repo = com.lagradost.cloudstream3.ui.APIRepository(api) + when (val result = repo.load(item.url)) { + is com.lagradost.cloudstream3.mvvm.Resource.Success -> { + val data = result.value + withContext(Dispatchers.Main) { + if (data is com.lagradost.cloudstream3.TvSeriesLoadResponse) { + screenManager.push(EpisodeListScreen(carContext, data, isExpressMode = true)) + } else { + screenManager.push(DetailsScreen(carContext, item)) + } + } + } + is com.lagradost.cloudstream3.mvvm.Resource.Failure -> { + withContext(Dispatchers.Main) { + androidx.car.app.CarToast.makeText(carContext, "Errore: ${result.errorString}", androidx.car.app.CarToast.LENGTH_LONG).show() + } } + else -> {} + } + } else { + withContext(Dispatchers.Main) { + androidx.car.app.CarToast.makeText(carContext, "Provider non trovato", androidx.car.app.CarToast.LENGTH_SHORT).show() } } - is com.lagradost.cloudstream3.mvvm.Resource.Failure -> { - kotlinx.coroutines.withContext(Dispatchers.Main) { - androidx.car.app.CarToast.makeText(carContext, "Errore: ${result.errorString}", androidx.car.app.CarToast.LENGTH_LONG).show() - } - } - else -> {} } } else { - kotlinx.coroutines.withContext(Dispatchers.Main) { - androidx.car.app.CarToast.makeText(carContext, "Provider non trovato", androidx.car.app.CarToast.LENGTH_SHORT).show() - } + screenManager.push(DetailsScreen(carContext, item)) } } - } else { - screenManager.push(DetailsScreen(carContext, item)) - } - } - .build() - ) - } - val builtList = builder.build() - withContext(Dispatchers.Main) { - itemList = builtList - invalidate() + .build() + ) + } + } + + val builtList = builder.build() + withContext(Dispatchers.Main) { + itemList = builtList + invalidate() + } + } catch (e: Exception) { + if (retryCount < 3) { + delay(3000) + loadBookmarks(retryCount + 1) + } else { + withContext(Dispatchers.Main) { + itemList = ItemList.Builder() + .addItem( + Row.Builder() + .setTitle("Errore: ${e.message}") + .setOnClickListener { loadBookmarks() } + .build() + ) + .build() + invalidate() + } + } } - // Async image loading removed } } override fun onGetTemplate(): Template { return ListTemplate.Builder() - .setSingleList(itemList ?: ItemList.Builder().setNoItemsMessage("Loading...").build()) - .setTitle("Bookmarks") + .setSingleList(itemList ?: ItemList.Builder().setNoItemsMessage("Caricamento preferiti...").build()) + .setTitle("Preferiti") .setHeaderAction(Action.BACK) .build() } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt index d96b8ab9c62..3f0b2c0a2cd 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt @@ -27,6 +27,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import kotlinx.coroutines.delay class HistoryScreen(carContext: CarContext) : Screen(carContext), DefaultLifecycleObserver { private val scope = CoroutineScope(Dispatchers.IO) @@ -40,54 +41,75 @@ class HistoryScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc loadHistory() } - private fun loadHistory() { + private fun loadHistory(retryCount: Int = 0) { scope.launch { - // Strict logic copied from HomeViewModel.getResumeWatching() - val resumeWatchingResult = withContext(Dispatchers.IO) { - getAllResumeStateIds()?.mapNotNull { id -> - getLastWatched(id) - }?.sortedBy { -it.updateTime }?.mapNotNull { resume -> - val data = getKey( - DOWNLOAD_HEADER_CACHE, - resume.parentId.toString() - ) ?: return@mapNotNull null - - // Mapping to a local helper or using the result directly - // We need the resume object for the episodeId/parentId/pos - Pair(resume, data) - } + withContext(Dispatchers.Main) { + itemList = null + invalidate() } - - val builder = ItemList.Builder() - - if (resumeWatchingResult.isNullOrEmpty()) { - builder.setNoItemsMessage("Nessun elemento 'Continua a guardare' trovato") - } else { - resumeWatchingResult.forEach { (resume, cachedData) -> - val title = cachedData.name - val subtitle = if (resume.episode != null && resume.season != null) { - "S${resume.season}:E${resume.episode}" - } else { - cachedData.apiName + try { + // Strict logic copied from HomeViewModel.getResumeWatching() + val resumeWatchingResult = withContext(Dispatchers.IO) { + getAllResumeStateIds()?.mapNotNull { id -> + getLastWatched(id) + }?.sortedBy { -it.updateTime }?.mapNotNull { resume -> + val data = getKey( + DOWNLOAD_HEADER_CACHE, + resume.parentId.toString() + ) ?: return@mapNotNull null + + Pair(resume, data) + } + } + + val builder = ItemList.Builder() + + if (resumeWatchingResult.isNullOrEmpty()) { + builder.setNoItemsMessage("Nessun elemento 'Continua a guardare' trovato") + } else { + resumeWatchingResult.forEach { (resume, cachedData) -> + val title = cachedData.name + val subtitle = if (resume.episode != null && resume.season != null) { + "S${resume.season}:E${resume.episode}" + } else { + cachedData.apiName + } + + builder.addItem( + Row.Builder() + .setTitle(title) + .addText(subtitle) + .setOnClickListener { + playResumeItem(resume, cachedData) + } + .build() + ) } - - builder.addItem( - Row.Builder() - .setTitle(title) - .addText(subtitle) - .setOnClickListener { - playResumeItem(resume, cachedData) - } - .build() - ) + } + + val builtList = builder.build() + withContext(Dispatchers.Main) { + itemList = builtList + invalidate() } + } catch (e: Exception) { + if (retryCount < 3) { + delay(3000) + loadHistory(retryCount + 1) + } else { + withContext(Dispatchers.Main) { + itemList = ItemList.Builder() + .addItem( + Row.Builder() + .setTitle("Errore: ${e.message}") + .setOnClickListener { loadHistory() } + .build() + ) + .build() + invalidate() + } + } } - - val builtList = builder.build() - withContext(Dispatchers.Main) { - itemList = builtList - invalidate() - } } } From 14659d717c5b71c188b155ae817e6d9183c9bafa Mon Sep 17 00:00:00 2001 From: Michele Granato Date: Tue, 13 Jan 2026 20:10:35 +0100 Subject: [PATCH 05/20] android auto RC3 -fix resume film scaricato --- app/build.gradle.kts | 2 +- .../com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a195e598da4..645e1cb7cf5 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -63,7 +63,7 @@ android { minSdk = libs.versions.minSdk.get().toInt() targetSdk = libs.versions.targetSdk.get().toInt() versionCode = 67 - versionName = "4.6.4" + versionName = "4.6.5" resValue("string", "commit_hash", getGitCommitHash()) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt index 0e9e5baf2c0..05af2949ca5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt @@ -130,13 +130,18 @@ class DownloadsScreen(carContext: CarContext) : Screen(carContext) { return@launch } + // Get saved resume position + val savedPos = DataStoreHelper.getViewPos(episodeIdToPlay) + val startTime = savedPos?.position ?: 0L + withContext(Dispatchers.Main) { screenManager.push( PlayerCarScreen( carContext = carContext, fileUri = fileInfo.path.toString(), videoId = episodeIdToPlay, - parentId = header.id + parentId = header.id, + startTime = startTime ) ) } From 65814baca2790819c7db120fa8afa3bcdeb8a9b0 Mon Sep 17 00:00:00 2001 From: Michele Granato Date: Wed, 14 Jan 2026 11:35:51 +0100 Subject: [PATCH 06/20] -fix messaggio errore stilizzazione icone -rimosso tasto play/pausa da menu riproduzione --- app/build.gradle.kts | 2 +- .../java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt | 1 - app/src/main/res/drawable/go_back_30.xml | 2 +- app/src/main/res/drawable/go_forward_30.xml | 2 +- app/src/main/res/drawable/ic_baseline_arrow_back_24.xml | 2 +- app/src/main/res/drawable/ic_baseline_aspect_ratio_24.xml | 2 +- app/src/main/res/drawable/ic_baseline_play_arrow_24.xml | 2 +- app/src/main/res/drawable/ic_baseline_tune_24.xml | 2 +- 8 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 645e1cb7cf5..49cb55686f8 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -63,7 +63,7 @@ android { minSdk = libs.versions.minSdk.get().toInt() targetSdk = libs.versions.targetSdk.get().toInt() versionCode = 67 - versionName = "4.6.5" + versionName = "4.6.6" resValue("string", "commit_hash", getGitCommitHash()) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt index f06249d3f16..267d12295db 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt @@ -391,7 +391,6 @@ class PlayerCarScreen( actionStripBuilder.addAction(backToMenuAction) .addAction(seekBackAction) - .addAction(playPauseAction) .addAction(seekForwardAction) } else { diff --git a/app/src/main/res/drawable/go_back_30.xml b/app/src/main/res/drawable/go_back_30.xml index 14999011662..8202d3ce42c 100644 --- a/app/src/main/res/drawable/go_back_30.xml +++ b/app/src/main/res/drawable/go_back_30.xml @@ -1,7 +1,7 @@ diff --git a/app/src/main/res/drawable/ic_baseline_aspect_ratio_24.xml b/app/src/main/res/drawable/ic_baseline_aspect_ratio_24.xml index d93d1b64b91..c7b8b5f55fb 100644 --- a/app/src/main/res/drawable/ic_baseline_aspect_ratio_24.xml +++ b/app/src/main/res/drawable/ic_baseline_aspect_ratio_24.xml @@ -1,4 +1,4 @@ - diff --git a/app/src/main/res/drawable/ic_baseline_play_arrow_24.xml b/app/src/main/res/drawable/ic_baseline_play_arrow_24.xml index f880379f0bb..0870be8f615 100644 --- a/app/src/main/res/drawable/ic_baseline_play_arrow_24.xml +++ b/app/src/main/res/drawable/ic_baseline_play_arrow_24.xml @@ -1,4 +1,4 @@ - diff --git a/app/src/main/res/drawable/ic_baseline_tune_24.xml b/app/src/main/res/drawable/ic_baseline_tune_24.xml index d0c63a3d17d..0342fb06ea8 100644 --- a/app/src/main/res/drawable/ic_baseline_tune_24.xml +++ b/app/src/main/res/drawable/ic_baseline_tune_24.xml @@ -2,7 +2,7 @@ android:height="24dp" android:viewportWidth="48" android:viewportHeight="48" - android:tint="?attr/white" + android:tint="#FFFFFF" xmlns:android="http://schemas.android.com/apk/res/android"> From b42a36977904eea151374012bd61b4f61b187019 Mon Sep 17 00:00:00 2001 From: Michele Granato Date: Wed, 14 Jan 2026 17:15:48 +0100 Subject: [PATCH 07/20] ANDROID AUTO RC4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - resume per serie tv da cronologia / download - elenco in download degli episodi per serie tv - workaround per contenuto erroneamente classificato come film (ma è una serie tv) - forzatura screenManager con rimozione dallo stack di navigazione della scheda film erroneamente caricata --- app/build.gradle.kts | 2 +- .../cloudstream3/ui/car/BookmarksScreen.kt | 37 +--- .../cloudstream3/ui/car/DetailsScreen.kt | 34 ++++ .../cloudstream3/ui/car/DownloadsScreen.kt | 168 ++++++++++++------ .../ui/car/EpisodeDetailScreen.kt | 6 +- .../cloudstream3/ui/car/EpisodeListScreen.kt | 6 +- .../cloudstream3/ui/car/HistoryScreen.kt | 48 +++-- .../cloudstream3/ui/car/PlayerCarScreen.kt | 51 +++++- .../cloudstream3/ui/car/SearchCarScreen.kt | 14 +- 9 files changed, 256 insertions(+), 110 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 49cb55686f8..497e92f3d79 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -63,7 +63,7 @@ android { minSdk = libs.versions.minSdk.get().toInt() targetSdk = libs.versions.targetSdk.get().toInt() versionCode = 67 - versionName = "4.6.6" + versionName = "4.6.8" resValue("string", "commit_hash", getGitCommitHash()) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt index d89a34b17db..fc9ec68a967 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt @@ -52,36 +52,13 @@ class BookmarksScreen(carContext: CarContext) : Screen(carContext), androidx.lif .setTitle(item.name) .setOnClickListener { val type = item.type - if (type == TvType.TvSeries || type == TvType.Anime || type == TvType.OVA) { - androidx.car.app.CarToast.makeText(carContext, "Caricamento episodi...", androidx.car.app.CarToast.LENGTH_SHORT).show() - CoroutineScope(Dispatchers.IO).launch { - val api = com.lagradost.cloudstream3.APIHolder.getApiFromNameNull(item.apiName) - if (api != null) { - val repo = com.lagradost.cloudstream3.ui.APIRepository(api) - when (val result = repo.load(item.url)) { - is com.lagradost.cloudstream3.mvvm.Resource.Success -> { - val data = result.value - withContext(Dispatchers.Main) { - if (data is com.lagradost.cloudstream3.TvSeriesLoadResponse) { - screenManager.push(EpisodeListScreen(carContext, data, isExpressMode = true)) - } else { - screenManager.push(DetailsScreen(carContext, item)) - } - } - } - is com.lagradost.cloudstream3.mvvm.Resource.Failure -> { - withContext(Dispatchers.Main) { - androidx.car.app.CarToast.makeText(carContext, "Errore: ${result.errorString}", androidx.car.app.CarToast.LENGTH_LONG).show() - } - } - else -> {} - } - } else { - withContext(Dispatchers.Main) { - androidx.car.app.CarToast.makeText(carContext, "Provider non trovato", androidx.car.app.CarToast.LENGTH_SHORT).show() - } - } - } + if (type == TvType.TvSeries || + type == TvType.Anime || + type == TvType.Cartoon || + type == TvType.OVA || + type == TvType.AsianDrama || + type == TvType.Documentary) { + screenManager.push(TvSeriesDetailScreen(carContext, item)) } else { screenManager.push(DetailsScreen(carContext, item)) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/DetailsScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/DetailsScreen.kt index b612a00a8c5..132c5605c1f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/DetailsScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/DetailsScreen.kt @@ -9,9 +9,13 @@ import androidx.car.app.model.PaneTemplate import androidx.car.app.model.Row import androidx.car.app.model.Template import com.lagradost.cloudstream3.SearchResponse +import com.lagradost.cloudstream3.TvSeriesLoadResponse +import com.lagradost.cloudstream3.TvType +import com.lagradost.cloudstream3.newTvSeriesSearchResponse import com.lagradost.cloudstream3.ui.player.DownloadedPlayerActivity import android.content.Intent import android.net.Uri +import android.util.Log import android.text.SpannableString import android.text.Spanned import androidx.car.app.model.CarIcon @@ -77,6 +81,36 @@ class DetailsScreen( when (val result = repo.load(item.url)) { is Resource.Success -> { fullDetails = result.value + + // Redirect if Type Mismatch (e.g. Provider reported Movie, but it's a Series) + // We check if the response is structurally a Series (has episodes etc) + // This fixes providers that return "Movie" type but provide series data. + if (result.value is TvSeriesLoadResponse) { + val detectedType = result.value.type + // If the provider says "Movie" but sends TvSeriesLoadResponse, force TvSeries type + val isTv = detectedType == TvType.TvSeries || + detectedType == TvType.Anime || + detectedType == TvType.Cartoon || + detectedType == TvType.OVA || + detectedType == TvType.AsianDrama || + detectedType == TvType.Documentary + + val finalType = if (isTv) detectedType else TvType.TvSeries + + val correctItem = api.newTvSeriesSearchResponse( + name = result.value.name, + url = result.value.url, + type = finalType, + ) { + this.posterUrl = result.value.posterUrl ?: item.posterUrl + } + withContext(Dispatchers.Main) { + screenManager.pop() + screenManager.push(TvSeriesDetailScreen(carContext, correctItem)) + } + return@launch + } + // Check ID logic matches standard val id = result.value.url.replace(api.mainUrl, "").replace("/", "").hashCode() isFavorite = DataStoreHelper.getFavoritesData(id) != null diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt index 05af2949ca5..405fc27367b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt @@ -21,15 +21,65 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import com.lagradost.cloudstream3.isEpisodeBased -class DownloadsScreen(carContext: CarContext) : Screen(carContext) { +class DownloadsScreen( + carContext: CarContext, + private val parentId: Int? = null, + private val headerName: String? = null +) : Screen(carContext) { private val scope = CoroutineScope(Dispatchers.IO) private var itemList: ItemList? = null init { - loadDownloads() + loadContent() } - private fun loadDownloads() { + private fun loadContent() { + if (parentId != null) { + loadEpisodes(parentId) + } else { + loadHeaders() + } + } + + private fun loadEpisodes(id: Int) { + scope.launch { + val context = carContext + val children = context.getKeys(DOWNLOAD_EPISODE_CACHE) + .mapNotNull { context.getKey(it) } + .filter { it.parentId == id } + .filter { + val info = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(context, it.id) + (info?.fileLength ?: 0L) > 0 + } + .sortedWith(compareBy({ it.season }, { it.episode })) + + val builder = ItemList.Builder() + + if (children.isEmpty()) { + builder.setNoItemsMessage("Nessun episodio trovato") + } else { + children.forEach { episode -> + val name = "S${episode.season}:E${episode.episode} - ${episode.name ?: "Episodio"}" + builder.addItem( + Row.Builder() + .setTitle(name) + .setOnClickListener { + playEpisode(episode.id, id) + } + .build() + ) + } + } + + val builtList = builder.build() + withContext(Dispatchers.Main) { + itemList = builtList + invalidate() + } + } + } + + private fun loadHeaders() { scope.launch { val headers = carContext.getKeys(DOWNLOAD_HEADER_CACHE) .mapNotNull { carContext.getKey(it) } @@ -58,14 +108,24 @@ class DownloadsScreen(carContext: CarContext) : Screen(carContext) { builder.setNoItemsMessage("Nessun download completato trovato") } else { validHeaders.forEach { header -> - builder.addItem( - Row.Builder() - .setTitle(header.name) - .setOnClickListener { - playDownload(header) - } - .build() - ) + val lastWatched = DataStoreHelper.getLastWatched(header.id) + val subtitle = if (lastWatched != null && lastWatched.season != null && lastWatched.episode != null) { + "S${lastWatched.season}E${lastWatched.episode}" + } else { + null + } + + val rowBuilder = Row.Builder() + .setTitle(header.name) + .setOnClickListener { + onHeaderClick(header) + } + + if (subtitle != null) { + rowBuilder.addText(subtitle) + } + + builder.addItem(rowBuilder.build()) } } @@ -77,17 +137,44 @@ class DownloadsScreen(carContext: CarContext) : Screen(carContext) { } } - private fun playDownload(header: VideoDownloadHelper.DownloadHeaderCached) { + private fun playEpisode(episodeId: Int, parentId: Int) { + scope.launch { + val context = carContext + val fileInfo = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(context, episodeId) + if (fileInfo?.path == null) { + withContext(Dispatchers.Main) { + androidx.car.app.CarToast.makeText(carContext, "File non trovato", androidx.car.app.CarToast.LENGTH_SHORT).show() + } + return@launch + } + + // Get saved resume position + val savedPos = DataStoreHelper.getViewPos(episodeId) + val startTime = savedPos?.position ?: 0L + + withContext(Dispatchers.Main) { + screenManager.push( + PlayerCarScreen( + carContext = carContext, + fileUri = fileInfo.path.toString(), + videoId = episodeId, + parentId = parentId, + startTime = startTime + ) + ) + } + } + } + + private fun onHeaderClick(header: VideoDownloadHelper.DownloadHeaderCached) { scope.launch { val context = carContext val id = header.id - // Logic to find THE BEST item to play (Resume or First) - + // Get children val children = context.getKeys(DOWNLOAD_EPISODE_CACHE) .mapNotNull { context.getKey(it) } .filter { it.parentId == id } - // Only consider valid downloads .filter { val info = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(context, it.id) (info?.fileLength ?: 0L) > 0 @@ -100,59 +187,26 @@ class DownloadsScreen(carContext: CarContext) : Screen(carContext) { return@launch } - var episodeIdToPlay: Int? = null - if (header.type.isEpisodeBased()) { - // Series: Check Resume - val lastWatched = DataStoreHelper.getLastWatched(id) - val lastEpisodeId = lastWatched?.episodeId - - // If last watched episode exists and is valid (downloaded), pick it - if (lastEpisodeId != null && children.any { it.id == lastEpisodeId }) { - episodeIdToPlay = lastEpisodeId - } else { - // Otherwise pick first sorted by season/episode - episodeIdToPlay = children.sortedWith(compareBy({ it.season }, { it.episode })).firstOrNull()?.id + // Series: Always go to episode list + withContext(Dispatchers.Main) { + screenManager.push(DownloadsScreen(carContext, id, header.name)) } } else { - // Movie: Just pick the first (and likely only) one - episodeIdToPlay = children.firstOrNull()?.id - } - - if (episodeIdToPlay == null) return@launch - - // Get file info - val fileInfo = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(context, episodeIdToPlay) - if (fileInfo?.path == null) { - withContext(Dispatchers.Main) { - androidx.car.app.CarToast.makeText(carContext, "File non trovato", androidx.car.app.CarToast.LENGTH_SHORT).show() + // Movie: Just pick the first/only one + val episodeId = children.firstOrNull()?.id + if (episodeId != null) { + playEpisode(episodeId, id) } - return@launch - } - - // Get saved resume position - val savedPos = DataStoreHelper.getViewPos(episodeIdToPlay) - val startTime = savedPos?.position ?: 0L - - withContext(Dispatchers.Main) { - screenManager.push( - PlayerCarScreen( - carContext = carContext, - fileUri = fileInfo.path.toString(), - videoId = episodeIdToPlay, - parentId = header.id, - startTime = startTime - ) - ) } } } override fun onGetTemplate(): Template { return ListTemplate.Builder() - .setTitle("Download") + .setTitle(headerName ?: "Download") .setHeaderAction(Action.BACK) - .setSingleList(itemList ?: ItemList.Builder().setNoItemsMessage("Caricamento...").build()) + .setSingleList(itemList ?: ItemList.Builder().setNoItemsMessage(if (headerName == null) "Caricamento download..." else "Caricamento episodi...").build()) .build() } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeDetailScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeDetailScreen.kt index 3d65749d5ee..a00ecfee66a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeDetailScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeDetailScreen.kt @@ -17,6 +17,7 @@ import coil3.SingletonImageLoader import com.lagradost.cloudstream3.Episode import com.lagradost.cloudstream3.TvSeriesLoadResponse import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -96,12 +97,15 @@ class EpisodeDetailScreen( .setIcon(CarIcon.Builder(playIcon).build()) .setBackgroundColor(CarColor.createCustom(android.graphics.Color.WHITE, android.graphics.Color.WHITE)) .setOnClickListener { + // Get saved position for resume + val startTime = getViewPos(episode.data.hashCode())?.position ?: 0L screenManager.push( PlayerCarScreen( carContext = carContext, loadResponse = seriesDetails, selectedEpisode = episode, - playlist = playlist + playlist = playlist, + startTime = startTime ) ) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeListScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeListScreen.kt index 1ee601ce35a..3d1a4905da4 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeListScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeListScreen.kt @@ -12,6 +12,7 @@ import androidx.car.app.model.Template import androidx.core.graphics.drawable.IconCompat import com.lagradost.cloudstream3.TvSeriesLoadResponse import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos class EpisodeListScreen( carContext: CarContext, @@ -42,12 +43,15 @@ class EpisodeListScreen( .setTitle(title) .setOnClickListener { if (isExpressMode) { + // Get saved position for resume + val startTime = getViewPos(episode.data.hashCode())?.position ?: 0L screenManager.push( PlayerCarScreen( carContext = carContext, loadResponse = details, selectedEpisode = episode, - playlist = seasonEpisodes + playlist = seasonEpisodes, + startTime = startTime ) ) } else { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt index 3f0b2c0a2cd..2aecc3a37b2 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt @@ -69,11 +69,11 @@ class HistoryScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc } else { resumeWatchingResult.forEach { (resume, cachedData) -> val title = cachedData.name - val subtitle = if (resume.episode != null && resume.season != null) { - "S${resume.season}:E${resume.episode}" - } else { - cachedData.apiName - } + val subtitle = if (resume.episode != null && resume.season != null) { + "S${resume.season}E${resume.episode} (${cachedData.apiName})" + } else { + cachedData.apiName + } builder.addItem( Row.Builder() @@ -128,8 +128,37 @@ class HistoryScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc } ?: return@launch if (loadResult is TvSeriesLoadResponse) { - withContext(Dispatchers.Main) { - screenManager.push(EpisodeListScreen(carContext, loadResult, isExpressMode = true)) + // Find the specific episode to resume + // resume.episodeId should match episode.data.hashCode() used by PlayerCarScreen + val episodeToResume = loadResult.episodes.find { episode -> + // Promiscuous check: try multiple ways to match the episode + // Note: Episode class does not have an 'id' field, so we skip direct ID check + val urlHashMatch = episode.data.hashCode() == resume.episodeId + val numberMatch = (episode.episode == resume.episode && episode.season == resume.season) + + urlHashMatch || numberMatch + } + + if (episodeToResume != null) { + val startTime = getViewPos(resume.episodeId)?.position ?: 0L + val seasonEpisodes = loadResult.episodes.filter { it.season == episodeToResume.season } + + withContext(Dispatchers.Main) { + screenManager.push( + PlayerCarScreen( + carContext = carContext, + loadResponse = loadResult, + selectedEpisode = episodeToResume, + playlist = seasonEpisodes, + startTime = startTime + ) + ) + } + } else { + // Fallback to episode list if episode not found + withContext(Dispatchers.Main) { + screenManager.push(EpisodeListScreen(carContext, loadResult, isExpressMode = true)) + } } } else { val startTime = getViewPos(resume.episodeId)?.position ?: 0L @@ -152,9 +181,6 @@ class HistoryScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc this.posterUrl = cachedData.poster } } - - // Resolve Episode for TV Series (Not needed if we skip player for series here, but kept for non-TvSeriesLoadResponse logic if any?) - // Actually, if it's NOT TvSeriesLoadResponse, selectedEpisode is likely null or irrelevant for Movie withContext(Dispatchers.Main) { screenManager.push( @@ -162,7 +188,7 @@ class HistoryScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc carContext = carContext, item = item, loadResponse = loadResult, - selectedEpisode = null, // movies don't have episodes usually or logic differs + selectedEpisode = null, startTime = startTime ) ) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt index 267d12295db..7bff0f29d3e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt @@ -38,9 +38,13 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import android.util.Log +import com.lagradost.cloudstream3.utils.DataStore +import com.lagradost.cloudstream3.utils.DataStore.getKey +import com.lagradost.cloudstream3.utils.VideoDownloadHelper +import com.lagradost.cloudstream3.utils.DOWNLOAD_EPISODE_CACHE +import com.lagradost.cloudstream3.Episode import com.lagradost.cloudstream3.LoadResponse -import com.lagradost.cloudstream3.Episode import com.lagradost.cloudstream3.TvSeriesLoadResponse import com.lagradost.cloudstream3.AnimeLoadResponse import com.lagradost.cloudstream3.MovieLoadResponse @@ -61,6 +65,7 @@ class PlayerCarScreen( val parentId: Int? = null ) : Screen(carContext), SurfaceCallback { + private var activeEpisode: Episode? = selectedEpisode private val scope = CoroutineScope(Dispatchers.IO + Job()) private var player: ExoPlayer? = null private var surface: Surface? = null @@ -102,7 +107,37 @@ class PlayerCarScreen( if (fileUri != null) { currentEpisodeId = videoId currentParentId = parentId - scope.launch { startPlayback(fileUri) } + + // Fix: Populate selectedEpisode metadata for Downloads so saveProgress works correctly + if (this.activeEpisode == null) { + scope.launch(Dispatchers.IO) { + try { + val cachedEp = carContext.getKey( + DOWNLOAD_EPISODE_CACHE, + videoId.toString() + ) + if (cachedEp != null) { + @Suppress("DEPRECATION_ERROR") + val ep = Episode( + data = "", // URL not available in cache, but ID is used from videoId so acceptable + name = cachedEp.name, + season = cachedEp.season, + episode = cachedEp.episode, + posterUrl = cachedEp.poster + ) + this@PlayerCarScreen.activeEpisode = ep + Log.d("PlayerCarScreen", "Populated activeEpisode from Download: S${cachedEp.season} E${cachedEp.episode}") + } + } catch (e: Exception) { + Log.e("PlayerCarScreen", "Error loading download metadata", e) + } + withContext(Dispatchers.Main) { + startPlayback(fileUri) + } + } + } else { + scope.launch { startPlayback(fileUri) } + } } else { loadMedia(item?.url) } @@ -151,7 +186,7 @@ class PlayerCarScreen( val links = mutableListOf() try { val urlToLoad = when { - selectedEpisode != null -> selectedEpisode.data + activeEpisode != null -> activeEpisode!!.data data is com.lagradost.cloudstream3.TvSeriesLoadResponse -> { // Auto-select first episode if none selected data.episodes.firstOrNull()?.data @@ -197,15 +232,15 @@ class PlayerCarScreen( // 2. Data URL Hashcode (using strict cleaning logic) currentParentId = item?.id ?: idFromUrl - if (data is TvSeriesLoadResponse && selectedEpisode != null) { + if (data is TvSeriesLoadResponse && activeEpisode != null) { // Episode doesn't have an ID property, so we use the data (url) hashcode // Note: Episodes might not use the mainUrl cleanup in the same way, but usually depend on their own data string. // In PlayerGeneratorViewModel/RepoLinkGenerator, episodes use 'current.id' which comes from ResultEpisode. // ResultEpisode is built using 'id' from LoadResponse. // So we should apply the same cleaning to episode data if it's a URL. - // However, selectedEpisode.data is usually the direct link. + // However, activeEpisode.data is usually the direct link. // Let's stick to .hashCode() of the data string for episodes as a reasonable unique key if explicit ID is known to be missing. - currentEpisodeId = selectedEpisode.data.hashCode() + currentEpisodeId = activeEpisode!!.data.hashCode() } else { // For movies, we use the parent ID currentEpisodeId = currentParentId @@ -245,8 +280,8 @@ class PlayerCarScreen( Log.d("PlayerCarScreen", "Removed Last Watched (Finished)") } else { // Update resume state - val epNum = selectedEpisode?.episode - val seasonNum = selectedEpisode?.season + val epNum = activeEpisode?.episode + val seasonNum = activeEpisode?.season DataStoreHelper.setLastWatched( parentId = currentParentId, diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/SearchCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/SearchCarScreen.kt index b97f24a0232..7f198e4c733 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/SearchCarScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/SearchCarScreen.kt @@ -58,7 +58,19 @@ class SearchCarScreen(carContext: CarContext) : Screen(carContext) { builder.addItem( Row.Builder() .setTitle(item.name) - .setOnClickListener { screenManager.push(DetailsScreen(carContext, item)) } + .setOnClickListener { + val type = item.type + if (type == com.lagradost.cloudstream3.TvType.TvSeries || + type == com.lagradost.cloudstream3.TvType.Anime || + type == com.lagradost.cloudstream3.TvType.Cartoon || + type == com.lagradost.cloudstream3.TvType.OVA || + type == com.lagradost.cloudstream3.TvType.AsianDrama || + type == com.lagradost.cloudstream3.TvType.Documentary) { + screenManager.push(TvSeriesDetailScreen(carContext, item)) + } else { + screenManager.push(DetailsScreen(carContext, item)) + } + } .build() ) } From f337a6b7dbf71b6fd7e04df9b263702032888ef1 Mon Sep 17 00:00:00 2001 From: Michele Granato Date: Thu, 15 Jan 2026 11:28:02 +0100 Subject: [PATCH 08/20] ANDROID AUTO RC5 - aggiunta selezione sorgente stream (rimpiazza icona preferiti - vincolo max 2 tasti) --- app/build.gradle.kts | 2 +- .../cloudstream3/ui/car/DetailsScreen.kt | 56 ++++++-- .../ui/car/EpisodeDetailScreen.kt | 38 ++++- .../cloudstream3/ui/car/PlayerCarScreen.kt | 26 ++-- .../ui/car/SourceSelectionScreen.kt | 132 ++++++++++++++++++ .../res/drawable/ic_baseline_source_24.xml | 10 ++ 6 files changed, 237 insertions(+), 27 deletions(-) create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/SourceSelectionScreen.kt create mode 100644 app/src/main/res/drawable/ic_baseline_source_24.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 497e92f3d79..28161875777 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -63,7 +63,7 @@ android { minSdk = libs.versions.minSdk.get().toInt() targetSdk = libs.versions.targetSdk.get().toInt() versionCode = 67 - versionName = "4.6.8" + versionName = "4.6.9" resValue("string", "commit_hash", getGitCommitHash()) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/DetailsScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/DetailsScreen.kt index 132c5605c1f..298e5b2d0d1 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/DetailsScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/DetailsScreen.kt @@ -38,6 +38,8 @@ import com.lagradost.cloudstream3.ui.APIRepository import com.lagradost.cloudstream3.utils.DataStoreHelper import com.lagradost.cloudstream3.ui.result.ResultViewModel2 import com.lagradost.cloudstream3.utils.DataStoreHelper.FavoritesData +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.MovieLoadResponse class DetailsScreen( carContext: CarContext, @@ -51,6 +53,9 @@ class DetailsScreen( private var posterBitmap: android.graphics.Bitmap? = null private var isFavorite: Boolean = false private val scope = CoroutineScope(Dispatchers.IO + Job()) + + // Selected source for playback + private var selectedSource: ExtractorLink? = null init { loadData() @@ -222,36 +227,59 @@ class DetailsScreen( } } - // Play Button: White background (simulated/requested) with Black Icon + // Play Button: White background with Black Icon val playIcon = IconCompat.createWithResource(carContext, android.R.drawable.ic_media_play) .setTint(android.graphics.Color.BLACK) val playAction = Action.Builder() .setIcon(CarIcon.Builder(playIcon).build()) - //.setTitle("Play") // No title as requested .setBackgroundColor(CarColor.createCustom(android.graphics.Color.WHITE, android.graphics.Color.WHITE)) .setOnClickListener { - screenManager.push(PlayerCarScreen(carContext, item)) + screenManager.push(PlayerCarScreen( + carContext = carContext, + item = item, + preSelectedSource = selectedSource + )) } .build() - - val favoriteIconRes = if (isFavorite) R.drawable.ic_baseline_favorite_24 else R.drawable.ic_baseline_favorite_border_24 - val favoriteIcon = IconCompat.createWithResource(carContext, favoriteIconRes) - if (isFavorite) { - favoriteIcon.setTint(0xFFFF0000.toInt()) // Red + + // Source Selection Button + val sourceIcon = IconCompat.createWithResource(carContext, R.drawable.ic_baseline_source_24) + + val sourceActionTitle = if (selectedSource != null) { + selectedSource!!.name } else { - favoriteIcon.setTint(android.graphics.Color.WHITE) // White + "Sorgente" } - - val favoriteAction = Action.Builder() - .setIcon(CarIcon.Builder(favoriteIcon).build()) + + val sourceAction = Action.Builder() + .setIcon(CarIcon.Builder(sourceIcon).build()) + .setTitle(sourceActionTitle) .setOnClickListener { - toggleFavorite() + val details = fullDetails + val dataUrl = when (details) { + is MovieLoadResponse -> details.dataUrl + else -> details?.url + } + if (dataUrl != null && details != null) { + screenManager.push( + SourceSelectionScreen( + carContext = carContext, + apiName = details.apiName, + dataUrl = dataUrl, + currentSourceUrl = selectedSource?.url, + onSourceSelected = { source -> + selectedSource = source + invalidate() + } + ) + ) + } } .build() paneBuilder.addAction(playAction) - paneBuilder.addAction(favoriteAction) + paneBuilder.addAction(sourceAction) return PaneTemplate.Builder(paneBuilder.build()) .setTitle(fullDetails?.name ?: item.name) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeDetailScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeDetailScreen.kt index a00ecfee66a..6e54eb62a73 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeDetailScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeDetailScreen.kt @@ -18,6 +18,7 @@ import com.lagradost.cloudstream3.Episode import com.lagradost.cloudstream3.TvSeriesLoadResponse import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos +import com.lagradost.cloudstream3.utils.ExtractorLink import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -33,6 +34,9 @@ class EpisodeDetailScreen( private val scope = CoroutineScope(Dispatchers.IO + Job()) private var posterBitmap: android.graphics.Bitmap? = null private var isLoadingImage = true + + // Selected source for playback + private var selectedSource: ExtractorLink? = null init { loadImage() @@ -89,7 +93,7 @@ class EpisodeDetailScreen( ) } - // Play Button actions + // Play Button action val playIcon = IconCompat.createWithResource(carContext, android.R.drawable.ic_media_play) .setTint(android.graphics.Color.BLACK) @@ -105,13 +109,43 @@ class EpisodeDetailScreen( loadResponse = seriesDetails, selectedEpisode = episode, playlist = playlist, - startTime = startTime + startTime = startTime, + preSelectedSource = selectedSource + ) + ) + } + .build() + + // Source Selection Button + val sourceIcon = IconCompat.createWithResource(carContext, R.drawable.ic_baseline_source_24) + + val sourceActionTitle = if (selectedSource != null) { + selectedSource!!.name + } else { + "Sorgente" + } + + val sourceAction = Action.Builder() + .setIcon(CarIcon.Builder(sourceIcon).build()) + .setTitle(sourceActionTitle) + .setOnClickListener { + screenManager.push( + SourceSelectionScreen( + carContext = carContext, + apiName = seriesDetails.apiName, + dataUrl = episode.data, + currentSourceUrl = selectedSource?.url, + onSourceSelected = { source -> + selectedSource = source + invalidate() + } ) ) } .build() paneBuilder.addAction(playAction) + paneBuilder.addAction(sourceAction) return PaneTemplate.Builder(paneBuilder.build()) .setTitle(seriesDetails.name) // Header Title is Series Name diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt index 7bff0f29d3e..16cb9463586 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt @@ -62,7 +62,8 @@ class PlayerCarScreen( val startTime: Long = 0L, val fileUri: String? = null, val videoId: Int? = null, - val parentId: Int? = null + val parentId: Int? = null, + val preSelectedSource: ExtractorLink? = null ) : Screen(carContext), SurfaceCallback { private var activeEpisode: Episode? = selectedEpisode @@ -206,16 +207,21 @@ class PlayerCarScreen( return@launch } - // Load links using the API - val success = api.loadLinks(urlToLoad, false, {}, { link -> - links.add(link) - }) - - if(links.isNotEmpty()) { - val bestLink = links.sortedByDescending { it.quality }.first() - startPlayback(bestLink) + // Use pre-selected source if provided, otherwise load and auto-select best + if (preSelectedSource != null) { + startPlayback(preSelectedSource) } else { - showToast("Nessun link trovato") + // Load links using the API + val success = api.loadLinks(urlToLoad, false, {}, { link -> + links.add(link) + }) + + if(links.isNotEmpty()) { + val bestLink = links.sortedByDescending { it.quality }.first() + startPlayback(bestLink) + } else { + showToast("Nessun link trovato") + } } } catch (e: Exception) { showToast("Errore caricamento link: ${e.message}") diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/SourceSelectionScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/SourceSelectionScreen.kt new file mode 100644 index 00000000000..634123be788 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/SourceSelectionScreen.kt @@ -0,0 +1,132 @@ +package com.lagradost.cloudstream3.ui.car + +import android.graphics.Color +import androidx.car.app.CarContext +import androidx.car.app.CarToast +import androidx.car.app.Screen +import androidx.car.app.model.Action +import androidx.car.app.model.CarIcon +import androidx.car.app.model.ItemList +import androidx.car.app.model.ListTemplate +import androidx.car.app.model.Row +import androidx.car.app.model.Template +import androidx.core.graphics.drawable.IconCompat +import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull +import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.Qualities +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * Screen that displays available streaming sources for a content item. + * User can select a source, which will be used for playback. + * + * @param apiName The API/provider name to use for loading links + * @param dataUrl The data URL to load links for (movie URL or episode data) + * @param currentSourceUrl The currently selected source URL (for showing check mark) + * @param onSourceSelected Callback when a source is selected + */ +class SourceSelectionScreen( + carContext: CarContext, + private val apiName: String, + private val dataUrl: String, + private val currentSourceUrl: String? = null, + private val onSourceSelected: (ExtractorLink) -> Unit +) : Screen(carContext) { + + private val scope = CoroutineScope(Dispatchers.IO + Job()) + private var isLoading = true + private var sources: List = emptyList() + private var errorMessage: String? = null + + init { + loadSources() + } + + private fun loadSources() { + scope.launch { + try { + val api = getApiFromNameNull(apiName) + if (api == null) { + errorMessage = "Provider non trovato" + isLoading = false + invalidate() + return@launch + } + + val links = mutableListOf() + api.loadLinks(dataUrl, false, {}, { link -> + links.add(link) + }) + + withContext(Dispatchers.Main) { + if (links.isEmpty()) { + errorMessage = "Nessuna sorgente trovata" + } else { + // Sort by quality (highest first) + sources = links.sortedByDescending { it.quality } + } + isLoading = false + invalidate() + } + } catch (e: Exception) { + withContext(Dispatchers.Main) { + errorMessage = "Errore: ${e.message}" + isLoading = false + invalidate() + } + } + } + } + + override fun onGetTemplate(): Template { + val templateBuilder = ListTemplate.Builder() + .setTitle("Sorgenti") + .setHeaderAction(Action.BACK) + + if (isLoading) { + // When loading, just set loading state without any list + templateBuilder.setLoading(true) + } else { + // Not loading - build the list + val listBuilder = ItemList.Builder() + + if (errorMessage != null) { + listBuilder.setNoItemsMessage(errorMessage!!) + } else if (sources.isEmpty()) { + listBuilder.setNoItemsMessage("Nessuna sorgente disponibile") + } else { + // Add each source as a row + for (source in sources) { + val qualityStr = Qualities.getStringByInt(source.quality) + val title = if (qualityStr.isNotEmpty()) { + "${source.name} - $qualityStr" + } else { + source.name + } + + val rowBuilder = Row.Builder() + .setTitle(title) + .addText(source.source) + .setOnClickListener { + onSourceSelected(source) + CarToast.makeText(carContext, "Sorgente selezionata: ${source.name}", CarToast.LENGTH_SHORT).show() + screenManager.pop() + } + + + listBuilder.addItem(rowBuilder.build()) + } + } + + templateBuilder.setSingleList(listBuilder.build()) + templateBuilder.setLoading(false) + } + + return templateBuilder.build() + } +} diff --git a/app/src/main/res/drawable/ic_baseline_source_24.xml b/app/src/main/res/drawable/ic_baseline_source_24.xml new file mode 100644 index 00000000000..0d7eb86d55f --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_source_24.xml @@ -0,0 +1,10 @@ + + + From b946fca8d68bf7c546175bcde35f7871752efb4d Mon Sep 17 00:00:00 2001 From: Michele Granato Date: Thu, 15 Jan 2026 14:22:38 +0100 Subject: [PATCH 09/20] fix regressione salvataggio cronologia --- app/build.gradle.kts | 2 +- .../cloudstream3/ui/car/PlayerCarScreen.kt | 44 ++++++++----------- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 28161875777..f2e9016621c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -63,7 +63,7 @@ android { minSdk = libs.versions.minSdk.get().toInt() targetSdk = libs.versions.targetSdk.get().toInt() versionCode = 67 - versionName = "4.6.9" + versionName = "4.6.10" resValue("string", "commit_hash", getGitCommitHash()) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt index 16cb9463586..e2bddf2d227 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt @@ -184,6 +184,24 @@ class PlayerCarScreen( val apiName = data.apiName val api = getApiFromNameNull(apiName) ?: return@launch + // Resolve IDs for syncing BEFORE starting playback + // This ensures IDs are available for saveProgress() calls during playback + val mainUrl = api.mainUrl + val idFromUrl = data.url.replace(mainUrl, "").replace("/", "").hashCode() + + // Priority: 1. Item ID (if available from Home/Search and valid) + // 2. Data URL Hashcode (using strict cleaning logic) + currentParentId = item?.id ?: idFromUrl + + if (data is TvSeriesLoadResponse && activeEpisode != null) { + currentEpisodeId = activeEpisode!!.data.hashCode() + } else { + // For movies, we use the parent ID + currentEpisodeId = currentParentId + } + + Log.d("PlayerCarScreen", "Resolved IDs (STRICT) - Name: ${data.name} | Parent: $currentParentId | Episode: $currentEpisodeId | Type: ${data.javaClass.simpleName} | ItemID: ${item?.id} | IdFromUrl: $idFromUrl") + val links = mutableListOf() try { val urlToLoad = when { @@ -227,32 +245,6 @@ class PlayerCarScreen( showToast("Errore caricamento link: ${e.message}") e.printStackTrace() } - - // Resolve IDs for syncing (Exact match to Main App's ResultViewModel2.getLoadResponseIdFromUrl) - // Logic: url.replace(mainUrl, "").replace("/", "").hashCode() - - val mainUrl = api.mainUrl - val idFromUrl = data.url.replace(mainUrl, "").replace("/", "").hashCode() - - // Priority: 1. Item ID (if available from Home/Search and valid) - // 2. Data URL Hashcode (using strict cleaning logic) - currentParentId = item?.id ?: idFromUrl - - if (data is TvSeriesLoadResponse && activeEpisode != null) { - // Episode doesn't have an ID property, so we use the data (url) hashcode - // Note: Episodes might not use the mainUrl cleanup in the same way, but usually depend on their own data string. - // In PlayerGeneratorViewModel/RepoLinkGenerator, episodes use 'current.id' which comes from ResultEpisode. - // ResultEpisode is built using 'id' from LoadResponse. - // So we should apply the same cleaning to episode data if it's a URL. - // However, activeEpisode.data is usually the direct link. - // Let's stick to .hashCode() of the data string for episodes as a reasonable unique key if explicit ID is known to be missing. - currentEpisodeId = activeEpisode!!.data.hashCode() - } else { - // For movies, we use the parent ID - currentEpisodeId = currentParentId - } - - Log.d("PlayerCarScreen", "Resolved IDs (STRICT) - Name: ${data.name} | Parent: $currentParentId | Episode: $currentEpisodeId | Type: ${data.javaClass.simpleName} | ItemID: ${item?.id} | IdFromUrl: $idFromUrl") } } From edd2d1d19cb96f3e7757455b17282f93d2d1c001 Mon Sep 17 00:00:00 2001 From: Michele Granato Date: Fri, 16 Jan 2026 14:52:58 +0100 Subject: [PATCH 10/20] ANDROID AUTO RC6 - testi gestiti con dizionari --- app/build.gradle.kts | 21 +++++- app/src/main/AndroidManifest.xml | 4 +- .../lagradost/cloudstream3/CloudStreamApp.kt | 25 ++++++- .../lagradost/cloudstream3/MainActivity.kt | 4 + .../ui/account/AccountSelectActivity.kt | 7 ++ .../cloudstream3/ui/car/BookmarksScreen.kt | 8 +- .../cloudstream3/ui/car/CarStrings.kt | 51 +++++++++++++ .../cloudstream3/ui/car/DetailsScreen.kt | 16 ++-- .../cloudstream3/ui/car/DownloadsScreen.kt | 15 ++-- .../ui/car/EpisodeDetailScreen.kt | 8 +- .../cloudstream3/ui/car/EpisodeListScreen.kt | 8 +- .../cloudstream3/ui/car/HistoryScreen.kt | 9 ++- .../cloudstream3/ui/car/LibraryCarScreen.kt | 7 +- .../cloudstream3/ui/car/MainCarScreen.kt | 24 +++--- .../cloudstream3/ui/car/PlayerCarScreen.kt | 16 ++-- .../cloudstream3/ui/car/ProviderCarScreen.kt | 5 +- .../cloudstream3/ui/car/SearchCarScreen.kt | 4 +- .../ui/car/SourceSelectionScreen.kt | 12 +-- .../ui/car/TvSeriesDetailScreen.kt | 22 +++--- .../main/res-car/values-b+af/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+am/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+apc/strings_car.xml | 74 +++++++++++++++++++ .../main/res-car/values-b+ar/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+ars/strings_car.xml | 74 +++++++++++++++++++ .../main/res-car/values-b+as/strings_car.xml | 74 +++++++++++++++++++ .../main/res-car/values-b+az/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+be/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+bg/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+bn/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+bs/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+ca/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+ckb/strings_car.xml | 74 +++++++++++++++++++ .../main/res-car/values-b+cs/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+da/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+de/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+el/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+eo/strings_car.xml | 74 +++++++++++++++++++ .../main/res-car/values-b+es/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+et/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+eu/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+fa/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+fi/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+fil/strings_car.xml | 74 +++++++++++++++++++ .../main/res-car/values-b+fr/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+gl/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+gu/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+hi/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+hr/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+hu/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+hy/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+in/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+is/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+iw/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+ja/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+ka/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+kk/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+km/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+kn/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+ko/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+ky/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+lo/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+lt/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+lv/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+mk/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+ml/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+mn/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+mr/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+ms/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+mt/strings_car.xml | 74 +++++++++++++++++++ .../main/res-car/values-b+my/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+ne/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+nl/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+nn/strings_car.xml | 74 +++++++++++++++++++ .../main/res-car/values-b+no/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+or/strings_car.xml | 74 +++++++++++++++++++ .../main/res-car/values-b+pa/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+pl/strings_car.xml | 51 +++++++++++++ .../res-car/values-b+pt+BR/strings_car.xml | 74 +++++++++++++++++++ .../main/res-car/values-b+pt/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+qt/strings_car.xml | 74 +++++++++++++++++++ .../main/res-car/values-b+ro/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+ru/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+si/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+sk/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+sl/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+so/strings_car.xml | 74 +++++++++++++++++++ .../main/res-car/values-b+sq/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+sr/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+sv/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+sw/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+ta/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+te/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+tg/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+th/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+ti/strings_car.xml | 74 +++++++++++++++++++ .../main/res-car/values-b+tl/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+tr/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+uk/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+ur/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+uz/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+vi/strings_car.xml | 51 +++++++++++++ .../res-car/values-b+zh+TW/strings_car.xml | 74 +++++++++++++++++++ .../main/res-car/values-b+zh/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-b+zu/strings_car.xml | 51 +++++++++++++ .../main/res-car/values-it/strings_car.xml | 74 +++++++++++++++++++ app/src/main/res-car/values/strings_car.xml | 74 +++++++++++++++++++ .../res/{values-b+es => values-es}/array.xml | 0 .../{values-b+es => values-es}/strings.xml | 0 .../{values-b+it => values-it}/strings.xml | 0 109 files changed, 4990 insertions(+), 81 deletions(-) create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/CarStrings.kt create mode 100644 app/src/main/res-car/values-b+af/strings_car.xml create mode 100644 app/src/main/res-car/values-b+am/strings_car.xml create mode 100644 app/src/main/res-car/values-b+apc/strings_car.xml create mode 100644 app/src/main/res-car/values-b+ar/strings_car.xml create mode 100644 app/src/main/res-car/values-b+ars/strings_car.xml create mode 100644 app/src/main/res-car/values-b+as/strings_car.xml create mode 100644 app/src/main/res-car/values-b+az/strings_car.xml create mode 100644 app/src/main/res-car/values-b+be/strings_car.xml create mode 100644 app/src/main/res-car/values-b+bg/strings_car.xml create mode 100644 app/src/main/res-car/values-b+bn/strings_car.xml create mode 100644 app/src/main/res-car/values-b+bs/strings_car.xml create mode 100644 app/src/main/res-car/values-b+ca/strings_car.xml create mode 100644 app/src/main/res-car/values-b+ckb/strings_car.xml create mode 100644 app/src/main/res-car/values-b+cs/strings_car.xml create mode 100644 app/src/main/res-car/values-b+da/strings_car.xml create mode 100644 app/src/main/res-car/values-b+de/strings_car.xml create mode 100644 app/src/main/res-car/values-b+el/strings_car.xml create mode 100644 app/src/main/res-car/values-b+eo/strings_car.xml create mode 100644 app/src/main/res-car/values-b+es/strings_car.xml create mode 100644 app/src/main/res-car/values-b+et/strings_car.xml create mode 100644 app/src/main/res-car/values-b+eu/strings_car.xml create mode 100644 app/src/main/res-car/values-b+fa/strings_car.xml create mode 100644 app/src/main/res-car/values-b+fi/strings_car.xml create mode 100644 app/src/main/res-car/values-b+fil/strings_car.xml create mode 100644 app/src/main/res-car/values-b+fr/strings_car.xml create mode 100644 app/src/main/res-car/values-b+gl/strings_car.xml create mode 100644 app/src/main/res-car/values-b+gu/strings_car.xml create mode 100644 app/src/main/res-car/values-b+hi/strings_car.xml create mode 100644 app/src/main/res-car/values-b+hr/strings_car.xml create mode 100644 app/src/main/res-car/values-b+hu/strings_car.xml create mode 100644 app/src/main/res-car/values-b+hy/strings_car.xml create mode 100644 app/src/main/res-car/values-b+in/strings_car.xml create mode 100644 app/src/main/res-car/values-b+is/strings_car.xml create mode 100644 app/src/main/res-car/values-b+iw/strings_car.xml create mode 100644 app/src/main/res-car/values-b+ja/strings_car.xml create mode 100644 app/src/main/res-car/values-b+ka/strings_car.xml create mode 100644 app/src/main/res-car/values-b+kk/strings_car.xml create mode 100644 app/src/main/res-car/values-b+km/strings_car.xml create mode 100644 app/src/main/res-car/values-b+kn/strings_car.xml create mode 100644 app/src/main/res-car/values-b+ko/strings_car.xml create mode 100644 app/src/main/res-car/values-b+ky/strings_car.xml create mode 100644 app/src/main/res-car/values-b+lo/strings_car.xml create mode 100644 app/src/main/res-car/values-b+lt/strings_car.xml create mode 100644 app/src/main/res-car/values-b+lv/strings_car.xml create mode 100644 app/src/main/res-car/values-b+mk/strings_car.xml create mode 100644 app/src/main/res-car/values-b+ml/strings_car.xml create mode 100644 app/src/main/res-car/values-b+mn/strings_car.xml create mode 100644 app/src/main/res-car/values-b+mr/strings_car.xml create mode 100644 app/src/main/res-car/values-b+ms/strings_car.xml create mode 100644 app/src/main/res-car/values-b+mt/strings_car.xml create mode 100644 app/src/main/res-car/values-b+my/strings_car.xml create mode 100644 app/src/main/res-car/values-b+ne/strings_car.xml create mode 100644 app/src/main/res-car/values-b+nl/strings_car.xml create mode 100644 app/src/main/res-car/values-b+nn/strings_car.xml create mode 100644 app/src/main/res-car/values-b+no/strings_car.xml create mode 100644 app/src/main/res-car/values-b+or/strings_car.xml create mode 100644 app/src/main/res-car/values-b+pa/strings_car.xml create mode 100644 app/src/main/res-car/values-b+pl/strings_car.xml create mode 100644 app/src/main/res-car/values-b+pt+BR/strings_car.xml create mode 100644 app/src/main/res-car/values-b+pt/strings_car.xml create mode 100644 app/src/main/res-car/values-b+qt/strings_car.xml create mode 100644 app/src/main/res-car/values-b+ro/strings_car.xml create mode 100644 app/src/main/res-car/values-b+ru/strings_car.xml create mode 100644 app/src/main/res-car/values-b+si/strings_car.xml create mode 100644 app/src/main/res-car/values-b+sk/strings_car.xml create mode 100644 app/src/main/res-car/values-b+sl/strings_car.xml create mode 100644 app/src/main/res-car/values-b+so/strings_car.xml create mode 100644 app/src/main/res-car/values-b+sq/strings_car.xml create mode 100644 app/src/main/res-car/values-b+sr/strings_car.xml create mode 100644 app/src/main/res-car/values-b+sv/strings_car.xml create mode 100644 app/src/main/res-car/values-b+sw/strings_car.xml create mode 100644 app/src/main/res-car/values-b+ta/strings_car.xml create mode 100644 app/src/main/res-car/values-b+te/strings_car.xml create mode 100644 app/src/main/res-car/values-b+tg/strings_car.xml create mode 100644 app/src/main/res-car/values-b+th/strings_car.xml create mode 100644 app/src/main/res-car/values-b+ti/strings_car.xml create mode 100644 app/src/main/res-car/values-b+tl/strings_car.xml create mode 100644 app/src/main/res-car/values-b+tr/strings_car.xml create mode 100644 app/src/main/res-car/values-b+uk/strings_car.xml create mode 100644 app/src/main/res-car/values-b+ur/strings_car.xml create mode 100644 app/src/main/res-car/values-b+uz/strings_car.xml create mode 100644 app/src/main/res-car/values-b+vi/strings_car.xml create mode 100644 app/src/main/res-car/values-b+zh+TW/strings_car.xml create mode 100644 app/src/main/res-car/values-b+zh/strings_car.xml create mode 100644 app/src/main/res-car/values-b+zu/strings_car.xml create mode 100644 app/src/main/res-car/values-it/strings_car.xml create mode 100644 app/src/main/res-car/values/strings_car.xml rename app/src/main/res/{values-b+es => values-es}/array.xml (100%) rename app/src/main/res/{values-b+es => values-es}/strings.xml (100%) rename app/src/main/res/{values-b+it => values-it}/strings.xml (100%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f2e9016621c..07b24928368 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -63,11 +63,20 @@ android { minSdk = libs.versions.minSdk.get().toInt() targetSdk = libs.versions.targetSdk.get().toInt() versionCode = 67 - versionName = "4.6.10" + versionName = "4.6.12" resValue("string", "commit_hash", getGitCommitHash()) - - resourceConfigurations.addAll(listOf("en", "it")) + + resourceConfigurations.addAll( + listOf( + "en", "af", "am", "apc", "ar", "ars", "as", "az", "be", "bg", "bn", "ca", "ckb", "cs", + "de", "el", "eo", "es", "fa", "fil", "fr", "gl", "hi", "hr", "hu", "in", "it", "iw", + "ja", "kn", "ko", "lt", "lv", "mk", "ml", "ms", "mt", "my", "ne", "nl", "nn", "no", + "or", "pl", "pt", "pt-rBR", "ro", "ru", "sk", "so", "sv", "ta", "ti", "tl", "tr", + "uk", "ur", "vi", "zh", "zh-rTW" + ) + ) + manifestPlaceholders["target_sdk_version"] = libs.versions.targetSdk.get() @@ -157,6 +166,12 @@ android { namespace = "com.lagradost.cloudstream3" + + sourceSets { + getByName("main") { + res.srcDirs("src/main/res", "src/main/res-car") + } + } } dependencies { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d73ad9fdcf7..5ab1ff2db93 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -127,7 +127,7 @@ --> diff --git a/app/src/main/java/com/lagradost/cloudstream3/CloudStreamApp.kt b/app/src/main/java/com/lagradost/cloudstream3/CloudStreamApp.kt index b7832799884..1e12d38b04a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/CloudStreamApp.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/CloudStreamApp.kt @@ -20,6 +20,7 @@ import com.lagradost.cloudstream3.ui.settings.Globals.EMULATOR import com.lagradost.cloudstream3.ui.settings.Globals.TV import com.lagradost.cloudstream3.ui.settings.Globals.isLayout import com.lagradost.cloudstream3.utils.AppContextUtils.openBrowser +import com.lagradost.cloudstream3.ui.car.CarStrings import com.lagradost.cloudstream3.utils.Coroutines.runOnMainThread import com.lagradost.cloudstream3.utils.DataStore.getKey import com.lagradost.cloudstream3.utils.DataStore.getKeys @@ -70,6 +71,7 @@ class CloudStreamApp : Application(), SingletonImageLoader.Factory { override fun onCreate() { super.onCreate() + CarStrings.init(this) // If we want to initialize Coil as early as possible, maybe when // loading an image or GIF in a splash screen activity. // buildImageLoader(applicationContext) @@ -84,7 +86,7 @@ class CloudStreamApp : Application(), SingletonImageLoader.Factory { } override fun attachBaseContext(base: Context?) { - super.attachBaseContext(base) + super.attachBaseContext(updateBaseContextLocale(base)) context = base // This can be removed without deprecation after next stable AcraApplication.context = context @@ -98,6 +100,27 @@ class CloudStreamApp : Application(), SingletonImageLoader.Factory { companion object { var exceptionHandler: ExceptionHandler? = null + fun updateBaseContextLocale(context: Context?): Context? { + if (context == null) return null + val settingsManager = androidx.preference.PreferenceManager.getDefaultSharedPreferences(context) + val localeCode = settingsManager.getString(context.getString(R.string.locale_key), null) + + // DEBUG LOGGING + println("DEBUG: updateBaseContextLocale called. localeCode from prefs: '$localeCode'") + + if (localeCode.isNullOrEmpty()) return context + + // Use forLanguageTag to correctly parse BCP 47 tags (e.g. "es", "es-ES", "it") + val locale = Locale.forLanguageTag(localeCode) + println("DEBUG: parsed Locale: '$locale', language: '${locale.language}', country: '${locale.country}'") + + Locale.setDefault(locale) + val config = android.content.res.Configuration(context.resources.configuration) + config.setLocale(locale) + config.setLayoutDirection(locale) + return context.createConfigurationContext(config) + } + /** Use to get Activity from Context. */ tailrec fun Context.getActivity(): Activity? { return when (this) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt index 1caaaa4c693..8d796a02dac 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt @@ -197,6 +197,10 @@ import android.content.ComponentName import android.content.ContentUris class MainActivity : AppCompatActivity(), ColorPickerDialogListener, BiometricCallback { + override fun attachBaseContext(base: Context?) { + super.attachBaseContext(CloudStreamApp.updateBaseContextLocale(base)) + } + companion object { var activityResultLauncher: ActivityResultLauncher? = null diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/account/AccountSelectActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/account/AccountSelectActivity.kt index 42f68067b8c..dafd8141041 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/account/AccountSelectActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/account/AccountSelectActivity.kt @@ -36,8 +36,15 @@ import com.lagradost.cloudstream3.utils.UIHelper.fixSystemBarsPadding import com.lagradost.cloudstream3.utils.UIHelper.openActivity import com.lagradost.cloudstream3.utils.UIHelper.setNavigationBarColorCompat +import android.content.Context +import com.lagradost.cloudstream3.CloudStreamApp + class AccountSelectActivity : FragmentActivity(), BiometricCallback { + override fun attachBaseContext(base: Context?) { + super.attachBaseContext(CloudStreamApp.updateBaseContextLocale(base)) + } + val accountViewModel: AccountViewModel by viewModels() @SuppressLint("NotifyDataSetChanged") diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt index fc9ec68a967..6f70f191384 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/BookmarksScreen.kt @@ -44,7 +44,7 @@ class BookmarksScreen(carContext: CarContext) : Screen(carContext), androidx.lif val builder = ItemList.Builder() if (favorites.isEmpty()) { - builder.setNoItemsMessage("Nessun preferito trovato") + builder.setNoItemsMessage(CarStrings.get(R.string.car_no_favorites_found)) } else { favorites.forEach { item -> builder.addItem( @@ -82,7 +82,7 @@ class BookmarksScreen(carContext: CarContext) : Screen(carContext), androidx.lif itemList = ItemList.Builder() .addItem( Row.Builder() - .setTitle("Errore: ${e.message}") + .setTitle("${CarStrings.get(R.string.car_error)}: ${e.message}") .setOnClickListener { loadBookmarks() } .build() ) @@ -96,8 +96,8 @@ class BookmarksScreen(carContext: CarContext) : Screen(carContext), androidx.lif override fun onGetTemplate(): Template { return ListTemplate.Builder() - .setSingleList(itemList ?: ItemList.Builder().setNoItemsMessage("Caricamento preferiti...").build()) - .setTitle("Preferiti") + .setSingleList(itemList ?: ItemList.Builder().setNoItemsMessage(CarStrings.get(R.string.car_loading)).build()) + .setTitle(CarStrings.get(R.string.car_favorites)) .setHeaderAction(Action.BACK) .build() } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/CarStrings.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/CarStrings.kt new file mode 100644 index 00000000000..3d27aab57f4 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/CarStrings.kt @@ -0,0 +1,51 @@ +package com.lagradost.cloudstream3.ui.car + +import android.content.Context +import android.content.res.Configuration +import android.content.res.Resources +import androidx.annotation.StringRes +import androidx.preference.PreferenceManager +import com.lagradost.cloudstream3.R +import java.util.Locale + +/** + * Singleton helper for Android Auto localization. + * Wraps Android Resources to support overriding the language based on app settings, + * independent of the system locale. + */ +object CarStrings { + private var resources: Resources? = null + + /** + * Initialize the helper with the application context. + * Call this in Application.onCreate(). + */ + fun init(context: Context) { + // Read user preference + val prefs = PreferenceManager.getDefaultSharedPreferences(context) + val localeCode = prefs.getString(context.getString(R.string.locale_key), null) + + // If a specific locale is set (e.g. "it"), force it. + // Otherwise, use system default. + if (!localeCode.isNullOrEmpty()) { + val locale = Locale(localeCode) + val config = Configuration(context.resources.configuration) + config.setLocale(locale) + resources = context.createConfigurationContext(config).resources + } else { + resources = context.resources + } + } + + /** + * Get a localized string by Resource ID. + */ + fun get(@StringRes id: Int, vararg args: Any): String { + val res = resources ?: throw IllegalStateException("CarStrings not initialized! Call init() in Application.onCreate()") + return if (args.isEmpty()) { + res.getString(id) + } else { + res.getString(id, *args) + } + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/DetailsScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/DetailsScreen.kt index 298e5b2d0d1..50b0f586ee6 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/DetailsScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/DetailsScreen.kt @@ -10,6 +10,7 @@ import androidx.car.app.model.Row import androidx.car.app.model.Template import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.TvSeriesLoadResponse +import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.TvType import com.lagradost.cloudstream3.newTvSeriesSearchResponse import com.lagradost.cloudstream3.ui.player.DownloadedPlayerActivity @@ -32,7 +33,6 @@ import coil3.request.ImageRequest import coil3.SingletonImageLoader import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull import com.lagradost.cloudstream3.LoadResponse -import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.ui.APIRepository import com.lagradost.cloudstream3.utils.DataStoreHelper @@ -128,7 +128,7 @@ class DetailsScreen( is Resource.Loading -> {} } } else { - errorMessage = "Provider non trovato" + errorMessage = CarStrings.get(R.string.car_provider_not_found) isLoading = false } } catch (e: Exception) { @@ -196,7 +196,7 @@ class DetailsScreen( if (!details.plot.isNullOrEmpty()) { paneBuilder.addRow( Row.Builder() - .setTitle("Trama") + .setTitle(CarStrings.get(R.string.car_plot)) .addText(details.plot!!) .build() ) @@ -216,14 +216,14 @@ class DetailsScreen( paneBuilder.addRow( Row.Builder() - .setTitle("Cast") + .setTitle(CarStrings.get(R.string.car_cast)) .addText(s) .build() ) } } } else if (errorMessage != null) { - paneBuilder.addRow(Row.Builder().setTitle("Errore dettagli: $errorMessage").build()) + paneBuilder.addRow(Row.Builder().setTitle("${CarStrings.get(R.string.car_error)}: $errorMessage").build()) } } @@ -249,7 +249,7 @@ class DetailsScreen( val sourceActionTitle = if (selectedSource != null) { selectedSource!!.name } else { - "Sorgente" + CarStrings.get(R.string.car_source) } val sourceAction = Action.Builder() @@ -295,7 +295,7 @@ class DetailsScreen( if (isFavorite) { DataStoreHelper.removeFavoritesData(id) isFavorite = false - androidx.car.app.CarToast.makeText(carContext, "Rimosso dai preferiti", androidx.car.app.CarToast.LENGTH_SHORT).show() + androidx.car.app.CarToast.makeText(carContext, CarStrings.get(R.string.car_removed_from_favorites), androidx.car.app.CarToast.LENGTH_SHORT).show() } else { val favoritesData = FavoritesData( favoritesTime = System.currentTimeMillis(), @@ -315,7 +315,7 @@ class DetailsScreen( ) DataStoreHelper.setFavoritesData(id, favoritesData) isFavorite = true - androidx.car.app.CarToast.makeText(carContext, "Aggiunto ai preferiti", androidx.car.app.CarToast.LENGTH_SHORT).show() + androidx.car.app.CarToast.makeText(carContext, CarStrings.get(R.string.car_added_to_favorites), androidx.car.app.CarToast.LENGTH_SHORT).show() } invalidate() } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt index 405fc27367b..424d3bbb116 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/DownloadsScreen.kt @@ -9,6 +9,7 @@ import androidx.car.app.model.Row import androidx.car.app.model.Template import com.lagradost.cloudstream3.utils.VideoDownloadHelper import com.lagradost.cloudstream3.utils.VideoDownloadManager +import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.utils.DataStore.getKey import com.lagradost.cloudstream3.utils.DataStore.getKeys import com.lagradost.cloudstream3.utils.DataStoreHelper @@ -56,10 +57,10 @@ class DownloadsScreen( val builder = ItemList.Builder() if (children.isEmpty()) { - builder.setNoItemsMessage("Nessun episodio trovato") + builder.setNoItemsMessage(CarStrings.get(R.string.car_no_episodes_found)) } else { children.forEach { episode -> - val name = "S${episode.season}:E${episode.episode} - ${episode.name ?: "Episodio"}" + val name = "S${episode.season}:E${episode.episode} - ${episode.name ?: CarStrings.get(R.string.car_episode)}" builder.addItem( Row.Builder() .setTitle(name) @@ -105,7 +106,7 @@ class DownloadsScreen( } if (validHeaders.isEmpty()) { - builder.setNoItemsMessage("Nessun download completato trovato") + builder.setNoItemsMessage(CarStrings.get(R.string.car_no_downloads_found)) } else { validHeaders.forEach { header -> val lastWatched = DataStoreHelper.getLastWatched(header.id) @@ -143,7 +144,7 @@ class DownloadsScreen( val fileInfo = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(context, episodeId) if (fileInfo?.path == null) { withContext(Dispatchers.Main) { - androidx.car.app.CarToast.makeText(carContext, "File non trovato", androidx.car.app.CarToast.LENGTH_SHORT).show() + androidx.car.app.CarToast.makeText(carContext, CarStrings.get(R.string.car_file_not_found), androidx.car.app.CarToast.LENGTH_SHORT).show() } return@launch } @@ -182,7 +183,7 @@ class DownloadsScreen( if (children.isEmpty()) { withContext(Dispatchers.Main) { - androidx.car.app.CarToast.makeText(carContext, "Nessun episodio valido trovato", androidx.car.app.CarToast.LENGTH_SHORT).show() + androidx.car.app.CarToast.makeText(carContext, CarStrings.get(R.string.car_no_valid_episode), androidx.car.app.CarToast.LENGTH_SHORT).show() } return@launch } @@ -204,9 +205,9 @@ class DownloadsScreen( override fun onGetTemplate(): Template { return ListTemplate.Builder() - .setTitle(headerName ?: "Download") + .setTitle(headerName ?: CarStrings.get(R.string.car_downloads)) .setHeaderAction(Action.BACK) - .setSingleList(itemList ?: ItemList.Builder().setNoItemsMessage(if (headerName == null) "Caricamento download..." else "Caricamento episodi...").build()) + .setSingleList(itemList ?: ItemList.Builder().setNoItemsMessage(CarStrings.get(R.string.car_loading)).build()) .build() } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeDetailScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeDetailScreen.kt index 6e54eb62a73..84060f26909 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeDetailScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeDetailScreen.kt @@ -67,11 +67,11 @@ class EpisodeDetailScreen( val paneBuilder = Pane.Builder() // Title Row - val title = "${episode.episode}. ${episode.name ?: "Episodio ${episode.episode}"}" + val title = "${episode.episode}. ${episode.name ?: "${CarStrings.get(R.string.car_episode)} ${episode.episode}"}" paneBuilder.addRow( Row.Builder() .setTitle(title) - .addText("Stagione ${episode.season ?: "?"}") + .addText("${CarStrings.get(R.string.car_season)} ${episode.season ?: "?"}") .build() ) @@ -87,7 +87,7 @@ class EpisodeDetailScreen( if (!episode.description.isNullOrEmpty()) { paneBuilder.addRow( Row.Builder() - .setTitle("Trama") + .setTitle(CarStrings.get(R.string.car_plot)) .addText(episode.description!!) .build() ) @@ -122,7 +122,7 @@ class EpisodeDetailScreen( val sourceActionTitle = if (selectedSource != null) { selectedSource!!.name } else { - "Sorgente" + CarStrings.get(R.string.car_source) } val sourceAction = Action.Builder() diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeListScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeListScreen.kt index 3d1a4905da4..44c3fe6baa3 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeListScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/EpisodeListScreen.kt @@ -28,7 +28,7 @@ class EpisodeListScreen( return ListTemplate.Builder() .setTitle(details.name) .setHeaderAction(Action.BACK) - .setSingleList(ItemList.Builder().addItem(Row.Builder().setTitle("Nessun episodio trovato").build()).build()) + .setSingleList(ItemList.Builder().addItem(Row.Builder().setTitle(CarStrings.get(R.string.car_no_episodes_found)).build()).build()) .build() } @@ -38,7 +38,7 @@ class EpisodeListScreen( val listBuilder = ItemList.Builder() seasonEpisodes.forEach { episode -> - val title = "${episode.episode}. ${episode.name ?: "Episodio ${episode.episode}"}" + val title = "${episode.episode}. ${episode.name ?: "${CarStrings.get(R.string.car_episode)} ${episode.episode}"}" val rowBuilder = Row.Builder() .setTitle(title) .setOnClickListener { @@ -76,7 +76,7 @@ class EpisodeListScreen( } val seasonAction = Action.Builder() - .setTitle("Stagione $currentSeason") + .setTitle("${CarStrings.get(R.string.car_season)} $currentSeason") .setOnClickListener { // Cycle through seasons currentSeasonIndex = (currentSeasonIndex + 1) % availableSeasons.size @@ -85,7 +85,7 @@ class EpisodeListScreen( .build() return ListTemplate.Builder() - .setTitle("${details.name} - Stagione $currentSeason") + .setTitle("${details.name} - ${CarStrings.get(R.string.car_season)} $currentSeason") .setHeaderAction(Action.BACK) .setSingleList(listBuilder.build()) .setActionStrip( diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt index 2aecc3a37b2..3eec46cd7ca 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/HistoryScreen.kt @@ -16,6 +16,7 @@ import com.lagradost.cloudstream3.utils.VideoDownloadHelper import com.lagradost.cloudstream3.utils.DOWNLOAD_HEADER_CACHE import com.lagradost.cloudstream3.CloudStreamApp.Companion.getKey import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull +import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.ui.APIRepository import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.TvSeriesLoadResponse @@ -65,7 +66,7 @@ class HistoryScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc val builder = ItemList.Builder() if (resumeWatchingResult.isNullOrEmpty()) { - builder.setNoItemsMessage("Nessun elemento 'Continua a guardare' trovato") + builder.setNoItemsMessage(CarStrings.get(R.string.car_no_continue_watching)) } else { resumeWatchingResult.forEach { (resume, cachedData) -> val title = cachedData.name @@ -116,7 +117,7 @@ class HistoryScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc private fun playResumeItem(resume: VideoDownloadHelper.ResumeWatching, cachedData: VideoDownloadHelper.DownloadHeaderCached) { scope.launch { withContext(Dispatchers.Main) { - androidx.car.app.CarToast.makeText(carContext, "Riprendo ${cachedData.name}...", androidx.car.app.CarToast.LENGTH_LONG).show() + androidx.car.app.CarToast.makeText(carContext, CarStrings.get(R.string.car_resuming, cachedData.name), androidx.car.app.CarToast.LENGTH_LONG).show() } val api = getApiFromNameNull(cachedData.apiName) ?: return@launch @@ -198,10 +199,10 @@ class HistoryScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc } override fun onGetTemplate(): Template { - val list = itemList ?: ItemList.Builder().setNoItemsMessage("Caricamento cronologia...").build() + val list = itemList ?: ItemList.Builder().setNoItemsMessage(CarStrings.get(R.string.car_loading)).build() return ListTemplate.Builder() - .setTitle("Cronologia") + .setTitle(CarStrings.get(R.string.car_history)) .setHeaderAction(Action.BACK) .setSingleList(list) .build() diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/LibraryCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/LibraryCarScreen.kt index bcb0dd616b4..50dbb980a26 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/LibraryCarScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/LibraryCarScreen.kt @@ -7,6 +7,7 @@ import androidx.car.app.model.ItemList import androidx.car.app.model.ListTemplate import androidx.car.app.model.Row import androidx.car.app.model.Template +import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.utils.DataStoreHelper import com.lagradost.cloudstream3.utils.DataStoreHelper.getBookmarkedData import com.lagradost.cloudstream3.utils.DataStoreHelper.getLastWatched @@ -22,21 +23,21 @@ class LibraryCarScreen(carContext: CarContext) : Screen(carContext) { ItemList.Builder() .addItem( Row.Builder() - .setTitle("Bookmarks") + .setTitle(CarStrings.get(R.string.car_bookmarks)) .setOnClickListener { screenManager.push(BookmarksScreen(carContext)) } .setBrowsable(true) .build() ) .addItem( Row.Builder() - .setTitle("History") + .setTitle(CarStrings.get(R.string.car_history)) .setOnClickListener { screenManager.push(HistoryScreen(carContext)) } .setBrowsable(true) .build() ) .build() ) - .setTitle("Library") + .setTitle(CarStrings.get(R.string.car_library)) .setHeaderAction(Action.BACK) .build() } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt index 179e62ac8ba..cd736e65a4b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt @@ -56,7 +56,7 @@ class MainCarScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc } if (api == null) { - errorMessage = "Provider not found: $currentApiName" + errorMessage = "${CarStrings.get(R.string.car_provider_not_found)}: $currentApiName" isLoading = false invalidate() return@launch @@ -69,7 +69,7 @@ class MainCarScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc isLoading = false } is Resource.Failure -> { - errorMessage = result.errorString ?: "Error loading content" + errorMessage = result.errorString ?: CarStrings.get(R.string.car_loading_content) isLoading = false } is Resource.Loading -> {} @@ -88,7 +88,7 @@ class MainCarScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc menuListBuilder.addItem( Row.Builder() - .setTitle("Preferiti") + .setTitle(CarStrings.get(R.string.car_favorites)) .setImage(CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_baseline_favorite_24)).build()) .setOnClickListener { screenManager.push(BookmarksScreen(carContext)) } .setBrowsable(true) @@ -97,7 +97,7 @@ class MainCarScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc menuListBuilder.addItem( Row.Builder() - .setTitle("Cronologia") + .setTitle(CarStrings.get(R.string.car_history)) .setImage(CarIcon.Builder(IconCompat.createWithResource(carContext, android.R.drawable.ic_menu_recent_history)).build()) .setOnClickListener { screenManager.push(HistoryScreen(carContext)) } .setBrowsable(true) @@ -106,7 +106,7 @@ class MainCarScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc menuListBuilder.addItem( Row.Builder() - .setTitle("Download") + .setTitle(CarStrings.get(R.string.car_downloads)) .setImage(CarIcon.Builder(IconCompat.createWithResource(carContext, android.R.drawable.stat_sys_download)).build()) .setOnClickListener { screenManager.push(DownloadsScreen(carContext)) } .setBrowsable(true) @@ -115,8 +115,8 @@ class MainCarScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc menuListBuilder.addItem( Row.Builder() - .setTitle("Provider") - .addText("Attuale: $currentApiName") + .setTitle(CarStrings.get(R.string.car_provider)) + .addText("${CarStrings.get(R.string.car_current)}: $currentApiName") .setImage(CarIcon.Builder(IconCompat.createWithResource(carContext, android.R.drawable.ic_menu_manage)).build()) .setOnClickListener { screenManager.push(ProviderCarScreen(carContext)) } .setBrowsable(true) @@ -129,11 +129,11 @@ class MainCarScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc val contentListBuilder = ItemList.Builder() if (isLoading) { - contentListBuilder.addItem(Row.Builder().setTitle("Caricamento contenuti...").setBrowsable(false).build()) + contentListBuilder.addItem(Row.Builder().setTitle(CarStrings.get(R.string.car_loading)).setBrowsable(false).build()) } else if (errorMessage != null) { - contentListBuilder.addItem(Row.Builder().setTitle("Errore: $errorMessage").setBrowsable(false).build()) + contentListBuilder.addItem(Row.Builder().setTitle("${CarStrings.get(R.string.car_error)}: $errorMessage").setBrowsable(false).build()) } else if (homePageLists.isEmpty()) { - contentListBuilder.addItem(Row.Builder().setTitle("Nessun contenuto dal provider").setBrowsable(false).build()) + contentListBuilder.addItem(Row.Builder().setTitle(CarStrings.get(R.string.car_no_content_from_provider)).setBrowsable(false).build()) } else { homePageLists.forEach { homePageList -> contentListBuilder.addItem( @@ -155,13 +155,13 @@ class MainCarScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc .addSectionedList( SectionedItemList.create( menuListBuilder.build(), - "Menu" + CarStrings.get(R.string.car_menu) ) ) .addSectionedList( SectionedItemList.create( contentListBuilder.build(), - "Contenuti Home" + CarStrings.get(R.string.car_home_content) ) ) .setActionStrip( diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt index e2bddf2d227..aec339e9450 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/PlayerCarScreen.kt @@ -158,7 +158,7 @@ class PlayerCarScreen( } private fun loadMedia(url: String?) { - updateStatus("Caricamento...") + updateStatus(CarStrings.get(R.string.car_loading)) scope.launch { // If we already have the LoadResponse (passed from Details), use it. // Otherwise, fetch it using item.url @@ -177,7 +177,7 @@ class PlayerCarScreen( } if (data == null) { - showToast("Impossibile caricare i dettagli") + showToast(CarStrings.get(R.string.car_unable_to_load_details)) return@launch } @@ -221,7 +221,7 @@ class PlayerCarScreen( } if (urlToLoad == null) { - showToast("Nessun contenuto riproducibile trovato") + showToast(CarStrings.get(R.string.car_no_playable_content)) return@launch } @@ -238,11 +238,11 @@ class PlayerCarScreen( val bestLink = links.sortedByDescending { it.quality }.first() startPlayback(bestLink) } else { - showToast("Nessun link trovato") + showToast(CarStrings.get(R.string.car_no_link_found)) } } } catch (e: Exception) { - showToast("Errore caricamento link: ${e.message}") + showToast("${CarStrings.get(R.string.car_error_loading_links)}: ${e.message}") e.printStackTrace() } } @@ -304,7 +304,7 @@ class PlayerCarScreen( } withContext(Dispatchers.Main) { - updateStatus("Avvio riproduzione...") + updateStatus(CarStrings.get(R.string.car_starting_playback)) if (player == null) { player = ExoPlayer.Builder(carContext).build().apply { val audioAttributes = AudioAttributes.Builder() @@ -350,7 +350,7 @@ class PlayerCarScreen( p.seekTo(startTime) } p.play() - updateStatus("In riproduzione") + updateStatus(CarStrings.get(R.string.car_playing)) // Start periodic save loop // startSaveLoop() @@ -443,7 +443,7 @@ class PlayerCarScreen( VIDEO_SCALING_MODE_SCALE_TO_FIT } player?.videoScalingMode = resizeMode - showToast(if (resizeMode == VIDEO_SCALING_MODE_SCALE_TO_FIT) "Adatta allo schermo" else "Riempi schermo") + showToast(if (resizeMode == VIDEO_SCALING_MODE_SCALE_TO_FIT) CarStrings.get(R.string.car_fit_to_screen) else CarStrings.get(R.string.car_fill_screen)) } .build() diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/ProviderCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/ProviderCarScreen.kt index fd730dbe2f8..e2f86a2f4e4 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/ProviderCarScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/ProviderCarScreen.kt @@ -7,6 +7,7 @@ import androidx.car.app.model.ItemList import androidx.car.app.model.ListTemplate import androidx.car.app.model.Row import androidx.car.app.model.Template +import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.APIHolder.apis import com.lagradost.cloudstream3.utils.DataStoreHelper @@ -26,7 +27,7 @@ class ProviderCarScreen(carContext: CarContext) : Screen(carContext) { } if (api.name == current) { - row.addText("Selected") + row.addText(CarStrings.get(R.string.car_selected)) } listBuilder.addItem(row.build()) @@ -34,7 +35,7 @@ class ProviderCarScreen(carContext: CarContext) : Screen(carContext) { return ListTemplate.Builder() .setSingleList(listBuilder.build()) - .setTitle("Select Provider") + .setTitle(CarStrings.get(R.string.car_select_provider)) .setHeaderAction(Action.BACK) .build() } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/SearchCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/SearchCarScreen.kt index 7f198e4c733..2c92c8678b1 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/SearchCarScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/SearchCarScreen.kt @@ -50,7 +50,7 @@ class SearchCarScreen(carContext: CarContext) : Screen(carContext) { val builder = ItemList.Builder() val items = result.value.items if (items.isEmpty()) { - builder.setNoItemsMessage("Nessun risultato trovato") + builder.setNoItemsMessage(CarStrings.get(R.string.car_no_results_found)) } // Text-only results @@ -88,7 +88,7 @@ class SearchCarScreen(carContext: CarContext) : Screen(carContext) { override fun onGetTemplate(): Template { return SearchTemplate.Builder(searchCallback) - .setSearchHint("Cerca film e serie TV...") + .setSearchHint("${CarStrings.get(R.string.car_search)}...") .setHeaderAction(Action.BACK) .setShowKeyboardByDefault(true) .setItemList(itemList ?: ItemList.Builder().build()) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/SourceSelectionScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/SourceSelectionScreen.kt index 634123be788..ba49f0f6e4a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/SourceSelectionScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/SourceSelectionScreen.kt @@ -52,7 +52,7 @@ class SourceSelectionScreen( try { val api = getApiFromNameNull(apiName) if (api == null) { - errorMessage = "Provider non trovato" + errorMessage = CarStrings.get(R.string.car_provider_not_found) isLoading = false invalidate() return@launch @@ -65,7 +65,7 @@ class SourceSelectionScreen( withContext(Dispatchers.Main) { if (links.isEmpty()) { - errorMessage = "Nessuna sorgente trovata" + errorMessage = CarStrings.get(R.string.car_no_source_found) } else { // Sort by quality (highest first) sources = links.sortedByDescending { it.quality } @@ -75,7 +75,7 @@ class SourceSelectionScreen( } } catch (e: Exception) { withContext(Dispatchers.Main) { - errorMessage = "Errore: ${e.message}" + errorMessage = "${CarStrings.get(R.string.car_error)}: ${e.message}" isLoading = false invalidate() } @@ -85,7 +85,7 @@ class SourceSelectionScreen( override fun onGetTemplate(): Template { val templateBuilder = ListTemplate.Builder() - .setTitle("Sorgenti") + .setTitle(CarStrings.get(R.string.car_sources)) .setHeaderAction(Action.BACK) if (isLoading) { @@ -98,7 +98,7 @@ class SourceSelectionScreen( if (errorMessage != null) { listBuilder.setNoItemsMessage(errorMessage!!) } else if (sources.isEmpty()) { - listBuilder.setNoItemsMessage("Nessuna sorgente disponibile") + listBuilder.setNoItemsMessage(CarStrings.get(R.string.car_no_source_available)) } else { // Add each source as a row for (source in sources) { @@ -114,7 +114,7 @@ class SourceSelectionScreen( .addText(source.source) .setOnClickListener { onSourceSelected(source) - CarToast.makeText(carContext, "Sorgente selezionata: ${source.name}", CarToast.LENGTH_SHORT).show() + CarToast.makeText(carContext, "${CarStrings.get(R.string.car_source_selected)}: ${source.name}", CarToast.LENGTH_SHORT).show() screenManager.pop() } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/TvSeriesDetailScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/TvSeriesDetailScreen.kt index 82f786c034e..4b4b3aef050 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/TvSeriesDetailScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/TvSeriesDetailScreen.kt @@ -16,10 +16,10 @@ import coil3.asDrawable import coil3.request.ImageRequest import coil3.SingletonImageLoader import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull +import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.LoadResponse import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.TvSeriesLoadResponse -import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.ui.APIRepository import com.lagradost.cloudstream3.utils.DataStoreHelper @@ -77,18 +77,18 @@ class TvSeriesDetailScreen( val id = data.url.replace(api.mainUrl, "").replace("/", "").hashCode() isFavorite = DataStoreHelper.getFavoritesData(id) != null } else { - errorMessage = "Non è una serie TV" + errorMessage = CarStrings.get(R.string.car_not_tv_series) } isLoading = false } is Resource.Failure -> { - errorMessage = result.errorString ?: "Errore caricamento dettagli" + errorMessage = result.errorString ?: CarStrings.get(R.string.car_error_loading_details) isLoading = false } is Resource.Loading -> {} } } else { - errorMessage = "Provider non trovato" + errorMessage = CarStrings.get(R.string.car_provider_not_found) isLoading = false } invalidate() @@ -103,7 +103,7 @@ class TvSeriesDetailScreen( if (isFavorite) { DataStoreHelper.removeFavoritesData(id) isFavorite = false - androidx.car.app.CarToast.makeText(carContext, "Rimosso dai preferiti", androidx.car.app.CarToast.LENGTH_SHORT).show() + androidx.car.app.CarToast.makeText(carContext, CarStrings.get(R.string.car_removed_from_favorites), androidx.car.app.CarToast.LENGTH_SHORT).show() } else { val favoritesData = FavoritesData( favoritesTime = System.currentTimeMillis(), @@ -123,7 +123,7 @@ class TvSeriesDetailScreen( ) DataStoreHelper.setFavoritesData(id, favoritesData) isFavorite = true - androidx.car.app.CarToast.makeText(carContext, "Aggiunto ai preferiti", androidx.car.app.CarToast.LENGTH_SHORT).show() + androidx.car.app.CarToast.makeText(carContext, CarStrings.get(R.string.car_added_to_favorites), androidx.car.app.CarToast.LENGTH_SHORT).show() } invalidate() } @@ -165,7 +165,7 @@ class TvSeriesDetailScreen( // details.seasonNames could be used, or just aggregating episodes val seasonCount = details.episodes.mapNotNull { it.season }.distinct().count() if (metaStringBuilder.isNotEmpty()) metaStringBuilder.append(" • ") - metaStringBuilder.append("$seasonCount Stagioni") + metaStringBuilder.append("$seasonCount ${CarStrings.get(R.string.car_seasons)}") if (metaStringBuilder.isNotEmpty()) { paneBuilder.addRow( @@ -195,7 +195,7 @@ class TvSeriesDetailScreen( // "Episode List >" paneBuilder.addAction( Action.Builder() - .setTitle("Lista Episodi") + .setTitle(CarStrings.get(R.string.car_episode_list)) .setBackgroundColor(CarColor.PRIMARY) .setOnClickListener { screenManager.push(EpisodeListScreen(carContext, details)) @@ -209,7 +209,7 @@ class TvSeriesDetailScreen( if (!details.plot.isNullOrEmpty()) { paneBuilder.addRow( Row.Builder() - .setTitle("Trama") + .setTitle(CarStrings.get(R.string.car_plot)) .addText(details.plot!!) .build() ) @@ -229,7 +229,7 @@ class TvSeriesDetailScreen( paneBuilder.addRow( Row.Builder() - .setTitle("Cast") + .setTitle(CarStrings.get(R.string.car_cast)) .addText(s) .build() ) @@ -237,7 +237,7 @@ class TvSeriesDetailScreen( } } else if (errorMessage != null) { - paneBuilder.addRow(Row.Builder().setTitle("Errore: $errorMessage").build()) + paneBuilder.addRow(Row.Builder().setTitle("${CarStrings.get(R.string.car_error)}: $errorMessage").build()) } } diff --git a/app/src/main/res-car/values-b+af/strings_car.xml b/app/src/main/res-car/values-b+af/strings_car.xml new file mode 100644 index 00000000000..f39d2aacfe2 --- /dev/null +++ b/app/src/main/res-car/values-b+af/strings_car.xml @@ -0,0 +1,51 @@ + + + Laai tans... + Fout + Fout met laai van inhoud + Gunstelinge + Geskiedenis + Aflaaie + Verskaffer + Huidige + Kieslys + Tuisinhoud + Geen inhoud van verskaffer + Verskaffer nie gevind nie + Bron + Bronne + Storielyn + Rolverdeling + Fout met laai van besonderhede + Episode lys + Seisoen + Seisoene + Episode + Geen episodes gevind nie + Nie \'n TV-reeks nie + By gunstelinge gevoeg + Van gunstelinge verwyder + Geen gunstelinge gevind nie + Begin terugspeel... + Speel tans + Geen skakel gevind nie + Geen speelbare inhoud gevind nie + Kan nie besonderhede laai nie + Fout met laai van skakels + Pas by skerm + Vul skerm + Geen bron gevind nie + Geen bron beskikbaar nie + Bron gekies + Soek + Geen resultate gevind nie + \'Gaan voort om te kyk\' nie gevind nie + Geen aflaaie gevind nie + Lêer nie gevind nie + Geen geldige episode gevind nie + Kies Verskaffer + Gekies + Biblioteek + Boekmerke + Hervat %1$s... + diff --git a/app/src/main/res-car/values-b+am/strings_car.xml b/app/src/main/res-car/values-b+am/strings_car.xml new file mode 100644 index 00000000000..73d1b93ae2e --- /dev/null +++ b/app/src/main/res-car/values-b+am/strings_car.xml @@ -0,0 +1,51 @@ + + + በመጫን ላይ... + ስህተት + ይዘት በመጫን ላይ ስህተት + ተወዳጆች + ታሪክ + ውርዶች + አቅራቢ + የአሁኑ + ምናሌ + የመነሻ ይዘት + ከአቅራቢው ምንም ይዘት የለም + አቅራቢ አልተገኘም + ምንጭ + ምንጮች + ሴራ + ተዋንያን + ዝርዝሮችን በመጫን ላይ ስህተት + የክፍሎች ዝርዝር + ወቅት + ወቅቶች + ክፍል + ምንም ክፍሎች አልተገኙም + የቲቪ ተከታታይ አይደለም + ወደ ተወዳጆች ታክሏል + ከተወዳጆች ተወግዷል + ምንም ተወዳጆች አልተገኙም + ማጫወት በመጀመር ላይ... + በማጫወት ላይ + ምንም አገናኝ አልተገኘም + ምንም የሚጫወት ይዘት አልተገኘም + ዝርዝሮችን መጫን አልተቻለም + አገናኞችን በመጫን ላይ ስህተት + ስክሪን ላይ ይግጠም + ስክሪን ይሙሉ + ምንም ምንጭ አልተገኘም + ምንም ምንጭ የለም + ምንጭ ተመርጧል + ፈልግ + ምንም ውጤቶች አልተገኙም + \'መመልከት ይቀጥሉ\' አልተገኘም + ምንም ውርዶች አልተገኙም + ፋይል አልተገኘም + ምንም ትክክለኛ ክፍል አልተገኘም + አቅራቢ ይምረጡ + ተመርጧል + ቤተ-መጽሐፍት + ዕልባቶች + %1$s በመቀጠል ላይ... + diff --git a/app/src/main/res-car/values-b+apc/strings_car.xml b/app/src/main/res-car/values-b+apc/strings_car.xml new file mode 100644 index 00000000000..ac0a25531bb --- /dev/null +++ b/app/src/main/res-car/values-b+apc/strings_car.xml @@ -0,0 +1,74 @@ + + + + Loading... + Error + Error loading content + + + Favorites + History + Downloads + Provider + Current + Menu + Home Content + No content from provider + Provider not found + + + Source + Sources + Plot + Cast + Error loading details + + + Episode List + Season + Seasons + Episode + No episodes found + Not a TV series + + + Added to favorites + Removed from favorites + No favorites found + + + Starting playback... + Playing + No link found + No playable content found + Unable to load details + Error loading links + Fit to screen + Fill screen + + + No source found + No source available + Source selected + + + Search + No results found + + + No \'Continue watching\' items found + + + No completed downloads found + File not found + No valid episode found + + + Select Provider + Selected + + + Library + Bookmarks + Resuming %1$s... + diff --git a/app/src/main/res-car/values-b+ar/strings_car.xml b/app/src/main/res-car/values-b+ar/strings_car.xml new file mode 100644 index 00000000000..2f75de73f8e --- /dev/null +++ b/app/src/main/res-car/values-b+ar/strings_car.xml @@ -0,0 +1,51 @@ + + + جارٍ التحميل... + خطأ + خطأ في تحميل المحتوى + المفضلة + السجل + التنزيلات + المزود + الحالي + القائمة + محتوى الصفحة الرئيسية + لا يوجد محتوى من المزود + المزود غير موجود + المصدر + المصادر + القصة + الممثلون + خطأ في تحميل التفاصيل + قائمة الحلقات + الموسم + المواسم + الحلقة + لم يتم العثور على حلقات + ليس مسلسلاً تلفزيونياً + تمت الإضافة إلى المفضلة + تمت الإزالة من المفضلة + لم يتم العثور على مفضلة + بدء التشغيل... + تشغيل + لم يتم العثور على رابط + لم يتم العثور على محتوى قابل للتشغيل + تعذر تحميل التفاصيل + خطأ في تحميل الروابط + ملاءمة للشاشة + ملء الشاشة + لم يتم العثور على مصدر + لا يوجد مصدر متاح + تم اختيار المصدر + بحث + لم يتم العثور على نتائج + لم يتم العثور على \'متابعة المشاهدة\' + لم يتم العثور على تنزيلات + الملف غير موجود + لا توجد حلقة صالحة + اختر المزود + محدد + المكتبة + الإشارات المرجعية + استئناف %1$s... + diff --git a/app/src/main/res-car/values-b+ars/strings_car.xml b/app/src/main/res-car/values-b+ars/strings_car.xml new file mode 100644 index 00000000000..ac0a25531bb --- /dev/null +++ b/app/src/main/res-car/values-b+ars/strings_car.xml @@ -0,0 +1,74 @@ + + + + Loading... + Error + Error loading content + + + Favorites + History + Downloads + Provider + Current + Menu + Home Content + No content from provider + Provider not found + + + Source + Sources + Plot + Cast + Error loading details + + + Episode List + Season + Seasons + Episode + No episodes found + Not a TV series + + + Added to favorites + Removed from favorites + No favorites found + + + Starting playback... + Playing + No link found + No playable content found + Unable to load details + Error loading links + Fit to screen + Fill screen + + + No source found + No source available + Source selected + + + Search + No results found + + + No \'Continue watching\' items found + + + No completed downloads found + File not found + No valid episode found + + + Select Provider + Selected + + + Library + Bookmarks + Resuming %1$s... + diff --git a/app/src/main/res-car/values-b+as/strings_car.xml b/app/src/main/res-car/values-b+as/strings_car.xml new file mode 100644 index 00000000000..ac0a25531bb --- /dev/null +++ b/app/src/main/res-car/values-b+as/strings_car.xml @@ -0,0 +1,74 @@ + + + + Loading... + Error + Error loading content + + + Favorites + History + Downloads + Provider + Current + Menu + Home Content + No content from provider + Provider not found + + + Source + Sources + Plot + Cast + Error loading details + + + Episode List + Season + Seasons + Episode + No episodes found + Not a TV series + + + Added to favorites + Removed from favorites + No favorites found + + + Starting playback... + Playing + No link found + No playable content found + Unable to load details + Error loading links + Fit to screen + Fill screen + + + No source found + No source available + Source selected + + + Search + No results found + + + No \'Continue watching\' items found + + + No completed downloads found + File not found + No valid episode found + + + Select Provider + Selected + + + Library + Bookmarks + Resuming %1$s... + diff --git a/app/src/main/res-car/values-b+az/strings_car.xml b/app/src/main/res-car/values-b+az/strings_car.xml new file mode 100644 index 00000000000..2d7a522db98 --- /dev/null +++ b/app/src/main/res-car/values-b+az/strings_car.xml @@ -0,0 +1,51 @@ + + + Yüklənir... + Xəta + Məzmun yüklənərkən xəta + Sevimlilər + Tarixçə + Yükləmələr + Provayder + Cari + Menyu + Ana səhifə məzmunu + Provayderdən məzmun yoxdur + Provayder tapılmadı + Mənbə + Mənbələr + Süjet + Rollarda + Təfərrüatları yükləyərkən xəta + Epizod siyahısı + Mövsüm + Mövsümlər + Epizod + Epizod tapılmadı + TV serialı deyil + Sevimlilərə əlavə edildi + Sevimlilərdən silindi + Sevimli tapılmadı + Oxutma başlayır... + Oxudulur + Link tapılmadı + Oxudula bilən məzmun tapılmadı + Təfərrüatları yükləmək mümkün olmadı + Linkləri yükləyərkən xəta + Ekranı uyğunlaşdır + Ekranı doldur + Mənbə tapılmadı + Mövcud mənbə yoxdur + Mənbə seçildi + Axtarış + Nəticə tapılmadı + \'İzləməyə davam et\' tapılmadı + Yükləmə tapılmadı + Fayl tapılmadı + Etibarlı epizod tapılmadı + Provayder seç + Seçildi + Kitabxana + Əlfəcinlər + %1$s davam etdirilir... + diff --git a/app/src/main/res-car/values-b+be/strings_car.xml b/app/src/main/res-car/values-b+be/strings_car.xml new file mode 100644 index 00000000000..4601e262724 --- /dev/null +++ b/app/src/main/res-car/values-b+be/strings_car.xml @@ -0,0 +1,51 @@ + + + Загрузка... + Памылка + Памылка загрузкі кантэнту + Выбранае + Гісторыя + Спампоўкі + Пастаўшчык + Бягучы + Меню + Галоўны кантэнт + Няма кантэнту ад пастаўшчыка + Пастаўшчык не знойдзены + Крыніца + Крыніцы + Сюжэт + Акцёры + Памылка загрузкі дэталяў + Спіс серый + Сезон + Сезоны + Серыя + Серый не знойдзена + Не серыял + Дададзена ў выбранае + Выдалена з выбранага + Няма выбранага + Пачатак прайгравання... + Прайграванне + Спасылка не знойдзена + Няма кантэнту для прайгравання + Не ўдалося загрузіць дэталі + Памылка загрузкі спасылак + Па памеры экрана + Запоўніць экран + Крыніца не знойдзена + Няма даступных крыніц + Крыніца выбрана + Пошук + Вынікаў не знойдзена + \'Працягнуць прагляд\' не знойдзена + Няма спамповак + Файл не знойдзены + Няма сапраўднай серыі + Выберыце пастаўшчыка + Выбрана + Бібліятэка + Закладкі + Аднаўленне %1$s... + diff --git a/app/src/main/res-car/values-b+bg/strings_car.xml b/app/src/main/res-car/values-b+bg/strings_car.xml new file mode 100644 index 00000000000..9c7ba83e426 --- /dev/null +++ b/app/src/main/res-car/values-b+bg/strings_car.xml @@ -0,0 +1,51 @@ + + + Зареждане... + Грешка + Грешка при зареждане на съдържание + Любими + История + Изтегляния + Доставчик + Текущ + Меню + Начално съдържание + Няма съдържание от доставчика + Доставчикът не е намерен + Източник + Източници + Сюжет + Актьорски състав + Грешка при зареждане на детайли + Списък с епизоди + Сезон + Сезони + Епизод + Няма намерени епизоди + Не е ТВ сериал + Добавено към любими + Премахнато от любими + Няма намерени любими + Стартиране на възпроизвеждане... + Възпроизвеждане + Няма намерена връзка + Няма намерено съдържание за възпроизвеждане + Не може да се заредят детайли + Грешка при зареждане на връзки + Побиране на екрана + Запълване на екрана + Няма намерен източник + Няма наличен източник + Избран източник + Търсене + Няма намерени резултати + Няма намерено \'Продължи гледането\' + Няма намерени изтегляния + Файлът не е намерен + Няма намерен валиден епизод + Избор на доставчик + Избрано + Библиотека + Отметки + Възобновяване %1$s... + diff --git a/app/src/main/res-car/values-b+bn/strings_car.xml b/app/src/main/res-car/values-b+bn/strings_car.xml new file mode 100644 index 00000000000..fb8281709e4 --- /dev/null +++ b/app/src/main/res-car/values-b+bn/strings_car.xml @@ -0,0 +1,51 @@ + + + লোড হচ্ছে... + ত্রুটি + কন্টেন্ট লোড করতে ত্রুটি + পছন্দ + ইতিহাস + ডাউনলোড + প্রদানকারী + বর্তমান + মেনু + হোম কন্টেন্ট + প্রদানকারী থেকে কোন কন্টেন্ট নেই + প্রদানকারী পাওয়া যায়নি + উৎস + উৎসসমূহ + কাহিনী + কুশীলব + বিস্তারিত লোড করতে ত্রুটি + পর্বের তালিকা + সিজন + সিজনসমূহ + পর্ব + কোন পর্ব পাওয়া যায়নি + টিভি সিরিজ নয় + পছন্দে যোগ করা হয়েছে + পছন্দ থেকে সরানো হয়েছে + কোন পছন্দ পাওয়া যায়নি + প্লেব্যাক শুরু হচ্ছে... + চলছে + কোন লিঙ্ক পাওয়া যায়নি + কোন চালানোর যোগ্য কন্টেন্ট পাওয়া যায়নি + বিস্তারিত লোড করা যায়নি + লিঙ্ক লোড করতে ত্রুটি + স্ক্রিনে মানানসই করুন + স্ক্রিন পূর্ণ করুন + কোন উৎস পাওয়া যায়নি + কোন উৎস উপলব্ধ নেই + উৎস নির্বাচিত + অনুসন্ধান + কোন ফলাফল পাওয়া যায়নি + \'দেখা চালিয়ে যান\' পাওয়া যায়নি + কোন ডাউনলোড পাওয়া যায়নি + ফাইল পাওয়া যায়নি + কোন বৈধ পর্ব পাওয়া যায়নি + প্রদানকারী নির্বাচন করুন + নির্বাচিত + লাইব্রেরি + বুকমার্ক + %1$s পুনরায় শুরু হচ্ছে... + diff --git a/app/src/main/res-car/values-b+bs/strings_car.xml b/app/src/main/res-car/values-b+bs/strings_car.xml new file mode 100644 index 00000000000..dfbc9fef949 --- /dev/null +++ b/app/src/main/res-car/values-b+bs/strings_car.xml @@ -0,0 +1,51 @@ + + + Učitavanje... + Greška + Greška pri učitavanju sadržaja + Omiljeni + Historija + Preuzimanja + Provajder + Trenutno + Meni + Početni sadržaj + Nema sadržaja od provajdera + Provajder nije pronađen + Izvor + Izvori + Radnja + Uloge + Greška pri učitavanju detalja + Lista epizoda + Sezona + Sezone + Epizoda + Nema pronađenih epizoda + Nije TV serija + Dodano u omiljene + Uklonjeno iz omiljenih + Nema omiljenih + Pokretanje reprodukcije... + Reprodukcija + Link nije pronađen + Sadržaj za reprodukciju nije pronađen + Nije moguće učitati detalje + Greška pri učitavanju linkova + Prilagodi ekranu + Popuni ekran + Izvor nije pronađen + Izvor nije dostupan + Izvor odabran + Pretraga + Nema rezultata + \'Nastavi gledanje\' nije pronađeno + Nema preuzimanja + Datoteka nije pronađena + Nema važeće epizode + Izaberi provajdera + Odabrano + Biblioteka + Obeleživači + Nastavljanje %1$s... + diff --git a/app/src/main/res-car/values-b+ca/strings_car.xml b/app/src/main/res-car/values-b+ca/strings_car.xml new file mode 100644 index 00000000000..6a7e285ec11 --- /dev/null +++ b/app/src/main/res-car/values-b+ca/strings_car.xml @@ -0,0 +1,51 @@ + + + Carregant... + Error + Error carregant contingut + Preferits + Historial + Descàrregues + Proveïdor + Actual + Menú + Contingut d\'inici + Sense contingut del proveïdor + Proveïdor no trobat + Font + Fonts + Argument + Repartiment + Error carregant detalls + Llista d\'episodis + Temporada + Temporades + Episodi + No s\'han trobat episodis + No és una sèrie de TV + Afegit a preferits + Eliminat de preferits + Cap preferit trobat + Iniciant reproducció... + Reproduint + Enllaç no trobat + Contingut reproduïble no trobat + No es poden carregar els detalls + Error carregant enllaços + Ajustar a la pantalla + Omplir la pantalla + Font no trobada + Cap font disponible + Font seleccionada + Cercar + Sense resultats + \'Continuar mirant\' no trobat + Sense descàrregues + Fitxer no trobat + Cap episodi vàlid + Seleccionar proveïdor + Seleccionat + Biblioteca + Marcadors + Reprenent %1$s... + diff --git a/app/src/main/res-car/values-b+ckb/strings_car.xml b/app/src/main/res-car/values-b+ckb/strings_car.xml new file mode 100644 index 00000000000..ac0a25531bb --- /dev/null +++ b/app/src/main/res-car/values-b+ckb/strings_car.xml @@ -0,0 +1,74 @@ + + + + Loading... + Error + Error loading content + + + Favorites + History + Downloads + Provider + Current + Menu + Home Content + No content from provider + Provider not found + + + Source + Sources + Plot + Cast + Error loading details + + + Episode List + Season + Seasons + Episode + No episodes found + Not a TV series + + + Added to favorites + Removed from favorites + No favorites found + + + Starting playback... + Playing + No link found + No playable content found + Unable to load details + Error loading links + Fit to screen + Fill screen + + + No source found + No source available + Source selected + + + Search + No results found + + + No \'Continue watching\' items found + + + No completed downloads found + File not found + No valid episode found + + + Select Provider + Selected + + + Library + Bookmarks + Resuming %1$s... + diff --git a/app/src/main/res-car/values-b+cs/strings_car.xml b/app/src/main/res-car/values-b+cs/strings_car.xml new file mode 100644 index 00000000000..d9011304d0a --- /dev/null +++ b/app/src/main/res-car/values-b+cs/strings_car.xml @@ -0,0 +1,51 @@ + + + Načítání... + Chyba + Chyba při načítání obsahu + Oblíbené + Historie + Stažené + Poskytovatel + Aktuální + Menu + Domovský obsah + Žádný obsah od poskytovatele + Poskytovatel nenalezen + Zdroj + Zdroje + Děj + Obsazení + Chyba při načítání podrobností + Seznam epizod + Série + Série + Epizoda + Nenalezeny žádné epizody + Není TV seriál + Přidáno do oblíbených + Odebráno z oblíbených + Nenalezeny žádné oblíbené + Spouštění přehrávání... + Přehrávání + Odkaz nenalezen + Nenalezen žádný přehrávatelný obsah + Nelze načíst podrobnosti + Chyba při načítání odkazů + Přizpůsobit obrazovce + Vyplnit obrazovku + Zdroj nenalezen + Žádný zdroj k dispozici + Zdroj vybrán + Hledat + Nenalezeny žádné výsledky + Nenalezeno \'Pokračovat ve sledování\' + Nenalezeny žádné stažené soubory + Soubor nenalezen + Nenalezena žádná platná epizoda + Vybrat poskytovatele + Vybráno + Knihovna + Záložky + Obnovování %1$s... + diff --git a/app/src/main/res-car/values-b+da/strings_car.xml b/app/src/main/res-car/values-b+da/strings_car.xml new file mode 100644 index 00000000000..afb929b5b50 --- /dev/null +++ b/app/src/main/res-car/values-b+da/strings_car.xml @@ -0,0 +1,51 @@ + + + Indlæser... + Fejl + Fejl ved indlæsning af indhold + Favoritter + Historik + Downloads + Udbydere + Nuværende + Menu + Hjemmeindhold + Intet indhold fra udbyder + Udbyder ikke fundet + Kilde + Kilder + Handling + Medvirkende + Fejl ved indlæsning af detaljer + Afsnitsliste + Sæson + Sæsoner + Afsnit + Ingen afsnit fundet + Ikke en TV-serie + Tilføjet til favoritter + Fjernet fra favoritter + Ingen favoritter fundet + Starter afspilning... + Afspiller + Intet link fundet + Intet afspilleligt indhold fundet + Kunne ikke indlæse detaljer + Fejl ved indlæsning af links + Tilpas til skærm + Fyld skærm + Ingen kilde fundet + Ingen kilde tilgængelig + Kilde valgt + Søg + Ingen resultater fundet + \'Fortsæt med at se\' ikke fundet + Ingen downloads fundet + Fil ikke fundet + Intet gyldigt afsnit fundet + Vælg udbyder + Valgt + Bibliotek + Bogmærker + Genoptager %1$s... + diff --git a/app/src/main/res-car/values-b+de/strings_car.xml b/app/src/main/res-car/values-b+de/strings_car.xml new file mode 100644 index 00000000000..2c88723f817 --- /dev/null +++ b/app/src/main/res-car/values-b+de/strings_car.xml @@ -0,0 +1,51 @@ + + + Laden... + Fehler + Fehler beim Laden des Inhalts + Favoriten + Verlauf + Downloads + Anbieter + Aktuell + Menü + Startseiteninhalt + Kein Inhalt vom Anbieter + Anbieter nicht gefunden + Quelle + Quellen + Handlung + Besetzung + Fehler beim Laden der Details + Episodenliste + Staffel + Staffeln + Episode + Keine Episoden gefunden + Keine TV-Serie + Zu Favoriten hinzugefügt + Aus Favoriten entfernt + Keine Favoriten gefunden + Wiedergabe wird gestartet... + Wiedergabe + Kein Link gefunden + Kein abspielbarer Inhalt gefunden + Details konnten nicht geladen werden + Fehler beim Laden der Links + An Bildschirm anpassen + Bildschirm füllen + Keine Quelle gefunden + Keine Quelle verfügbar + Quelle ausgewählt + Suchen + Keine Ergebnisse gefunden + Keine \'Weiterschauen\'-Elemente gefunden + Keine Downloads gefunden + Datei nicht gefunden + Keine gültige Episode gefunden + Anbieter auswählen + Ausgewählt + Bibliothek + Lesezeichen + Setze %1$s fort... + diff --git a/app/src/main/res-car/values-b+el/strings_car.xml b/app/src/main/res-car/values-b+el/strings_car.xml new file mode 100644 index 00000000000..fd08dfb2f56 --- /dev/null +++ b/app/src/main/res-car/values-b+el/strings_car.xml @@ -0,0 +1,51 @@ + + + Φόρτωση... + Σφάλμα + Σφάλμα φόρτωσης περιεχομένου + Αγαπημένα + Ιστορικό + Λήψεις + Πάροχος + Τρέχον + Μενού + Περιεχόμενο αρχικής σελίδας + Δεν υπάρχει περιεχόμενο από τον πάροχο + Ο πάροχος δεν βρέθηκε + Πηγή + Πηγές + Πλοκή + Ηθοποιοί + Σφάλμα φόρτωσης λεπτομερειών + Λίστα επεισοδίων + Σεζόν + Σεζόν + Επεισόδιο + Δεν βρέθηκαν επεισόδια + Δεν είναι τηλεοπτική σειρά + Προστέθηκε στα αγαπημένα + Αφαιρέθηκε από τα αγαπημένα + Δεν βρέθηκαν αγαπημένα + Έναρξη αναπαραγωγής... + Αναπαραγωγή + Δεν βρέθηκε σύνδεσμος + Δεν βρέθηκε περιεχόμενο για αναπαραγωγή + Αδυναμία φόρτωσης λεπτομερειών + Σφάλμα φόρτωσης συνδέσμων + Προσαρμογή στην οθόνη + Γέμισμα οθόνης + Δεν βρέθηκε πηγή + Καμία διαθέσιμη πηγή + Επιλέχθηκε πηγή + Αναζήτηση + Δεν βρέθηκαν αποτελέσματα + Δεν βρέθηκε \'Συνέχεια παρακολούθησης\' + Δεν βρέθηκαν λήψεις + Το αρχείο δεν βρέθηκε + Δεν βρέθηκε έγκυρο επεισόδιο + Επιλογή παρόχου + Επιλεγμένο + Βιβλιοθήκη + Σελιδοδείκτες + Συνέχιση %1$s... + diff --git a/app/src/main/res-car/values-b+eo/strings_car.xml b/app/src/main/res-car/values-b+eo/strings_car.xml new file mode 100644 index 00000000000..ac0a25531bb --- /dev/null +++ b/app/src/main/res-car/values-b+eo/strings_car.xml @@ -0,0 +1,74 @@ + + + + Loading... + Error + Error loading content + + + Favorites + History + Downloads + Provider + Current + Menu + Home Content + No content from provider + Provider not found + + + Source + Sources + Plot + Cast + Error loading details + + + Episode List + Season + Seasons + Episode + No episodes found + Not a TV series + + + Added to favorites + Removed from favorites + No favorites found + + + Starting playback... + Playing + No link found + No playable content found + Unable to load details + Error loading links + Fit to screen + Fill screen + + + No source found + No source available + Source selected + + + Search + No results found + + + No \'Continue watching\' items found + + + No completed downloads found + File not found + No valid episode found + + + Select Provider + Selected + + + Library + Bookmarks + Resuming %1$s... + diff --git a/app/src/main/res-car/values-b+es/strings_car.xml b/app/src/main/res-car/values-b+es/strings_car.xml new file mode 100644 index 00000000000..515293d8a82 --- /dev/null +++ b/app/src/main/res-car/values-b+es/strings_car.xml @@ -0,0 +1,51 @@ + + + Cargando... + Error + Error al cargar contenido + Favoritos + Historial + Descargas + Proveedor + Actual + Menú + Contenido de inicio + Sin contenido del proveedor + Proveedor no encontrado + Fuente + Fuentes + Trama + Reparto + Error al cargar detalles + Lista de episodios + Temporada + Temporadas + Episodio + No se encontraron episodios + No es una serie de TV + Añadido a favoritos + Eliminado de favoritos + No se encontraron favoritos + Iniciando reproducción... + Reproduciendo + No se encontró enlace + No se encontró contenido reproducible + No se pudieron cargar los detalles + Error al cargar enlaces + Ajustar a la pantalla + Llenar pantalla + No se encontró fuente + Ninguna fuente disponible + Fuente seleccionada + Buscar + No se encontraron resultados + No se encontró \'Continuar viendo\' + No se encontraron descargas + Archivo no encontrado + No se encontró episodio válido + Seleccionar proveedor + Seleccionado + Biblioteca + Marcadores + Reanudando %1$s... + diff --git a/app/src/main/res-car/values-b+et/strings_car.xml b/app/src/main/res-car/values-b+et/strings_car.xml new file mode 100644 index 00000000000..64067503545 --- /dev/null +++ b/app/src/main/res-car/values-b+et/strings_car.xml @@ -0,0 +1,51 @@ + + + Laadimine... + Viga + Sisu laadimise viga + Lemmikud + Ajalugu + Allalaadimised + Teenusepakkuja + Praegune + Menüü + Avalehe sisu + Teenusepakkujalt puudub sisu + Teenusepakkujat ei leitud + Allikas + Allikad + Sisu + Osades + Viga üksikasjade laadimisel + Episoodide loend + Hooaeg + Hooajad + Episood + Episoode ei leitud + Ei ole telesari + Lisatud lemmikutesse + Eemaldatud lemmikutest + Lemmikuid ei leitud + Taasesituse alustamine... + Esitamine + Link ei leitud + Mängitavat sisu ei leitud + Üksikasju ei saa laadida + Viga linkide laadimisel + Mahuta ekraanile + Täida ekraan + Allikat ei leitud + Ühtegi allikat pole saadaval + Allikas valitud + Otsi + Tulemusi ei leitud + \'Jätka vaatamist\' ei leitud + Allalaadimisi ei leitud + Faili ei leitud + Kehtivat episoodi ei leitud + Vali teenusepakkuja + Valitud + Raamatukogu + Järjehoidjad + Jätkamine %1$s... + diff --git a/app/src/main/res-car/values-b+eu/strings_car.xml b/app/src/main/res-car/values-b+eu/strings_car.xml new file mode 100644 index 00000000000..dd794473078 --- /dev/null +++ b/app/src/main/res-car/values-b+eu/strings_car.xml @@ -0,0 +1,51 @@ + + + Kargatzen... + Errorea + Errorea edukia kargatzean + Gogokoak + Historia + Deskargak + Hornitzailea + Unekoa + Menua + Hasierako edukia + Hornitzailearen edukirik ez + Hornitzailea ez da aurkitu + Iturburua + Iturburuak + Argumentua + Aktoreak + Errorea xehetasunak kargatzean + Atalen zerrenda + Denboraldia + Denboraldiak + Atala + Ez da atalik aurkitu + Ez da telebista saioa + Gogokoetan gehitu da + Gogokoetatik kendu da + Ez da gogokorik aurkitu + Erreprodukzioa hasten... + Erreproduzitzen + Ez da estekarik aurkitu + Ez da erreproduzitzeko edukirik aurkitu + Ezin dira xehetasunak kargatu + Errorea estekak kargatzean + Doitu pantailara + Bete pantaila + Ez da iturbururik aurkitu + Ez dago iturbururik eskuragarri + Iturburua hautatuta + Bilatu + Ez da emaitzarik aurkitu + Ez da \'Jarraitu ikusten\' aurkitu + Ez da deskargarik aurkitu + Ez da fitxategia aurkitu + Ez da baliozko atalik aurkitu + Hautatu hornitzailea + Hautatuta + Liburutegia + Laster-markak + %1$s jarraitzen... + diff --git a/app/src/main/res-car/values-b+fa/strings_car.xml b/app/src/main/res-car/values-b+fa/strings_car.xml new file mode 100644 index 00000000000..8c23b79e7fd --- /dev/null +++ b/app/src/main/res-car/values-b+fa/strings_car.xml @@ -0,0 +1,51 @@ + + + درحال بارگذاری... + خطا + خطا در بارگذاری محتوا + علاقه‌مندی‌ها + تاریخچه + دانلودها + ارائه‌دهنده + کنونی + منو + محتوای خانه + بدون محتوا از ارائه‌دهنده + ارائه‌دهنده یافت نشد + منبع + منابع + داستان + بازیگران + خطا در بارگذاری جزئیات + لیست قسمت‌ها + فصل + فصل‌ها + قسمت + قسمتی یافت نشد + سریال تلویزیونی نیست + به علاقه‌مندی‌ها اضافه شد + از علاقه‌مندی‌ها حذف شد + علاقه‌مندی یافت نشد + شروع پخش... + درحال پخش + لینکی یافت نشد + محتوای قابل پخش یافت نشد + ناتوان در بارگذاری جزئیات + خطا در بارگذاری لینک‌ها + فیت صفحه + پر کردن صفحه + منبع یافت نشد + منبعی در دسترس نیست + منبع انتخاب شد + جستجو + نتیجه‌ای یافت نشد + \'ادامه تماشا\' یافت نشد + دانلودی یافت نشد + فایل یافت نشد + قسمت معتبری یافت نشد + انتخاب ارائه‌دهنده + انتخاب شد + کتابخانه + نشانک‌ها + درحال ادامه %1$s... + diff --git a/app/src/main/res-car/values-b+fi/strings_car.xml b/app/src/main/res-car/values-b+fi/strings_car.xml new file mode 100644 index 00000000000..4c609c8cfcb --- /dev/null +++ b/app/src/main/res-car/values-b+fi/strings_car.xml @@ -0,0 +1,51 @@ + + + Ladataan... + Virhe + Virhe ladattaessa sisältöä + Suosikit + Historia + Lataukset + Palveluntarjoaja + Nykyinen + Valikko + Etusivun sisältö + Ei sisältöä palveluntarjoajalta + Palveluntarjoajaa ei löytynyt + Lähde + Lähteet + Juoni + Näyttelijät + Virhe ladattaessa tietoja + Jaksot + Kausi + Kaudet + Jakso + Jaksoja ei löytynyt + Ei TV-sarja + Lisätty suosikkeihin + Poistettu suosikeista + Ei suosikkeja löytynyt + Aloitetaan toistoa... + Toistetaan + Linkkiä ei löytynyt + Toistettavaa sisältöä ei löytynyt + Tietoja ei voitu ladata + Virhe ladattaessa linkkejä + Sovita näyttöön + Täytä näyttö + Lähdettä ei löytynyt + Ei lähdettä saatavilla + Lähde valittu + Haku + Tuloksia ei löytynyt + \'Jatka katselua\' ei löytynyt + Latauksia ei löytynyt + Tiedostoa ei löytynyt + Kelvollista jaksoa ei löytynyt + Valitse palveluntarjoaja + Valittu + Kirjasto + Kirjanmerkit + Jatketaan %1$s... + diff --git a/app/src/main/res-car/values-b+fil/strings_car.xml b/app/src/main/res-car/values-b+fil/strings_car.xml new file mode 100644 index 00000000000..ac0a25531bb --- /dev/null +++ b/app/src/main/res-car/values-b+fil/strings_car.xml @@ -0,0 +1,74 @@ + + + + Loading... + Error + Error loading content + + + Favorites + History + Downloads + Provider + Current + Menu + Home Content + No content from provider + Provider not found + + + Source + Sources + Plot + Cast + Error loading details + + + Episode List + Season + Seasons + Episode + No episodes found + Not a TV series + + + Added to favorites + Removed from favorites + No favorites found + + + Starting playback... + Playing + No link found + No playable content found + Unable to load details + Error loading links + Fit to screen + Fill screen + + + No source found + No source available + Source selected + + + Search + No results found + + + No \'Continue watching\' items found + + + No completed downloads found + File not found + No valid episode found + + + Select Provider + Selected + + + Library + Bookmarks + Resuming %1$s... + diff --git a/app/src/main/res-car/values-b+fr/strings_car.xml b/app/src/main/res-car/values-b+fr/strings_car.xml new file mode 100644 index 00000000000..86f178c5683 --- /dev/null +++ b/app/src/main/res-car/values-b+fr/strings_car.xml @@ -0,0 +1,51 @@ + + + Chargement... + Erreur + Erreur de chargement du contenu + Favoris + Historique + Téléchargements + Fournisseur + Actuel + Menu + Contenu d\'accueil + Aucun contenu du fournisseur + Fournisseur non trouvé + Source + Sources + Intrigue + Distribution + Erreur de chargement des détails + Liste des épisodes + Saison + Saisons + Épisode + Aucun épisode trouvé + Pas une série TV + Ajouté aux favoris + Retiré des favoris + Aucun favori trouvé + Démarrage de la lecture... + Lecture + Aucun lien trouvé + Aucun contenu lisible trouvé + Impossible de charger les détails + Erreur de chargement des liens + Adapter à l\'écran + Remplir l\'écran + Aucune source trouvée + Aucune source disponible + Source sélectionnée + Rechercher + Aucun résultat trouvé + Aucun élément \'Continuer à regarder\' trouvé + Aucun téléchargement trouvé + Fichier non trouvé + Aucun épisode valide trouvé + Sélectionner le fournisseur + Sélectionné + Bibliothèque + Marque-pages + Reprise %1$s... + diff --git a/app/src/main/res-car/values-b+gl/strings_car.xml b/app/src/main/res-car/values-b+gl/strings_car.xml new file mode 100644 index 00000000000..7ae2aa29f06 --- /dev/null +++ b/app/src/main/res-car/values-b+gl/strings_car.xml @@ -0,0 +1,51 @@ + + + Cargando... + Erro + Erro cargando contido + Favoritos + Historial + Descargas + Provedor + Actual + Menú + Contido de inicio + Sen contido do provedor + Provedor non atopado + Fonte + Fontes + Argumento + Reparto + Erro cargando detalles + Lista de episodios + Tempada + Tempadas + Episodio + Non se atoparon episodios + Non é unha serie de TV + Engadido a favoritos + Eliminado de favoritos + Non se atoparon favoritos + Iniciando reprodución... + Reproducindo + Ligazón non atopada + Contido reproducible non atopado + Non se poden cargar os detalles + Erro cargando ligazóns + Axustar á pantalla + Encher pantalla + Fonte non atopada + Non hai fonte dispoñible + Fonte seleccionada + Buscar + Sen resultados + \'Continuar vendo\' non atopado + Sen descargas + Ficheiro non atopado + Sen episodio válido + Seleccionar provedor + Seleccionado + Biblioteca + Marcadores + Retomando %1$s... + diff --git a/app/src/main/res-car/values-b+gu/strings_car.xml b/app/src/main/res-car/values-b+gu/strings_car.xml new file mode 100644 index 00000000000..458737dab3b --- /dev/null +++ b/app/src/main/res-car/values-b+gu/strings_car.xml @@ -0,0 +1,51 @@ + + + લોડ થઈ રહ્યું છે... + ભૂલ + સામગ્રી લોડ કરવામાં ભૂલ + મનપસંદ + ઇતિહાસ + ડાઉનલોડ્સ + પ્રદાતા + વર્તમાન + મેનુ + હોમ સામગ્રી + પ્રદાતા તરફથી કોઈ સામગ્રી નથી + પ્રદાતા મળ્યા નથી + સ્ત્રોત + સ્ત્રોતો + પ્લોટ + કલાકારો + વિગતો લોડ કરવામાં ભૂલ + એ એપિસોડ સૂચિ + સીઝન + સીઝન + એપિસોડ + કોઈ એપિસોડ મળ્યા નથી + ટીવી શ્રેણી નથી + મનપસંદમાં ઉમેર્યું + મનપસંદમાંથી દૂર કર્યું + કોઈ મનપસંદ મળ્યા નથી + પ્લેબેક શરૂ થઈ રહ્યું છે... + રમી રહ્યું છે + કોઈ લિંક મળી નથી + કોઈ રમી શકાય તેવી સામગ્રી મળી નથી + વિગતો લોડ કરવામાં અસમર્થ + લિંક્સ લોડ કરવામાં ભૂલ + સ્ક્રીન પર ફિટ કરો + સ્ક્રીન ભરો + કોઈ સ્ત્રોત મળ્યો નથી + કોઈ સ્ત્રોત ઉપલબ્ધ નથી + સ્ત્રોત પસંદ કર્યો + શોધો + કોઈ પરિણામ મળ્યા નથી + \'જોવાનું ચાલુ રાખો\' મળ્યું નથી + કોઈ ડાઉનલોડ્સ મળ્યા નથી + ફાઇલ મળી નથી + કોઈ માન્ય એપિસોડ મળ્યો નથી + પ્રદાતા પસંદ કરો + પસંદ કરેલ + લાઇબ્રેરી + બુકમાર્ક્સ + %1$s ફરી શરૂ કરી રહ્યું છે... + diff --git a/app/src/main/res-car/values-b+hi/strings_car.xml b/app/src/main/res-car/values-b+hi/strings_car.xml new file mode 100644 index 00000000000..f3418c0e4e3 --- /dev/null +++ b/app/src/main/res-car/values-b+hi/strings_car.xml @@ -0,0 +1,51 @@ + + + 로드 중... + गलती + सामग्री लोड हो रही है + पसंदीदा + इतिहास + डाउनलोड + प्रदाता + वर्तमान + मेन्यू + गृह सामग्री + प्रदाता से कोई सामग्री नहीं + प्रदाता नहीं मिला + स्रोत + सूत्रों + भूखंड + ढालना + विवरण लोड करने में त्रुटि + एपिसोड सूची + मौसम + मौसम + प्रसंग + कोई एपिसोड नहीं मिला + टीवी श्रृंखला नहीं + पसंदीदा में जोड़ा गया + पसंदीदा से हटाया गया + कोई पसंदीदा नहीं मिला + प्लेबैक प्रारंभ हो रहा है... + खेल + कोई लिंक नहीं मिला + कोई खेलने योग्य सामग्री नहीं मिली + विवरण लोड करने में असमर्थ + लिंक लोड करने में त्रुटि + स्क्रीन पर फिट करें + स्क्रीन भरें + कोई स्रोत नहीं मिला + कोई स्रोत उपलब्ध नहीं है + स्रोत चयनित + खोज + कोई परिणाम नहीं मिला + \'देखना जारी रखें\' नहीं मिला + कोई डाउनलोड नहीं मिला + फ़ाइल नहीं मिली + कोई मान्य एपिसोड नहीं मिला + प्रदाता का चयन करें + चयनित + पुस्तकालय + बुकमार्क + %1$s फिर से शुरू... + diff --git a/app/src/main/res-car/values-b+hr/strings_car.xml b/app/src/main/res-car/values-b+hr/strings_car.xml new file mode 100644 index 00000000000..8bf55c3fab5 --- /dev/null +++ b/app/src/main/res-car/values-b+hr/strings_car.xml @@ -0,0 +1,51 @@ + + + Učitavanje... + Greška + Greška pri učitavanju sadržaja + Favoriti + Povijest + Preuzimanja + Pružatelj + Trenutno + Izbornik + Početni sadržaj + Nema sadržaja od pružatelja + Pružatelj nije pronađen + Izvor + Izvori + Radnja + Glumci + Greška pri učitavanju detalja + Popis epizoda + Sezona + Sezone + Epizoda + Nema pronađenih epizoda + Nije TV serija + Dodano u favorite + Uklonjeno iz favorita + Nema favorita + Pokretanje reprodukcije... + Reprodukcija + Poveznica nije pronađena + Sadržaj za reprodukciju nije pronađen + Nije moguće učitati detalje + Greška pri učitavanju poveznica + Prilagodi ekranu + Ispuni ekran + Izvor nije pronađen + Izvor nije dostupan + Izvor odabran + Pretraži + Nema rezultata + \'Nastavi gledanje\' nije pronađeno + Nema preuzimanja + Datoteka nije pronađena + Nema važeće epizode + Odaberi pružatelja + Odabrano + Knjižnica + Oznake + Nastavljanje %1$s... + diff --git a/app/src/main/res-car/values-b+hu/strings_car.xml b/app/src/main/res-car/values-b+hu/strings_car.xml new file mode 100644 index 00000000000..3434ca4a290 --- /dev/null +++ b/app/src/main/res-car/values-b+hu/strings_car.xml @@ -0,0 +1,51 @@ + + + Betöltés... + Hiba + Tartalom betöltési hiba + Kedvencek + Előzmények + Letöltések + Szolgáltató + Jelenlegi + Menü + Kezdőlap tartalom + Nincs tartalom a szolgáltatótól + Szolgáltató nem található + Forrás + Források + Cselekmény + Szereplők + Részletek betöltési hiba + Epizódlista + Évad + Évadok + Epizód + Nem található epizód + Nem TV sorozat + Hozzáadva a kedvencekhez + Eltávolítva a kedvencekből + Nincs kedvenc + Lejátszás indítása... + Lejátszás + Link nem található + Nincs lejátszható tartalom + Nem sikerült betölteni a részleteket + Link betöltési hiba + Képernyőhöz igazítás + Kitöltés + Forrás nem található + Nincs elérhető forrás + Forrás kiválasztva + Keresés + Nincs találat + Nincs \'Nézés folytatása\' + Nincs letöltés + Fájl nem található + Nincs érvényes epizód + Válassz szolgáltatót + Kiválasztva + Könyvtár + Könyvjelzők + %1$s folytatása... + diff --git a/app/src/main/res-car/values-b+hy/strings_car.xml b/app/src/main/res-car/values-b+hy/strings_car.xml new file mode 100644 index 00000000000..414748b3d8b --- /dev/null +++ b/app/src/main/res-car/values-b+hy/strings_car.xml @@ -0,0 +1,51 @@ + + + Բեռնում... + Սխալ + Բովանդակության բեռնման սխալ + Ընտրյալներ + Պատմություն + Ներբեռնումներ + Մատակարար + Ընթացիկ + Մենյու + Գլխավոր էջի բովանդակություն + Մատակարարից բովանդակություն չկա + Մատակարարը չի գտնվել + Աղբյուր + Աղբյուրներ + Սյուժե + Դերասանական կազմ + Մանրամասների բեռնման սխալ + Սերիաների ցանկ + Եթերաշրջան + Եթերաշրջաններ + Սերիա + Սերիաներ չեն գտնվել + Հեռուստասերիալ չէ + Ավելացվել է ընտրյալներին + Հեռացվել է ընտրյալներից + Ընտրյալներ չեն գտնվել + Նվագարկման մեկնարկ... + Նվագարկվում է + Հղում չի գտնվել + Նվագարկվող բովանդակություն չի գտնվել + Հնարավոր չէ բեռնել մանրամասները + Հղումների բեռնման սխալ + Հարմարեցնել էկրանին + Լրացնել էկրանը + Աղբյուր չի գտնվել + Հասանելի աղբյուր չկա + Աղբյուրն ընտրված է + Որոնել + Արդյունքներ չեն գտնվել + \'Շարունակել դիտել\' չի գտնվել + Ներբեռնումներ չեն գտնվել + Ֆայլը չի գտնվել + Վավեր սերիա չի գտնվել + Ընտրեք մատակարար + Ընտրված է + Գրադարան + Էջանիշեր + Շարունակվում է %1$s... + diff --git a/app/src/main/res-car/values-b+in/strings_car.xml b/app/src/main/res-car/values-b+in/strings_car.xml new file mode 100644 index 00000000000..1caea08ba75 --- /dev/null +++ b/app/src/main/res-car/values-b+in/strings_car.xml @@ -0,0 +1,51 @@ + + + Memuat... + Kesalahan + Kesalahan memuat konten + Favorit + Riwayat + Unduhan + Penyedia + Saat Ini + Menu + Konten Beranda + Tidak ada konten dari penyedia + Penyedia tidak ditemukan + Sumber + Sumber + Plot + Pemeran + Kesalahan memuat detail + Daftar Episode + Musim + Musim + Episode + Tidak ada episode ditemukan + Bukan serial TV + Ditambahkan ke favorit + Dihapus dari favorit + Tidak ada favorit ditemukan + Memulai pemutaran... + Memutar + Tautan tidak ditemukan + Tidak ada konten yang dapat diputar + Tidak dapat memuat detail + Kesalahan memuat tautan + Pas ke Layar + Isi Layar + Sumber tidak ditemukan + Tidak ada sumber tersedia + Sumber dipilih + Cari + Tidak ada hasil ditemukan + \'Lanjutkan Menonton\' tidak ditemukan + Tidak ada unduhan ditemukan + Berkas tidak ditemukan + Tidak ada episode valid + Pilih Penyedia + Dipilih + Pustaka + Penanda + Melanjutkan %1$s... + diff --git a/app/src/main/res-car/values-b+is/strings_car.xml b/app/src/main/res-car/values-b+is/strings_car.xml new file mode 100644 index 00000000000..4bf48c74395 --- /dev/null +++ b/app/src/main/res-car/values-b+is/strings_car.xml @@ -0,0 +1,51 @@ + + + Hleður... + Villa + Villa við að hlaða efni + Eftirlæti + Saga + Niðurhal + Veita + Núverandi + Valmynd + Heimaefni + Ekkert efni frá veitu + Veita fannst ekki + Heimild + Heimildir + Söguþráður + Leikarar + Villa við að hlaða upplýsingum + Þáttalisti + Sería + Seríur + Þáttur + Engir þættir fundust + Ekki sjónvarpsþáttaröð + Bætt við eftirlæti + Fjarlægt úr eftirlæti + Engin eftirlæti fundust + Hefur spilun... + Spilar + Enginn tengill fannst + Ekkert spilanlegt efni fannst + Gat ekki hlaðið upplýsingum + Villa við að hlaða tenglum + Passa á skjá + Fylla skjá + Engin heimild fannst + Engin heimild tiltæk + Heimild valin + Leita + Engar niðurstöður fundust + \'Halda áfram að horfa\' fannst ekki + Ekkert niðurhal fannst + Skrá fannst ekki + Enginn gildur þáttur fannst + Veldu veitu + Valið + Bókasafn + Bókamerki + Heldur áfram %1$s... + diff --git a/app/src/main/res-car/values-b+iw/strings_car.xml b/app/src/main/res-car/values-b+iw/strings_car.xml new file mode 100644 index 00000000000..100c986137b --- /dev/null +++ b/app/src/main/res-car/values-b+iw/strings_car.xml @@ -0,0 +1,51 @@ + + + טוען... + שגיאה + שגיאה בטעינת תוכן + מועדפים + היסטוריה + הורדות + ספק + נוכחי + תפריט + תוכן דף הבית + אין תוכן מהספק + ספק לא נמצא + מקור + מקורות + עלילה + שחקנים + שגיאה בטעינת פרטים + רשימת פרקים + עונה + עונות + פרק + לא נמצאו פרקים + לא סדרת טלוויזיה + נוסף למועדפים + הוסר מהמועדפים + לא נמצאו מועדפים + מתחיל ניגון... + מנגן + לא נמצא קישור + לא נמצא תוכן לניגון + לא ניתן לטעון פרטים + שגיאה בטעינת קישורים + התאם למסך + מלא מסך + מקור לא נמצא + אין מקור זמין + מקור נבחר + חיפוש + לא נמצאו תוצאות + \'המשך צפייה\' לא נמצא + לא נמצאו הורדות + קובץ לא נמצא + לא נמצא פרק תקין + בחר ספק + נבחר + ספרייה + סימניות + ממשיך %1$s... + diff --git a/app/src/main/res-car/values-b+ja/strings_car.xml b/app/src/main/res-car/values-b+ja/strings_car.xml new file mode 100644 index 00000000000..940e87c68a5 --- /dev/null +++ b/app/src/main/res-car/values-b+ja/strings_car.xml @@ -0,0 +1,51 @@ + + + 読み込み中... + エラー + コンテンツの読み込みエラー + お気に入り + 履歴 + ダウンロード + プロバイダー + 現在 + メニュー + ホームコンテンツ + プロバイダーからのコンテンツなし + プロバイダーが見つかりません + ソース + ソース + あらすじ + キャスト + 詳細の読み込みエラー + エピソードリスト + シーズン + シーズン + エピソード + エピソードが見つかりません + TV番組ではありません + お気に入りに追加しました + お気に入りから削除しました + お気に入りが見つかりません + 再生を開始しています... + 再生中 + リンクが見つかりません + 再生可能なコンテンツが見つかりません + 詳細を読み込めません + リンクの読み込みエラー + 画面に合わせる + 画面を埋める + ソースが見つかりません + 利用可能なソースがありません + ソースを選択しました + 検索 + 結果が見つかりません + 続きを見るコンテンツがありません + ダウンロードが見つかりません + ファイルが見つかりません + 有効なエピソードが見つかりません + プロバイダーを選択 + 選択済み + ライブラリ + ブックマーク + %1$s を再開しています... + diff --git a/app/src/main/res-car/values-b+ka/strings_car.xml b/app/src/main/res-car/values-b+ka/strings_car.xml new file mode 100644 index 00000000000..d1b995dc81e --- /dev/null +++ b/app/src/main/res-car/values-b+ka/strings_car.xml @@ -0,0 +1,51 @@ + + + ჩატვირთვა... + შეცდომა + შინაარსის ჩატვირთვის შეცდომა + რჩეულები + ისტორია + ჩამოტვირთვები + მომწოდებელი + მიმდინარე + მენიუ + მთავარი შინაარსი + შინაარსი მომწოდებლისგან არ არის + მომწოდებელი ვერ მოიძებნა + წყარო + წყაროები + სიუჟეტი + მსახიობები + დეტალების ჩატვირთვის შეცდომა + ეპიზოდების სია + სეზონი + სეზონები + ეპიზოდი + ეპიზოდები ვერ მოიძებნა + არ არის სატელევიზიო სერიალი + დაემატა რჩეულებში + ამოღებულია რჩეულებიდან + რჩეულები ვერ მოიძებნა + დაკვრის დაწყება... + დაკვრა + ბმული ვერ მოიძებნა + დასაკრავი შინაარსი ვერ მოიძებნა + დეტალების ჩატვირთვა ვერ მოხერხდა + ბმულების ჩატვირთვის შეცდომა + ეკრანზე მორგება + ეკრანის შევსება + წყარო ვერ მოიძებნა + წყარო არ არის ხელმისაწვდომი + წყარო არჩეულია + ძიება + შედეგები ვერ მოიძებნა + \'ყურების გაგრძელება\' ვერ მოიძებნა + ჩამოტვირთვები ვერ მოიძებნა + ფაილი ვერ მოიძებნა + ვალიდური ეპიზოდი ვერ მოიძებნა + აირჩიეთ მომწოდებელი + არჩეულია + ბიბლიოთეკა + სანიშნეები + გრძელდება %1$s... + diff --git a/app/src/main/res-car/values-b+kk/strings_car.xml b/app/src/main/res-car/values-b+kk/strings_car.xml new file mode 100644 index 00000000000..e1cffdd409d --- /dev/null +++ b/app/src/main/res-car/values-b+kk/strings_car.xml @@ -0,0 +1,51 @@ + + + Жүктелуде... + Қате + Мазмұнды жүктеу қатесі + Таңдаулылар + Тарих + Жүктеулер + Провайдер + Ағымдағы + Мәзір + Басты бет мазмұны + Провайдерден мазмұн жоқ + Провайдер табылмады + Дереккөз + Дереккөздер + Сюжет + Актерлер + Мәліметтерді жүктеу қатесі + Эпизодтар тізімі + Маусым + Маусымдар + Эпизод + Эпизодтар табылмады + ТВ сериалы емес + Таңдаулыларға қосылды + Таңдаулылардан жойылды + Таңдаулылар табылмады + Ойнату басталуда... + Ойнатылуда + Сілтеме табылмады + Ойнатылатын мазмұн табылмады + Мәліметтерді жүктеу мүмкін емес + Сілтемелерді жүктеу қатесі + Экранға сыйғызу + Экранды толтыру + Дереккөз табылмады + Қолжетімді дереккөз жоқ + Дереккөз таңдалды + Іздеу + Нәтижелер табылмады + \'Көруді жалғастыру\' табылмады + Жүктеулер табылмады + Файл табылмады + Жарамды эпизод табылмады + Провайдерді таңдаңыз + Таңдалды + Кітапхана + Бетбелгілер + Жалғастырылуда %1$s... + diff --git a/app/src/main/res-car/values-b+km/strings_car.xml b/app/src/main/res-car/values-b+km/strings_car.xml new file mode 100644 index 00000000000..0a6743d3ba1 --- /dev/null +++ b/app/src/main/res-car/values-b+km/strings_car.xml @@ -0,0 +1,51 @@ + + + កំពុងផ្ទុក... + កំហុស + កំហុសក្នុងការផ្ទុកមាតិកា + ដែលចូលចិត្ត + ប្រវត្តិ + ការទាញយក + អ្នកផ្តល់សេវា + បច្ចុប្បន្ន + ម៉ឺនុយ + មាតិកាដើម + គ្មានមាតិកាពីអ្នកផ្តល់សេវា + រកមិនឃើញអ្នកផ្តល់សេវា + ប្រភព + ប្រភព + សាច់រឿង + តួសម្តែង + កំហុសក្នុងការផ្ទុកព័ត៌មានលម្អិត + បញ្ជីភាគ + រដូវកាល + រដូវកាល + ភាគ + រកមិនឃើញភាគ + មិនមែនជាស៊េរីទូរទស្សន៍ + បានបន្ថែមទៅការចូលចិត្ត + បានលុបចេញពីការចូលចិត្ត + រកមិនឃើញការចូលចិត្ត + កំពុងចាប់ផ្តើមការចាក់សារថ្មី... + កំពុងចាក់ + រកមិនឃើញតំណ + រកមិនឃើញមាតិកាដែលអាចចាក់បាន + មិនអាចផ្ទុកព័ត៌មានលម្អិត + កំហុសក្នុងការផ្ទុកតំណ + សមនឹងអេក្រង់ + ពេញអេក្រង់ + រកមិនឃើញប្រភព + គ្មានប្រភពដែលអាចប្រើបាន + បានជ្រើសរើសប្រភព + ស្វែងរក + រកមិនឃើញលទ្ធផល + រកមិនឃើញ \'បន្តមើល\' + រកមិនឃើញការទាញយក + រកមិនឃើញឯកសារ + រកមិនឃើញភាគដែលមានសុពលភាព + ជ្រើសរើសអ្នកផ្តល់សេវា + បានជ្រើសរើស + បណ្ណាល័យ + ចំណាំ + កំពុងបន្ត %1$s... + diff --git a/app/src/main/res-car/values-b+kn/strings_car.xml b/app/src/main/res-car/values-b+kn/strings_car.xml new file mode 100644 index 00000000000..7a20b0d2a20 --- /dev/null +++ b/app/src/main/res-car/values-b+kn/strings_car.xml @@ -0,0 +1,51 @@ + + + ಲೋಡ್ ಆಗುತ್ತಿದೆ... + ದೋಷ + ವಿಷಯವನ್ನು ಲೋಡ್ ಮಾಡುವಲ್ಲಿ ದೋಷ + ಮೆಚ್ಚಿನವುಗಳು + ಇತಿಹಾಸ + ಡೌನ್‌ಲೋಡ್‌ಗಳು + ಪೂರೈಕೆದಾರ + ಪ್ರಸ್ತುತ + ಮೆನು + ಮುಖಪುಟ ವಿಷಯ + ಪೂರೈಕೆದಾರರಿಂದ ಯಾವುದೇ ವಿಷಯವಿಲ್ಲ + ಪೂರೈಕೆದಾರ ಕಂಡುಬಂದಿಲ್ಲ + ಮೂಲ + ಮೂಲಗಳು + ಕಥಾವಸ್ತು + ಪಾತ್ರವರ್ಗ + ವಿವರಗಳನ್ನು ಲೋಡ್ ಮಾಡುವಲ್ಲಿ ದೋಷ + ಸಂಚಿಕೆ ಪಟ್ಟಿ + ಋತು + ಋತುಗಳು + ಸಂಚಿಕೆ + ಯಾವುದೇ ಸಂಚಿಕೆಗಳು ಕಂಡುಬಂದಿಲ್ಲ + ಟಿವಿ ಸರಣಿಯಲ್ಲ + ಮೆಚ್ಚಿನವುಗಳಿಗೆ ಸೇರಿಸಲಾಗಿದೆ + ಮೆಚ್ಚಿನವುಗಳಿಂದ ತೆಗೆದುಹಾಕಲಾಗಿದೆ + ಯಾವುದೇ ಮೆಚ್ಚಿನವುಗಳು ಕಂಡುಬಂದಿಲ್ಲ + ಪ್ಲೇಬ್ಯಾಕ್ ಪ್ರಾರಂಭವಾಗುತ್ತಿದೆ... + ಪ್ಲೇ ಆಗುತ್ತಿದೆ + ಯಾವುದೇ ಲಿಂಕ್ ಕಂಡುಬಂದಿಲ್ಲ + ಯಾವುದೇ ಪ್ಲೇ ಮಾಡಬಹುದಾದ ವಿಷಯ ಕಂಡುಬಂದಿಲ್ಲ + ವಿವರಗಳನ್ನು ಲೋಡ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ + ಲಿಂಕ್‌ಗಳನ್ನು ಲೋಡ್ ಮಾಡುವಲ್ಲಿ ದೋಷ + ಪರದೆಗೆ ಹೊಂದಿಸಿ + ಪರದೆ ತುಂಬಿಸಿ + ಯಾವುದೇ ಮೂಲ ಕಂಡುಬಂದಿಲ್ಲ + ಯಾವುದೇ ಮೂಲ ಲಭ್ಯವಿಲ್ಲ + ಮೂಲ ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ + ಹುಡುಕಿ + ಯಾವುದೇ ಫಲಿತಾಂಶಗಳು ಕಂಡುಬಂದಿಲ್ಲ + \'ವೀಕ್ಷಣೆ ಮುಂದುವರಿಸಿ\' ಕಂಡುಬಂದಿಲ್ಲ + ಯಾವುದೇ ಡೌನ್‌ಲೋಡ್‌ಗಳು ಕಂಡುಬಂದಿಲ್ಲ + ಫೈಲ್ ಕಂಡುಬಂದಿಲ್ಲ + ಯಾವುದೇ ಮಾನ್ಯ ಸಂಚಿಕೆ ಕಂಡುಬಂದಿಲ್ಲ + ಪೂರೈಕೆದಾರರನ್ನು ಆಯ್ಕೆಮಾಡಿ + ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ + ಗ್ರಂಥಾಲಯ + ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು + %1$s ಪುನರಾರಂಭವಾಗುತ್ತಿದೆ... + diff --git a/app/src/main/res-car/values-b+ko/strings_car.xml b/app/src/main/res-car/values-b+ko/strings_car.xml new file mode 100644 index 00000000000..0c6f7bf81fd --- /dev/null +++ b/app/src/main/res-car/values-b+ko/strings_car.xml @@ -0,0 +1,51 @@ + + + 로드 중... + 오류 + 콘텐츠 로드 오류 + 즐겨찾기 + 기록 + 다운로드 + 제공자 + 현재 + 메뉴 + 홈 콘텐츠 + 제공자의 콘텐츠 없음 + 제공자를 찾을 수 없음 + 소스 + 소스 + 줄거리 + 출연진 + 세부 정보 로드 오류 + 에피소드 목록 + 시즌 + 시즌 + 에피소드 + 에피소드 없음 + TV 시리즈 아님 + 즐겨찾기에 추가됨 + 즐겨찾기에서 제거됨 + 즐겨찾기 없음 + 재생 시작 중... + 재생 중 + 링크 없음 + 재생 가능한 콘텐츠 없음 + 세부 정보를 로드할 수 없음 + 링크 로드 오류 + 화면에 맞춤 + 화면 채우기 + 소스 없음 + 사용 가능한 소스 없음 + 소스 선택됨 + 검색 + 결과 없음 + 이어보기 없음 + 다운로드 없음 + 파일 없음 + 유효한 에피소드 없음 + 제공자 선택 + 선택됨 + 라이브러리 + 북마크 + %1$s 이어보는 중... + diff --git a/app/src/main/res-car/values-b+ky/strings_car.xml b/app/src/main/res-car/values-b+ky/strings_car.xml new file mode 100644 index 00000000000..4f5a4790a09 --- /dev/null +++ b/app/src/main/res-car/values-b+ky/strings_car.xml @@ -0,0 +1,51 @@ + + + Жүктөө... + Ката + Мазмунду жүктөө катасы + Сүйүктүүлөр + Тарых + Жүктөөлөр + Провайдер + Учурдагы + Меню + Башкы мазмун + Провайдерден мазмун жок + Провайдер табылган жок + Булак + Булактар + Сюжет + Актерлор + Маалыматтарды жүктөө катасы + Эпизоддор тизмеси + Сезон + Сезондор + Эпизод + Эпизоддор табылган жок + ТВ сериалы эмес + Сүйүктүүлөргө кошулду + Сүйүктүүлөрдөн алынды + Сүйүктүүлөр табылган жок + Ойнотуу башталууда... + Ойнотулууда + Шилтеме табылган жок + Ойнотула турган мазмун табылган жок + Маалыматтарды жүктөө мүмкүн эмес + Шилтемелерди жүктөө катасы + Экранга тууралоо + Экранды толтуруу + Булак табылган жок + Жеткиликтүү булак жок + Булак тандалды + Издөө + Жыйынтык табылган жок + \'Көрүүнү улантуу\' табылган жок + Жүктөөлөр табылган жок + Файл табылган жок + Жарактуу эпизод табылган жок + Провайдерди тандоо + Тандалды + Китепкана + Кыстармалар + Улантылууда %1$s... + diff --git a/app/src/main/res-car/values-b+lo/strings_car.xml b/app/src/main/res-car/values-b+lo/strings_car.xml new file mode 100644 index 00000000000..6241b14e84c --- /dev/null +++ b/app/src/main/res-car/values-b+lo/strings_car.xml @@ -0,0 +1,51 @@ + + + ກຳລັງໂຫຼດ... + ຂໍ້ຜິດພາດ + ເກີດຂໍ້ຜິດພາດໃນການໂຫຼດເນື້ອຫາ + ລາຍການທີ່ມັກ + ປະຫວັດການເຂົ້າຊົມ + ການດາວໂຫຼດ + ຜູ້ໃຫ້ບໍລິການ + ປັດຈຸບັນ + ເມນູ + ເນື້ອຫາໜ້າຫຼັກ + ບໍ່ມີເນື້ອຫາຈາກຜູ້ໃຫ້ບໍລິການ + ບໍ່ພົບຜູ້ໃຫ້ບໍລິການ + ແຫຼ່ງທີ່ມາ + ແຫຼ່ງທີ່ມາ + ເນື້ອເລື່ອງ + ນັກສະແດງ + ເກີດຂໍ້ຜິດພາດໃນການໂຫຼດລາຍລະອຽດ + ລາຍການຕອນ + ຊີຊັນ + ຊີຊັນ + ຕອນ + ບໍ່ພົບຕອນ + ບໍ່ແມ່ນຊີຣີໂທລະທັດ + ເພີ່ມເຂົ້າໃນລາຍການທີ່ມັກແລ້ວ + ລົບອອກຈາກລາຍການທີ່ມັກແລ້ວ + ບໍ່ພົບລາຍການທີ່ມັກ + ກຳລັງເລີ່ມການຫຼິ້ນ... + ກຳລັງຫຼິ້ນ + ບໍ່ພົບລິ້ງ + ບໍ່ພົບເນື້ອຫາທີ່ສາມາດຫຼິ້ນໄດ້ + ບໍ່ສາມາດໂຫຼດລາຍລະອຽດໄດ້ + ເກີດຂໍ້ຜິດພາດໃນການໂຫຼດລິ້ງ + ປັບໃຫ້ພໍດີກັບໜ້າຈໍ + ຂະຫຍາຍເຕັ້ນໜ້າຈໍ + ບໍ່ພົບແຫຼ່ງທີ່ມາ + ບໍ່ມີແຫຼ່ງທີ່ມາທີ່ໃຊ້ໄດ້ + ເລືອກແຫຼ່ງທີ່ມາແລ້ວ + ຄົ້ນຫາ + ບໍ່ພົບຜົນການຄົ້ນຫາ + ບໍ່ພົບ \'ເບິ່ງຕໍ່\' + ບໍ່ພົບການດາວໂຫຼດ + ບໍ່ພົບໄຟລ໌ + ບໍ່ພົບຕອນທີ່ຖືກຕ້ອງ + ເລືອກຜູ້ໃຫ້ບໍລິການ + ທີ່ເລືອກ + ຫ້ອງສະໝຸດ + ບຸກມາກ + ກຳລັງເບິ່ງຕໍ່ %1$s... + diff --git a/app/src/main/res-car/values-b+lt/strings_car.xml b/app/src/main/res-car/values-b+lt/strings_car.xml new file mode 100644 index 00000000000..2812345f660 --- /dev/null +++ b/app/src/main/res-car/values-b+lt/strings_car.xml @@ -0,0 +1,51 @@ + + + Įkeliama... + Klaida + Klaida įkeliant turinį + Mėgstamiausi + Istorija + Atsisiuntimai + Tiekėjas + Dabartinis + Meniu + Pradžios turinys + Nėra turinio iš tiekėjo + Tiekėjas nerastas + Šaltinis + Šaltiniai + Siužetas + Aktoriai + Klaida įkeliant informaciją + Epizodų sąrašas + Sezonas + Sezonai + Epizodas + Epizodų nerasta + Ne TV serialas + Pridėta prie mėgstamiausių + Pašalinta iš mėgstamiausių + Mėgstamiausių nerasta + Pradedamas atkūrimas... + Atkuriama + Nuoroda nerasta + Atkuriamo turinio nerasta + Nepavyko įkelti informacijos + Klaida įkeliant nuorodas + Pritaikyti ekranui + Užpildyti ekraną + Šaltinis nerastas + Nėra galimų šaltinių + Šaltinis pasirinktas + Paieška + Rezultatų nerasta + \'Tęsti žiūrėjimą\' nerasta + Atsisiuntimų nerasta + Failas nerastas + Nerastas tinkamas epizodas + Pasirinkite tiekėją + Pasirinkta + Biblioteka + Žymos + Tęsiama %1$s... + diff --git a/app/src/main/res-car/values-b+lv/strings_car.xml b/app/src/main/res-car/values-b+lv/strings_car.xml new file mode 100644 index 00000000000..386bf2b92fa --- /dev/null +++ b/app/src/main/res-car/values-b+lv/strings_car.xml @@ -0,0 +1,51 @@ + + + Ielādē... + Kļūda + Satura ielādes kļūda + Izlase + Vēsture + Lejupielādes + Piegādātājs + Pašreizējais + Izvēlne + Sākuma saturs + Nav satura no piegādātāja + Piegādātājs nav atrasts + Avots + Avoti + Sižets + Lomas + Kļūda ielādējot informāciju + Epizožu saraksts + Sezona + Sezonas + Epizode + Epizodes nav atrastas + Nav TV seriāls + Pievienots izlasei + Noņemts no izlases + Izlase nav atrasta + Sāk atskaņošanu... + Atskaņo + Saite nav atrasta + Nav atrasts atskaņojams saturs + Nevar ielādēt informāciju + Kļūda ielādējot saites + Pielāgot ekrānam + Aizpildīt ekrānu + Avots nav atrasts + Nav pieejamu avotu + Avots izvēlēts + Meklēt + Rezultāti nav atrasti + \'Turpināt skatīties\' nav atrasts + Lejupielādes nav atrastas + Fails nav atrasts + Nav atrasta derīga epizode + Izvēlēties piegādātāju + Izvēlēts + Bibliotēka + Grāmatzīmes + Atsāk %1$s... + diff --git a/app/src/main/res-car/values-b+mk/strings_car.xml b/app/src/main/res-car/values-b+mk/strings_car.xml new file mode 100644 index 00000000000..bdc47d33110 --- /dev/null +++ b/app/src/main/res-car/values-b+mk/strings_car.xml @@ -0,0 +1,51 @@ + + + Вчитување... + Грешка + Грешка при вчитување содржина + Омилени + Историја + Преземања + Добавувач + Тековно + Мени + Почетна содржина + Нема содржина од добавувачот + Добавувачот не е пронајден + Извор + Извори + Дејство + Улоги + Грешка при вчитување детали + Листа на епизоди + Сезона + Сезони + Епизода + Не се пронајдени епизоди + Не е ТВ серија + Додадено во омилени + Отстрането од омилени + Не се пронајдени омилени + Започнување репродукција... + Репродукција + Врската не е пронајдена + Не е пронајдена содржина за репродукција + Не може да се вчитаат детали + Грешка при вчитување врски + Вклопи во екран + Пополни екран + Изворот не е пронајден + Нема достапен извор + Изворот е избран + Пребарување + Не се пронајдени резултати + \'Продолжи со гледање\' не е пронајдено + Не се пронајдени преземања + Датотеката не е пронајдена + Не е пронајдена валидна епизода + Избери добавувач + Избрано + Библиотека + Обележувачи + Продолжување %1$s... + diff --git a/app/src/main/res-car/values-b+ml/strings_car.xml b/app/src/main/res-car/values-b+ml/strings_car.xml new file mode 100644 index 00000000000..d1af8f61ff2 --- /dev/null +++ b/app/src/main/res-car/values-b+ml/strings_car.xml @@ -0,0 +1,51 @@ + + + ലോഡ് ചെയ്യുന്നു... + പിശക് + ഉള്ളടക്കം ലോഡ് ചെയ്യുന്നതിൽ പിശക് + പ്രിയപ്പെട്ടവ + ചരിത്രം + ഡൗൺലോഡുകൾ + ദാതാവ് + നിലവിലുള്ള + മെനു + ഹോം ഉള്ളടക്കം + ദാതാവിൽ നിന്ന് ഉള്ളടക്കമില്ല + ദാതാവിനെ കണ്ടെത്തിയില്ല + ഉറവിടം + ഉറവിടങ്ങൾ + ഇതിവൃത്തം + അഭിനേതാക്കൾ + വിശദാംശങ്ങൾ ലോഡ് ചെയ്യുന്നതിൽ പിശക് + എപ്പിസോഡ് ലിസ്റ്റ് + സീസൺ + സീസണുകൾ + എപ്പിസോഡ് + എപ്പിസോഡുകളൊന്നും കണ്ടെത്തിയില്ല + ടിവി സീരീസ് അല്ല + പ്രിയപ്പെട്ടവയിലേക്ക് ചേർത്തു + പ്രിയപ്പെട്ടവയിൽ നിന്ന് നീക്കം ചെയ്തു + പ്രിയപ്പെട്ടവയൊന്നും കണ്ടെത്തിയില്ല + പ്ലേബാക്ക് ആരംഭിക്കുന്നു... + പ്ലേ ചെയ്യുന്നു + ലിങ്ക് കണ്ടെത്തിയില്ല + പ്ലേ ചെയ്യാവുന്ന ഉള്ളടക്കമൊന്നും കണ്ടെത്തിയില്ല + വിശദാംശങ്ങൾ ലോഡ് ചെയ്യാനായില്ല + ലിങ്കുകൾ ലോഡ് ചെയ്യുന്നതിൽ പിശക് + സ്‌ക്രീനിലേക്ക് യോജിപ്പിക്കുക + സ്‌ക്രീൻ നിറയ്ക്കുക + ഉറവിടം കണ്ടെത്തിയില്ല + ഉറവിടമൊന്നും ലഭ്യമല്ല + ഉറവിടം തിരഞ്ഞെടുത്തു + തിരയുക + ഫലങ്ങളൊന്നും കണ്ടെത്തിയില്ല + \'കാണുന്നത് തുടരുക\' കണ്ടെത്തിയില്ല + ഡൗൺലോഡുകളൊന്നും കണ്ടെത്തിയില്ല + ഫയൽ കണ്ടെത്തിയില്ല + സാധുവായ എപ്പിസോഡ് കണ്ടെത്തിയില്ല + ദാതാവിനെ തിരഞ്ഞെടുക്കുക + തിരഞ്ഞെടുത്തു + ലൈബ്രറി + ബുക്ക്മാർക്കുകൾ + %1$s പുനരാരംഭിക്കുന്നു... + diff --git a/app/src/main/res-car/values-b+mn/strings_car.xml b/app/src/main/res-car/values-b+mn/strings_car.xml new file mode 100644 index 00000000000..69bb275def9 --- /dev/null +++ b/app/src/main/res-car/values-b+mn/strings_car.xml @@ -0,0 +1,51 @@ + + + Ачаалж байна... + Алдаа + Контент ачаалахад алдаа гарлаа + Таалагдсан + Түүх + Татаж авсан + Нийлүүлэгч + Одоогийн + Цэс + Нүүр хуудасны контент + Нийлүүлэгчээс контент алга + Нийлүүлэгч олдсонгүй + Эх сурвалж + Эх сурвалжууд + Үйл явдал + Дүрүүд + Дэлгэрэнгүйг ачаалахад алдаа гарлаа + Ангийн жагсаалт + Бүлэг + Бүлгүүд + Анги + Анги олдсонгүй + ТВ цуврал биш + Таалагдсанд нэмлээ + Таалагдсанаас хаслаа + Таалагдсан контент олдсонгүй + Тоглуулж эхэлж байна... + Тоглуулж байна + Холбоос олдсонгүй + Тоглуулах контент олдсонгүй + Дэлгэрэнгүйг ачаалах боломжгүй + Холбоос ачаалахад алдаа гарлаа + Дэлгэцэнд тааруулах + Дэлгэц дүүргэх + Эх сурвалж олдсонгүй + Боломжит эх сурвалж алга + Эх сурвалж сонгогдсон + Хайх + Үр дүн олдсонгүй + \'Үргэлжлүүлж үзэх\' олдсонгүй + Таталт олдсонгүй + Файл олдсонгүй + Хүчинтэй анги олдсонгүй + Нийлүүлэгч сонгох + Сонгогдсон + Сан + Хавчуурга + %1$s үргэлжлүүлж байна... + diff --git a/app/src/main/res-car/values-b+mr/strings_car.xml b/app/src/main/res-car/values-b+mr/strings_car.xml new file mode 100644 index 00000000000..656591ef267 --- /dev/null +++ b/app/src/main/res-car/values-b+mr/strings_car.xml @@ -0,0 +1,51 @@ + + + लोड होत आहे... + त्रुटी + सामग्री लोड करताना त्रुटी + आवडते + इतिहास + डाउनलोड + पुरवठादार + वर्तमान + मेनू + होम सामग्री + पुरवठादाराकडून कोणतीही सामग्री नाही + पुरवठादार सापडला नाही + स्त्रोत + स्त्रोत + कथानक + कलाकार + तपशील लोड करताना त्रुटी + एपिसोड यादी + सीझन + सीझन + एपिसोड + कोणतेही एपिसोड सापडले नाहीत + टीव्ही मालिका नाही + आवडत्यांमध्ये जोडले + आवडत्यांमधून काढले + कोणतेही आवडते सापडले नाहीत + प्लेबॅक सुरू होत आहे... + प्ले होत आहे + कोणतीही लिंक सापडली नाही + कोणतीही प्ले करण्यायोग्य सामग्री सापडली नाही + तपशील लोड करण्यास अक्षम + लिंक लोड करताना त्रुटी + स्क्रीनवर बसवा + स्क्रीन भरा + कोणताही स्त्रोत सापडला नाही + कोणताही स्त्रोत उपलब्ध नाही + स्त्रोत निवडला + शोधा + कोणतेही परिणाम सापडले नाहीत + \'पाहणे सुरू ठेवा\' सापडले नाही + कोणतेही डाउनलोड सापडले नाहीत + फाइल सापडली नाही + कोणताही वैध एपिसोड सापडला नाही + पुरवठादार निवडा + निवडलेले + ग्रंथालय + बुकमार्क + %1$s पुन्हा सुरू करत आहे... + diff --git a/app/src/main/res-car/values-b+ms/strings_car.xml b/app/src/main/res-car/values-b+ms/strings_car.xml new file mode 100644 index 00000000000..3735de6abcc --- /dev/null +++ b/app/src/main/res-car/values-b+ms/strings_car.xml @@ -0,0 +1,51 @@ + + + Memuatkan... + Ralat + Ralat memuatkan kandungan + Kegemaran + Sejarah + Muat Turun + Penyedia + Semasa + Menu + Kandungan Laman Utama + Tiada kandungan dari penyedia + Penyedia tidak ditemui + Sumber + Sumber + Plot + Pelakon + Ralat memuatkan butiran + Senarai Episod + Musim + Musim + Episod + Tiada episod ditemui + Bukan siri TV + Ditambah ke kegemaran + Dibuang dari kegemaran + Tiada kegemaran ditemui + Memulakan main balik... + Memainkan + Pautan tidak ditemui + Tiada kandungan boleh dimainkan ditemui + Tidak dapat memuatkan butiran + Ralat memuatkan pautan + Muat ke Skrin + Penuhi Skrin + Tiada sumber ditemui + Tiada sumber tersedia + Sumber dipilih + Cari + Tiada hasil ditemui + \'Teruskan Menonton\' tidak ditemui + Tiada muat turun ditemui + Fail tidak ditemui + Tiada episod sah ditemui + Pilih Penyedia + Dipilih + Perpustakaan + Penanda Buku + Menyambung semula %1$s... + diff --git a/app/src/main/res-car/values-b+mt/strings_car.xml b/app/src/main/res-car/values-b+mt/strings_car.xml new file mode 100644 index 00000000000..ac0a25531bb --- /dev/null +++ b/app/src/main/res-car/values-b+mt/strings_car.xml @@ -0,0 +1,74 @@ + + + + Loading... + Error + Error loading content + + + Favorites + History + Downloads + Provider + Current + Menu + Home Content + No content from provider + Provider not found + + + Source + Sources + Plot + Cast + Error loading details + + + Episode List + Season + Seasons + Episode + No episodes found + Not a TV series + + + Added to favorites + Removed from favorites + No favorites found + + + Starting playback... + Playing + No link found + No playable content found + Unable to load details + Error loading links + Fit to screen + Fill screen + + + No source found + No source available + Source selected + + + Search + No results found + + + No \'Continue watching\' items found + + + No completed downloads found + File not found + No valid episode found + + + Select Provider + Selected + + + Library + Bookmarks + Resuming %1$s... + diff --git a/app/src/main/res-car/values-b+my/strings_car.xml b/app/src/main/res-car/values-b+my/strings_car.xml new file mode 100644 index 00000000000..67f29ecd327 --- /dev/null +++ b/app/src/main/res-car/values-b+my/strings_car.xml @@ -0,0 +1,51 @@ + + + Loading... + အမှား + အကြောင်းအရာကို ဆွဲယူရာတွင် အမှားဖြစ်နေသည် + အကြိုက်ဆုံးများ + မှတ်တမ်း + ဒေါင်းလုဒ်များ + ပံ့ပိုးသူ + လက်ရှိ + မီနူး + ပင်မစာမျက်နှာ + ပံ့ပိုးသူထံမှ အကြောင်းအရာ မရှိပါ + ပံ့ပိုးသူကို မတွေ့ပါ + အရင်းအမြစ် + အရင်းအမြစ်များ + ဇာတ်လမ်းအကျဉ်း + သရုပ်ဆောင်များ + အသေးစိတ်အချက်အလက်များကို ဆွဲယူရာတွင် အမှားဖြစ်နေသည် + အပိုင်းများ + ရာသီ + ရာသီများ + အပိုင်း + အပိုင်းများ မတွေ့ပါ + တီဗီစီးရီး မဟုတ်ပါ + အကြိုက်ဆုံးများသို့ ထည့်ပြီးပါပြီ + အကြိုက်ဆုံးများမှ ဖယ်ရှားလိုက်ပါပြီ + အကြိုက်ဆုံးများ မတွေ့ပါ + ဖွင့်နေသည်... + ဖွင့်နေသည် + လင့်ခ်မတွေ့ပါ + ဖွင့်နိုင်သော အကြောင်းအရာ မတွေ့ပါ + အသေးစိတ်အချက်အလက်များကို မဆွဲယူနိုင်ပါ + လင့်ခ်များကို ဆွဲယူရာတွင် အမှားဖြစ်နေသည် + မျက်နှာပြင်နှင့် အံကိုက် + မျက်နှာပြင်အပြည့် + အရင်းအမြစ် မတွေ့ပါ + ရရှိနိုင်သော အရင်းအမြစ် မရှိပါ + အရင်းအမြစ်ကို ရွေးချယ်လိုက်သည် + ရှာဖွေရန် + ရလဒ်မတွေ့ပါ + \'ဆက်လက်ကြည့်ရှုရန်\' မတွေ့ပါ + ဒေါင်းလုဒ်များ မတွေ့ပါ + ဖိုင်မတွေ့ပါ + မှန်ကန်သော အပိုင်း မတွေ့ပါ + ပံ့ပိုးသူကို ရွေးချယ်ပါ + ရွေးချယ်ပြီး + စာကြည့်တိုက် + မှတ်သားမှုများ + %1$s ကို ဆက်လက်ကြည့်ရှုနေသည်... + diff --git a/app/src/main/res-car/values-b+ne/strings_car.xml b/app/src/main/res-car/values-b+ne/strings_car.xml new file mode 100644 index 00000000000..ec6ce51b767 --- /dev/null +++ b/app/src/main/res-car/values-b+ne/strings_car.xml @@ -0,0 +1,51 @@ + + + लोड हुँदैछ... + त्रुटि + सामग्री लोड गर्दा त्रुटि + मनपर्नेहरू + इतिहास + डाउनलोडहरू + प्रदायक + हालको + मेनु + गृह सामग्री + प्रदायकबाट कुनै सामग्री छैन + प्रदायक फेला परेन + स्रोत + स्रोतहरू + कथा + कलाकारहरू + विवरण लोड गर्दा त्रुटि + एपिसोड सूची + सिजन + सिजनहरू + एपिसोड + कुनै एपिसोड फेला परेन + टिभी शृङ्खला होइन + मनपर्नेमा थपियो + मनपर्नेबाट हटाइयो + कुनै मनपर्ने फेला परेन + प्लेब्याक सुरु हुँदैछ... + बजाउँदै + कुनै लिङ्क फेला परेन + कुनै बजाउन योग्य सामग्री फेला परेन + विवरण लोड गर्न असक्षम + लिङ्कहरू लोड गर्दा त्रुटि + स्क्रिनमा मिलाउनुहोस् + स्क्रिन भर्नुहोस् + कुनै स्रोत फेला परेन + कुनै स्रोत उपलब्ध छैन + स्रोत चयन गरियो + खोज्नुहोस् + कुनै नतिजा फेला परेन + \'हेर्न जारी राख्नुहोस्\' फेला परेन + कुनै डाउनलोड फेला परेन + फाइल फेला परेन + कुनै मान्य एपिसोड फेला परेन + प्रदायक चयन गर्नुहोस् + चयन गरिएको + पुस्तकालय + बुकमार्कहरू + %1$s सुचारु हुँदैछ... + diff --git a/app/src/main/res-car/values-b+nl/strings_car.xml b/app/src/main/res-car/values-b+nl/strings_car.xml new file mode 100644 index 00000000000..891c01a4b40 --- /dev/null +++ b/app/src/main/res-car/values-b+nl/strings_car.xml @@ -0,0 +1,51 @@ + + + Laden... + Fout + Fout bij laden inhoud + Favorieten + Geschiedenis + Downloads + Aanbieder + Huidig + Menu + De inhoud van het huis + Geen inhoud van aanbieder + Aanbieder niet gevonden + Bron + Bronnen + Verhaal + Cast + Fout bij laden details + Afleveringenlijst + Seizoen + Seizoenen + Aflevering + Geen afleveringen gevonden + Geen TV-serie + Toegevoegd aan favorieten + Verwijderd uit favorieten + Geen favorieten gevonden + Afspelen starten... + Afspelen + Geen link gevonden + Geen afspeelbare inhoud gevonden + Kan details niet laden + Fout bij laden links + Passend maken + Scherm vullen + Geen bron gevonden + Geen bron beschikbaar + Bron geselecteerd + Zoeken + Geen resultaten gevonden + Geen \'Verder kijken\' gevonden + Geen downloads gevonden + Bestand niet gevonden + Geen geldige aflevering gevonden + Selecteer aanbieder + Geselecteerd + Bibliotheek + Bladwijzers + Hervatten %1$s... + diff --git a/app/src/main/res-car/values-b+nn/strings_car.xml b/app/src/main/res-car/values-b+nn/strings_car.xml new file mode 100644 index 00000000000..ac0a25531bb --- /dev/null +++ b/app/src/main/res-car/values-b+nn/strings_car.xml @@ -0,0 +1,74 @@ + + + + Loading... + Error + Error loading content + + + Favorites + History + Downloads + Provider + Current + Menu + Home Content + No content from provider + Provider not found + + + Source + Sources + Plot + Cast + Error loading details + + + Episode List + Season + Seasons + Episode + No episodes found + Not a TV series + + + Added to favorites + Removed from favorites + No favorites found + + + Starting playback... + Playing + No link found + No playable content found + Unable to load details + Error loading links + Fit to screen + Fill screen + + + No source found + No source available + Source selected + + + Search + No results found + + + No \'Continue watching\' items found + + + No completed downloads found + File not found + No valid episode found + + + Select Provider + Selected + + + Library + Bookmarks + Resuming %1$s... + diff --git a/app/src/main/res-car/values-b+no/strings_car.xml b/app/src/main/res-car/values-b+no/strings_car.xml new file mode 100644 index 00000000000..1b884c6e828 --- /dev/null +++ b/app/src/main/res-car/values-b+no/strings_car.xml @@ -0,0 +1,51 @@ + + + Laster inn... + Feil + Feil ved lasting av innhold + Favoritter + Historikk + Nedlastinger + Leverandør + Nåværende + Meny + Hjem-innhold + Ingen innhold fra leverandør + Leverandør ikke funnet + Kilde + Kilder + Handling + Skuespillere + Feil ved lasting av detaljer + Episodeliste + Sesong + Sesonger + Episode + Ingen episoder funnet + Ikke en TV-serie + Lagt til i favoritter + Fjernet fra favoritter + Ingen favoritter funnet + Starter avspilling... + Spiller av + Ingen lenke funnet + Ingen spillbart innhold funnet + Kan ikke laste detaljer + Feil ved lasting av lenker + Tilpass til skjerm + Fyll skjerm + Ingen kilde funnet + Ingen kilde tilgjengelig + Kilde valgt + Søk + Ingen resultater funnet + \'Fortsett å se\' ikke funnet + Ingen nedlastinger funnet + Fil ikke funnet + Ingen gyldig episode funnet + Velg leverandør + Valgt + Bibliotek + Bokmerker + Gjenopptar %1$s... + diff --git a/app/src/main/res-car/values-b+or/strings_car.xml b/app/src/main/res-car/values-b+or/strings_car.xml new file mode 100644 index 00000000000..ac0a25531bb --- /dev/null +++ b/app/src/main/res-car/values-b+or/strings_car.xml @@ -0,0 +1,74 @@ + + + + Loading... + Error + Error loading content + + + Favorites + History + Downloads + Provider + Current + Menu + Home Content + No content from provider + Provider not found + + + Source + Sources + Plot + Cast + Error loading details + + + Episode List + Season + Seasons + Episode + No episodes found + Not a TV series + + + Added to favorites + Removed from favorites + No favorites found + + + Starting playback... + Playing + No link found + No playable content found + Unable to load details + Error loading links + Fit to screen + Fill screen + + + No source found + No source available + Source selected + + + Search + No results found + + + No \'Continue watching\' items found + + + No completed downloads found + File not found + No valid episode found + + + Select Provider + Selected + + + Library + Bookmarks + Resuming %1$s... + diff --git a/app/src/main/res-car/values-b+pa/strings_car.xml b/app/src/main/res-car/values-b+pa/strings_car.xml new file mode 100644 index 00000000000..6b1e7ca0dc0 --- /dev/null +++ b/app/src/main/res-car/values-b+pa/strings_car.xml @@ -0,0 +1,51 @@ + + + ਲੋਡ ਹੋ ਰਿਹਾ ਹੈ... + ਗਲਤੀ + ਸਮੱਗਰੀ ਲੋਡ ਕਰਨ ਵਿੱਚ ਗਲਤੀ + ਮਨਪਸੰਦ + ਇਤਿਹਾਸ + ਡਾਊਨਲੋਡ + ਪ੍ਰਦਾਤਾ + ਮੌਜੂਦਾ + ਮੀਨੂ + ਘਰੇਲੂ ਸਮੱਗਰੀ + ਪ੍ਰਦਾਤਾ ਤੋਂ ਕੋਈ ਸਮੱਗਰੀ ਨਹੀਂ + ਪ੍ਰਦਾਤਾ ਨਹੀਂ ਮਿਲਿਆ + ਸਰੋਤ + ਸਰੋਤ + ਕਹਾਣੀ + ਕਲਾਕਾਰ + ਵੇਰਵੇ ਲੋਡ ਕਰਨ ਵਿੱਚ ਗਲਤੀ + ਐਪੀਸੋਡ ਸੂਚੀ + ਸੀਜ਼ਨ + ਸੀਜ਼ਨ + ਐਪੀਸੋਡ + ਕੋਈ ਐਪੀਸੋਡ ਨਹੀਂ ਮਿਲਿਆ + ਟੀਵੀ ਲੜੀਵਾਰ ਨਹੀਂ + ਮਨਪਸੰਦ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ + ਮਨਪਸੰਦ ਤੋਂ ਹਟਾਇਆ ਗਿਆ + ਕੋਈ ਮਨਪਸੰਦ ਨਹੀਂ ਮਿਲਿਆ + ਪਲੇਬੈਕ ਸ਼ੁਰੂ ਹੋ ਰਿਹਾ ਹੈ... + ਖੇਡ ਰਿਹਾ ਹੈ + ਕੋਈ ਲਿੰਕ ਨਹੀਂ ਮਿਲਿਆ + ਕੋਈ ਖੇਡਣ ਯੋਗ ਸਮੱਗਰੀ ਨਹੀਂ ਮਿਲੀ + ਵੇਰਵੇ ਲੋਡ ਕਰਨ ਵਿੱਚ ਅਸਮਰੱਥ + ਲਿੰਕ ਲੋਡ ਕਰਨ ਵਿੱਚ ਗਲਤੀ + ਸਕ੍ਰੀਨ \'ਤੇ ਫਿੱਟ ਕਰੋ + ਸਕ੍ਰੀਨ ਭਰੋ + ਕੋਈ ਸਰੋਤ ਨਹੀਂ ਮਿਲਿਆ + ਕੋਈ ਸਰੋਤ ਉਪਲਬਧ ਨਹੀਂ + ਸਰੋਤ ਚੁਣਿਆ ਗਿਆ + ਖੋਜ + ਕੋਈ ਨਤੀਜਾ ਨਹੀਂ ਮਿਲਿਆ + \'ਦੇਖਣਾ ਜਾਰੀ ਰੱਖੋ\' ਨਹੀਂ ਮਿਲਿਆ + ਕੋਈ ਡਾਊਨਲੋਡ ਨਹੀਂ ਮਿਲਿਆ + ਫਾਈਲ ਨਹੀਂ ਮਿਲੀ + ਕੋਈ ਵੈਧ ਐਪੀਸੋਡ ਨਹੀਂ ਮਿਲਿਆ + ਪ੍ਰਦਾਤਾ ਚੁਣੋ + ਚੁਣਿਆ ਗਿਆ + ਲਾਇਬ੍ਰੇਰੀ + ਬੁੱਕਮਾਰਕ + %1$s ਮੁੜ ਸ਼ੁਰੂ ਹੋ ਰਿਹਾ ਹੈ... + diff --git a/app/src/main/res-car/values-b+pl/strings_car.xml b/app/src/main/res-car/values-b+pl/strings_car.xml new file mode 100644 index 00000000000..99f3d4095b1 --- /dev/null +++ b/app/src/main/res-car/values-b+pl/strings_car.xml @@ -0,0 +1,51 @@ + + + Ładowanie... + Błąd + Błąd ładowania treści + Ulubione + Historia + Pobrane + Dostawca + Obecny + Menu + Treść główna + Brak treści od dostawcy + Nie znaleziono dostawcy + Źródło + Źródła + Fabuła + Obsada + Błąd ładowania szczegółów + Lista odcinków + Sezon + Sezony + Odcinek + Nie znaleziono odcinków + To nie jest serial TV + Dodano do ulubionych + Usunięto z ulubionych + Nie znaleziono ulubionych + Rozpoczynanie odtwarzania... + Odtwarzanie + Nie znaleziono łącza + Nie znaleziono treści do odtworzenia + Nie można załadować szczegółów + Błąd ładowania łączy + Dopasuj do ekranu + Wypełnij ekran + Nie znaleziono źródła + Brak dostępnych źródeł + Wybrano źródło + Szukaj + Brak wyników + Nie znaleziono „Oglądaj dalej” + Brak pobranych plików + Plik nie znaleziony + Brak poprawnego odcinka + Wybierz dostawcę + Wybrano + Biblioteka + Zakładki + Wznawianie %1$s... + diff --git a/app/src/main/res-car/values-b+pt+BR/strings_car.xml b/app/src/main/res-car/values-b+pt+BR/strings_car.xml new file mode 100644 index 00000000000..ac0a25531bb --- /dev/null +++ b/app/src/main/res-car/values-b+pt+BR/strings_car.xml @@ -0,0 +1,74 @@ + + + + Loading... + Error + Error loading content + + + Favorites + History + Downloads + Provider + Current + Menu + Home Content + No content from provider + Provider not found + + + Source + Sources + Plot + Cast + Error loading details + + + Episode List + Season + Seasons + Episode + No episodes found + Not a TV series + + + Added to favorites + Removed from favorites + No favorites found + + + Starting playback... + Playing + No link found + No playable content found + Unable to load details + Error loading links + Fit to screen + Fill screen + + + No source found + No source available + Source selected + + + Search + No results found + + + No \'Continue watching\' items found + + + No completed downloads found + File not found + No valid episode found + + + Select Provider + Selected + + + Library + Bookmarks + Resuming %1$s... + diff --git a/app/src/main/res-car/values-b+pt/strings_car.xml b/app/src/main/res-car/values-b+pt/strings_car.xml new file mode 100644 index 00000000000..0195a196e51 --- /dev/null +++ b/app/src/main/res-car/values-b+pt/strings_car.xml @@ -0,0 +1,51 @@ + + + Carregando... + Erro + Erro ao carregar conteúdo + Favoritos + Histórico + Downloads + Provedor + Atual + Menu + Conteúdo da página inicial + Nenhum conteúdo do provedor + Provedor não encontrado + Fonte + Fontes + Enredo + Elenco + Erro ao carregar detalhes + Lista de episódios + Temporada + Temporadas + Episódio + Nenhum episódio encontrado + Não é uma série de TV + Adicionado aos favoritos + Removido dos favoritos + Nenhum favorito encontrado + Iniciando reprodução... + Reproduzindo + Nenhum link encontrado + Nenhum conteúdo reproduzível encontrado + Não foi possível carregar os detalhes + Erro ao carregar links + Ajustar à tela + Preencher tela + Nenhuma fonte encontrada + Nenhuma fonte disponível + Fonte selecionada + Buscar + Nenhum resultado encontrado + Nenhum item \'Continuar assistindo\' encontrado + Nenhum download encontrado + Arquivo não encontrado + Nenhum episódio válido encontrado + Selecionar provedor + Selecionado + Biblioteca + Marcadores + Retomando %1$s... + diff --git a/app/src/main/res-car/values-b+qt/strings_car.xml b/app/src/main/res-car/values-b+qt/strings_car.xml new file mode 100644 index 00000000000..ac0a25531bb --- /dev/null +++ b/app/src/main/res-car/values-b+qt/strings_car.xml @@ -0,0 +1,74 @@ + + + + Loading... + Error + Error loading content + + + Favorites + History + Downloads + Provider + Current + Menu + Home Content + No content from provider + Provider not found + + + Source + Sources + Plot + Cast + Error loading details + + + Episode List + Season + Seasons + Episode + No episodes found + Not a TV series + + + Added to favorites + Removed from favorites + No favorites found + + + Starting playback... + Playing + No link found + No playable content found + Unable to load details + Error loading links + Fit to screen + Fill screen + + + No source found + No source available + Source selected + + + Search + No results found + + + No \'Continue watching\' items found + + + No completed downloads found + File not found + No valid episode found + + + Select Provider + Selected + + + Library + Bookmarks + Resuming %1$s... + diff --git a/app/src/main/res-car/values-b+ro/strings_car.xml b/app/src/main/res-car/values-b+ro/strings_car.xml new file mode 100644 index 00000000000..fb7f4316bbe --- /dev/null +++ b/app/src/main/res-car/values-b+ro/strings_car.xml @@ -0,0 +1,51 @@ + + + Se încarcă... + Eroare + Eroare la încărcarea conținutului + Favorite + Istoric + Descărcări + Furnizor + Curent + Meniu + Conținut acasă + Niciun conținut de la furnizor + Furnizorul nu a fost găsit + Sursă + Surse + Intrigă + Distribuție + Eroare la încărcarea detaliilor + Listă episoade + Sezon + Sezoane + Episod + Nu s-au găsit episoade + Nu este serial TV + Adăugat la favorite + Eliminat din favorite + Nu s-au găsit favorite + Se începe redarea... + Se redă + Nu s-a găsit link + Nu s-a găsit conținut care poate fi redat + Nu se pot încărca detaliile + Eroare la încărcarea linkurilor + Potrivire la ecran + Umplere ecran + Nu s-a găsit sursă + Nicio sursă disponibilă + Sursă selectată + Căutare + Niciun rezultat găsit + Nu s-a găsit \'Continuare vizionare\' + Nu s-au găsit descărcări + Fișierul nu a fost găsit + Nu s-a găsit episod valid + Selectează furnizor + Selectat + Bibliotecă + Marcaje + Se reia %1$s... + diff --git a/app/src/main/res-car/values-b+ru/strings_car.xml b/app/src/main/res-car/values-b+ru/strings_car.xml new file mode 100644 index 00000000000..5d9ba1db8ac --- /dev/null +++ b/app/src/main/res-car/values-b+ru/strings_car.xml @@ -0,0 +1,51 @@ + + + Загрузка... + Ошибка + Ошибка загрузки контента + Избранное + История + Загрузки + Провайдер + Текущий + Меню + Контент главной + Нет контента от провайдера + Провайдер не найден + Источник + Источники + Сюжет + Актеры + Ошибка загрузки деталей + Список эпизодов + Сезон + Сезоны + Эпизод + Эпизоды не найдены + Не сериал + Добавлено в избранное + Удалено из избранного + Избранное не найдено + Запуск воспроизведения... + Воспроизведение + Ссылка не найдена + Нет воспроизводимого контента + Не удалось загрузить детали + Ошибка загрузки ссылок + По размеру экрана + Заполнить экран + Источник не найден + Нет доступных источников + Источник выбран + Поиск + Результаты не найдены + Нет "Продолжить просмотр" + Загрузки не найдены + Файл не найден + Нет валидного эпизода + Выбрать провайдера + Выбрано + Библиотека + Закладки + Возобновление %1$s... + diff --git a/app/src/main/res-car/values-b+si/strings_car.xml b/app/src/main/res-car/values-b+si/strings_car.xml new file mode 100644 index 00000000000..62482b2491c --- /dev/null +++ b/app/src/main/res-car/values-b+si/strings_car.xml @@ -0,0 +1,51 @@ + + + පූරණය වෙමින්... + දෝෂය + අන්තර්ගතය පූරණය කිරීමේ දෝෂය + ප්‍රියතමයන් + ඉතිහාසය + බාගැනීම් + සැපයුම්කරු + වත්මන් + මෙනුව + මුල් පිටුව අන්තර්ගතය + සැපයුම්කරුගෙන් අන්තර්ගතයක් නැත + සැපයුම්කරු හමු නොවිණි + මූලාශ්‍රය + මූලාශ්‍ර + කතාව + නළු නිළියන් + විස්තර පූරණය කිරීමේ දෝෂය + කොටස් ලැයිස්තුව + වාරය + වාර + කොටස + කොටස් හමු නොවිණි + රූපවාහිනී කතා මාලාවක් නොවේ + ප්‍රියතමයන් වෙත එක් කරන ලදී + ප්‍රියතමයන්ගෙන් ඉවත් කරන ලදී + ප්‍රියතමයන් හමු නොවිණි + ප්‍රතිණිර්මාණය ආරම්භ කරමින්... + වාදනය වෙමින් + සබැඳියක් හමු නොවිණි + වාදනය කළ හැකි අන්තර්ගතයක් හමු නොවිණි + විස්තර පූරණය කළ නොහැක + සබැඳි පූරණය කිරීමේ දෝෂය + තිරයට ගැලපේ + තිරය පුරවන්න + මූලාශ්‍රයක් හමු නොවිණි + මූලාශ්‍රයක් නොමැත + මූලාශ්‍රය තෝරා ගන්නා ලදී + සොයන්න + ප්‍රතිඵල හමු නොවිණි + \'නැරඹීම අඛණ්ඩව\' හමු නොවිණි + බාගැනීම් හමු නොවිණි + ගොනුව හමු නොවිණි + වලංගු කොටසක් හමු නොවිණි + සැපයුම්කරු තෝරන්න + තෝරා ගන්නා ලදී + පුස්තකාලය + පොත් යොමු + %1$s නැවත ආරම්භ කරමින්... + diff --git a/app/src/main/res-car/values-b+sk/strings_car.xml b/app/src/main/res-car/values-b+sk/strings_car.xml new file mode 100644 index 00000000000..250aa89c43a --- /dev/null +++ b/app/src/main/res-car/values-b+sk/strings_car.xml @@ -0,0 +1,51 @@ + + + Načítavanie... + Chyba + Chyba pri načítavaní obsahu + Obľúbené + História + Sťahovania + Poskytovateľ + Aktuálne + Menu + Domovský obsah + Žiadny obsah od poskytovateľa + Poskytovateľ nenájdený + Zdroj + Zdroje + Dej + Obsadenie + Chyba pri načítavaní podrobností + Zoznam epizód + Séria + Série + Epizóda + Nenašli sa žiadne epizódy + Nie je to TV seriál + Pridané do obľúbených + Odstránené z obľúbených + Žiadne obľúbené položky + Spúšťanie prehrávania... + Prehrávanie + Odkaz sa nenašiel + Žiadny prehrávateľný obsah + Nedá sa načítať podrobnosti + Chyba pri načítavaní odkazov + Prispôsobiť na obrazovku + Vyplniť obrazovku + Zdroj sa nenašiel + Žiadny zdroj k dispozícii + Zdroj vybraný + Hľadať + Žiadne výsledky sa nenašli + \'Pokračovať v sledovaní\' sa nenašlo + Žiadne sťahovania + Súbor nenájdený + Žiadna platná epizóda + Vybrať poskytovateľa + Vybrané + Knižnica + Záložky + Obnovovanie %1$s... + diff --git a/app/src/main/res-car/values-b+sl/strings_car.xml b/app/src/main/res-car/values-b+sl/strings_car.xml new file mode 100644 index 00000000000..5a97685aaff --- /dev/null +++ b/app/src/main/res-car/values-b+sl/strings_car.xml @@ -0,0 +1,51 @@ + + + Nalaganje... + Napaka + Napaka pri nalaganju vsebine + Priljubljene + Zgodovina + Prenosi + Ponudnik + Trenutno + Meni + Domača vsebina + Ni vsebine od ponudnika + Ponudnik ni najden + Vir + Viri + Zgodba + Igralska zasedba + Napaka pri nalaganju podrobnosti + Seznam epizod + Sezona + Sezone + Epizoda + Ni najdenih epizod + Ni TV serija + Dodano med priljubljene + Odstranjeno iz priljubljenih + Ni priljubljenih + Začenjam predvajanje... + Predvajam + Povezava ni najdena + Ni vsebine za predvajanje + Ni bilo mogoče naložiti podrobnosti + Napaka pri nalaganju povezav + Prilagodi zaslonu + Napolni zaslon + Vir ni najden + Ni razpoložljivih virov + Vir izbran + Iskanje + Ni rezultatov + \'Nadaljuj z ogledom\' ni najdeno + Ni prenosov + Datoteka ni najdena + Ni veljavne epizode + Izberi ponudnika + Izbrano + Knjižnica + Zaznamki + Nadaljujem %1$s... + diff --git a/app/src/main/res-car/values-b+so/strings_car.xml b/app/src/main/res-car/values-b+so/strings_car.xml new file mode 100644 index 00000000000..ac0a25531bb --- /dev/null +++ b/app/src/main/res-car/values-b+so/strings_car.xml @@ -0,0 +1,74 @@ + + + + Loading... + Error + Error loading content + + + Favorites + History + Downloads + Provider + Current + Menu + Home Content + No content from provider + Provider not found + + + Source + Sources + Plot + Cast + Error loading details + + + Episode List + Season + Seasons + Episode + No episodes found + Not a TV series + + + Added to favorites + Removed from favorites + No favorites found + + + Starting playback... + Playing + No link found + No playable content found + Unable to load details + Error loading links + Fit to screen + Fill screen + + + No source found + No source available + Source selected + + + Search + No results found + + + No \'Continue watching\' items found + + + No completed downloads found + File not found + No valid episode found + + + Select Provider + Selected + + + Library + Bookmarks + Resuming %1$s... + diff --git a/app/src/main/res-car/values-b+sq/strings_car.xml b/app/src/main/res-car/values-b+sq/strings_car.xml new file mode 100644 index 00000000000..dcb8bc43bfd --- /dev/null +++ b/app/src/main/res-car/values-b+sq/strings_car.xml @@ -0,0 +1,51 @@ + + + Duke ngarkuar... + Gabim + Gabim në ngarkimin e përmbajtjes + Të preferuarat + Historia + Shkarkimet + Ofruesi + Aktual + Menu + Përmbajtja e kreut + Nuk ka përmbajtje nga ofruesi + Ofruesi nuk u gjet + Burimi + Burimet + Përmbajtja + Aktorët + Gabim në ngarkimin e detajeve + Lista e episodeve + Sezoni + Sezonet + Episodi + Nuk u gjetën episode + Nuk është serial TV + U shtua te të preferuarat + U hoq nga të preferuarat + Nuk u gjetën të preferuara + Duke filluar luajtjen... + Duke luajtur + Nuk u gjet lidhje + Nuk u gjet përmbajtje për t\'u luajtur + Nuk mund të ngarkohen detajet + Gabim në ngarkimin e lidhjeve + Përshtat në ekran + Mbush ekranin + Nuk u gjet burim + Asnjë burim i disponueshëm + Burimi u zgjodh + Kërko + Nuk u gjetën rezultate + \'Vazhdo shikimin\' nuk u gjet + Nuk u gjetën shkarkime + Skedari nuk u gjet + Nuk u gjet episod i vlefshëm + Zgjidh ofruesin + E zgjedhur + Biblioteka + Faqerojtësit + Duke vazhduar %1$s... + diff --git a/app/src/main/res-car/values-b+sr/strings_car.xml b/app/src/main/res-car/values-b+sr/strings_car.xml new file mode 100644 index 00000000000..6b81d44509b --- /dev/null +++ b/app/src/main/res-car/values-b+sr/strings_car.xml @@ -0,0 +1,51 @@ + + + Učitavanje... + Greška + Greška pri učitavanju sadržaja + Favoriti + Istorija + Preuzimanja + Provajder + Trenutno + Meni + Početni sadržaj + Nema sadržaja od provajdera + Provajder nije pronađen + Izvor + Izvori + Radnja + Uloge + Greška pri učitavanju detalja + Lista epizoda + Sezona + Sezone + Epizoda + Nema pronađenih epizoda + Nije TV serija + Dodato u favorite + Uklonjeno iz favorita + Nema favorita + Pokretanje reprodukcije... + Reprodukcija + Link nije pronađen + Sadržaj za reprodukciju nije pronađen + Nije moguće učitati detalje + Greška pri učitavanju linkova + Prilagodi ekranu + Popuni ekran + Izvor nije pronađen + Izvor nije dostupan + Izvor izabran + Pretraga + Nema rezultata + \'Nastavi gledanje\' nije pronađeno + Nema preuzimanja + Datoteka nije pronađena + Nema važeće epizode + Izaberi provajdera + Izabrano + Biblioteka + Obeleživači + Nastavljanje %1$s... + diff --git a/app/src/main/res-car/values-b+sv/strings_car.xml b/app/src/main/res-car/values-b+sv/strings_car.xml new file mode 100644 index 00000000000..fcbf7528bc8 --- /dev/null +++ b/app/src/main/res-car/values-b+sv/strings_car.xml @@ -0,0 +1,51 @@ + + + Laddar... + Fel + Fel vid laddning av innehåll + Favoriter + Historik + Nedladdningar + Leverantör + Nuvarande + Meny + Heminnehåll + Inget innehåll från leverantör + Leverantör hittades inte + Källa + Källor + Handling + Skådespelare + Fel vid laddning av detaljer + Avsnittslista + Säsong + Säsonger + Avsnitt + Inga avsnitt hittades + Inte en TV-serie + Tillagd i favoriter + Borttagen från favoriter + Inga favoriter hittades + Startar uppspelning... + Spelar + Ingen länk hittades + Inget spelbart innehåll hittades + Kunde inte ladda detaljer + Fel vid laddning av länkar + Anpassa till skärm + Fyll skärm + Ingen källa hittades + Ingen källa tillgänglig + Källa vald + Sök + Inga resultat hittades + Inget \'Fortsätt titta\' hittades + Inga nedladdningar hittades + Filen hittades inte + Inget giltigt avsnitt hittades + Välj leverantör + Vald + Bibliotek + Bokmärken + Återupptar %1$s... + diff --git a/app/src/main/res-car/values-b+sw/strings_car.xml b/app/src/main/res-car/values-b+sw/strings_car.xml new file mode 100644 index 00000000000..97997a98256 --- /dev/null +++ b/app/src/main/res-car/values-b+sw/strings_car.xml @@ -0,0 +1,51 @@ + + + Inapakia... + Hitilafu + Hitilafu katika kupakia maudhui + Vipendwa + Historia + Vipakuliwa + Mtoaji + Sasa + Menyu + Maudhui ya Nyumbani + Hakuna maudhui kutoka kwa mtoaji + Mtoaji hajapatikana + Chanzo + Vyanzo + Hadithi + Waigizaji + Hitilafu katika kupakia maelezo + Orodha ya Vipindi + Msimu + Misimu + Kipindi + Hakuna vipindi vilivyopatikana + Si mfululizo wa TV + Imeongezwa kwenye vipendwa + Imeondolewa kwenye vipendwa + Hakuna vipendwa vilivyopatikana + Inaanza kucheza... + Inacheza + Hakuna kiungo kilichopatikana + Hakuna maudhui ya kucheza yaliyopatikana + Imeshindwa kupakia maelezo + Hitilafu katika kupakia viungo + Toshea kwenye Skrini + Jaza Skrini + Hakuna chanzo kilichopatikana + Hakuna chanzo kinachopatikana + Chanzo kimechaguliwa + Tafuta + Hakuna matokeo yaliyopatikana + \'Endelea Kutazama\' haijapatikana + Hakuna vipakuliwa vilivyopatikana + Faili haijapatikana + Hakuna kipindi halali kilichopatikana + Chagua Mtoaji + Imechaguliwa + Maktaba + Alamisho + Inaendelea %1$s... + diff --git a/app/src/main/res-car/values-b+ta/strings_car.xml b/app/src/main/res-car/values-b+ta/strings_car.xml new file mode 100644 index 00000000000..b7960e0b796 --- /dev/null +++ b/app/src/main/res-car/values-b+ta/strings_car.xml @@ -0,0 +1,51 @@ + + + ஏற்றுகிறது... + பிழை + உள்ளடக்கத்தை ஏற்றுவதில் பிழை + விருப்பங்கள் + வரலாறு + பதிவிறக்கங்கள் + வழங்குநர் + தற்போதைய + மெனு + முகப்பு உள்ளடக்கம் + வழங்குநரிடமிருந்து உள்ளடக்கம் இல்லை + வழங்குநரைக் காணவில்லை + மூலம் + மூலங்கள் + கதைக்களம் + நடிப்பு + விவரங்களை ஏற்றுவதில் பிழை + அத்தியாயப் பட்டியல் + பருவம் + பருவங்கள் + அத்தியாயம் + அத்தியாயங்கள் எதுவும் காணப்படவில்லை + தொலைக்காட்சித் தொடர் அல்ல + விருப்பங்களில் சேர்க்கப்பட்டது + விருப்பங்களிலிருந்து நீக்கப்பட்டது + விருப்பங்கள் எதுவும் இல்லை + இயக்கத்தைத் தொடங்குகிறது... + இயங்குகிறது + இணைப்பு எதுவும் காணப்படவில்லை + இயக்கக்கூடிய உள்ளடக்கம் எதுவும் இல்லை + விவரங்களை ஏற்ற முடியவில்லை + இணைப்புகளை ஏற்றுவதில் பிழை + திரைக்குப் பொருத்து + திரையை நிரப்பு + மூலம் எதுவும் காணப்படவில்லை + மூலம் எதுவும் கிடைக்கவில்லை + மூலம் தேர்ந்தெடுக்கப்பட்டது + தேடு + முடிவுகள் எதுவும் இல்லை + \'தொடர்ந்து பார்க்க\' எதுவும் இல்லை + பதிவிறக்கங்கள் எதுவும் இல்லை + கோப்பைக் காணவில்லை + செல்லுபடியாகும் அத்தியாயம் எதுவும் இல்லை + வழங்குநரைத் தேர்ந்தெடு + தேர்ந்தெடுக்கப்பட்டது + நூலகம் + புத்தகக்குறிகள் + %1$s தொடர்கிறது... + diff --git a/app/src/main/res-car/values-b+te/strings_car.xml b/app/src/main/res-car/values-b+te/strings_car.xml new file mode 100644 index 00000000000..d2d9ace81ac --- /dev/null +++ b/app/src/main/res-car/values-b+te/strings_car.xml @@ -0,0 +1,51 @@ + + + లోడ్ అవుతోంది... + లోపం + కంటెంట్ లోడ్ చేయడంలో లోపం + ఇష్టమైనవి + చరిత్ర + డౌన్‌లోడ్‌లు + ప్రొవైడర్ + ప్రస్తుత + మెనూ + హోమ్ కంటెంట్ + ప్రొవైడర్ నుండి కంటెంట్ లేదు + ప్రొవైడర్ కనుగొనబడలేదు + మూలం + మూలాలు + కథాంశం + నటీనటులు + వివరాలు లోడ్ చేయడంలో లోపం + ఎపిసోడ్ జాబితా + సీజన్ + సీజన్లు + ఎపిసోడ్ + ఎపిసోడ్‌లు కనుగొనబడలేదు + టీవీ సిరీస్ కాదు + ఇష్టమైన వాటికి జోడించబడింది + ఇష్టమైన వాటి నుండి తీసివేయబడింది + ఇష్టమైనవి కనుగొనబడలేదు + ప్లేబ్యాక్ ప్రారంభమవుతోంది... + ప్లే అవుతోంది + లింక్ కనుగొనబడలేదు + ప్లే చేయగల కంటెంట్ కనుగొనబడలేదు + వివరాలు లోడ్ చేయడం సాధ్యం కాలేదు + లింక్‌లు లోడ్ చేయడంలో లోపం + స్క్రీన్‌కు సరిపోల్చండి + స్క్రీన్‌ను నింపండి + మూలం కనుగొనబడలేదు + మూలం అందుబాటులో లేదు + మూలం ఎంపిక చేయబడింది + శోధించు + ఫలితాలు కనుగొనబడలేదు + \'చూడటం కొనసాగించు\' కనుగొనబడలేదు + డౌన్‌లోడ్‌లు కనుగొనబడలేదు + ఫైల్ కనుగొనబడలేదు + చెల్లుబాటు అయ్యే ఎపిసోడ్ కనుగొనబడలేదు + ప్రొవైడర్‌ను ఎంచుకోండి + ఎంపిక చేయబడింది + లైబ్రరీ + బుక్‌మార్క్‌లు + %1$s పునఃప్రారంభించబడుతోంది... + diff --git a/app/src/main/res-car/values-b+tg/strings_car.xml b/app/src/main/res-car/values-b+tg/strings_car.xml new file mode 100644 index 00000000000..f29105798bb --- /dev/null +++ b/app/src/main/res-car/values-b+tg/strings_car.xml @@ -0,0 +1,51 @@ + + + Боргирӣ... + Хатогӣ + Хатогӣ дар боргирии муҳтаво + Дӯстдоштаҳо + Таърих + Боргириҳо + Провайдер + Ҷорӣ + Меню + Муҳтавои хона + Ҳеҷ муҳтаво аз провайдер нест + Провайдер ёфт нашуд + Манбаъ + Манбаъҳо + Сюжет + Ҳунармандон + Хатогӣ дар боргирии тафсилот + Рӯйхати қисмҳо + Мавсим + Мавсимҳо + Қисм + Ҳеҷ қисм ёфт нашуд + Силсилафилм нест + Ба дӯстдоштаҳо илова шуд + Аз дӯстдоштаҳо хориҷ шуд + Ҳеҷ дӯстдошта ёфт нашуд + Оғози пахш... + Дар ҳоли пахш + Ҳеҷ пайванд ёфт нашуд + Ҳеҷ муҳтавои қобили пахш ёфт нашуд + Тафсилот боргирӣ нашуд + Хатогӣ дар боргирии пайвандҳо + Ба экран мувофиқ кардан + Пур кардани экран + Ҳеҷ манбаъ ёфт нашуд + Ҳеҷ манбаъ дастрас нест + Манбаъ интихоб шуд + Ҷустуҷӯ + Ҳеҷ натиҷа ёфт нашуд + \'Идомаи тамошо\' ёфт нашуд + Ҳеҷ боргирӣ ёфт нашуд + Файл ёфт нашуд + Ҳеҷ қисми дуруст ёфт нашуд + Провайдерро интихоб кунед + Интихобшуда + Китобхона + Хабовҳо + Идомаи %1$s... + diff --git a/app/src/main/res-car/values-b+th/strings_car.xml b/app/src/main/res-car/values-b+th/strings_car.xml new file mode 100644 index 00000000000..374658cc309 --- /dev/null +++ b/app/src/main/res-car/values-b+th/strings_car.xml @@ -0,0 +1,51 @@ + + + กำลังโหลด... + ข้อผิดพลาด + ข้อผิดพลาดในการโหลดเนื้อหา + รายการโปรด + ประวัติ + ดาวน์โหลด + ผู้ให้บริการ + ปัจจุบัน + เมนู + เนื้อหาหน้าแรก + ไม่มีเนื้อหาจากผู้ให้บริการ + ไม่พบผู้ให้บริการ + แหล่งที่มา + แหล่งที่มา + เนื้อเรื่อง + นักแสดง + ข้อผิดพลาดในการโหลดรายละเอียด + รายการตอน + ซีซั่น + ซีซั่น + ตอน + ไม่พบตอน + ไม่ใช่ทีวีซีรีส์ + เพิ่มในรายการโปรดแล้ว + ลบออกจากรายการโปรดแล้ว + ไม่พบรายการโปรด + กำลังเริ่มเล่น... + กำลังเล่น + ไม่พบลิงก์ + ไม่พบเนื้อหาที่เล่นได้ + ไม่สามารถโหลดรายละเอียดได้ + ข้อผิดพลาดในการโหลดลิงก์ + พอดีหน้าจอ + เต็มหน้าจอ + ไม่พบแหล่งที่มา + ไม่มีแหล่งที่มาที่ใช้ได้ + เลือกแหล่งที่มาแล้ว + ค้นหา + ไม่พบผลลัพธ์ + ไม่พบ \'ดูต่อ\' + ไม่พบการดาวน์โหลด + ไม่พบไฟล์ + ไม่พบตอนที่ถูกต้อง + เลือกผู้ให้บริการ + ที่เลือก + ห้องสมุด + บุ๊กมาร์ก + กำลังดูต่อ %1$s... + diff --git a/app/src/main/res-car/values-b+ti/strings_car.xml b/app/src/main/res-car/values-b+ti/strings_car.xml new file mode 100644 index 00000000000..ac0a25531bb --- /dev/null +++ b/app/src/main/res-car/values-b+ti/strings_car.xml @@ -0,0 +1,74 @@ + + + + Loading... + Error + Error loading content + + + Favorites + History + Downloads + Provider + Current + Menu + Home Content + No content from provider + Provider not found + + + Source + Sources + Plot + Cast + Error loading details + + + Episode List + Season + Seasons + Episode + No episodes found + Not a TV series + + + Added to favorites + Removed from favorites + No favorites found + + + Starting playback... + Playing + No link found + No playable content found + Unable to load details + Error loading links + Fit to screen + Fill screen + + + No source found + No source available + Source selected + + + Search + No results found + + + No \'Continue watching\' items found + + + No completed downloads found + File not found + No valid episode found + + + Select Provider + Selected + + + Library + Bookmarks + Resuming %1$s... + diff --git a/app/src/main/res-car/values-b+tl/strings_car.xml b/app/src/main/res-car/values-b+tl/strings_car.xml new file mode 100644 index 00000000000..a99f6e086a9 --- /dev/null +++ b/app/src/main/res-car/values-b+tl/strings_car.xml @@ -0,0 +1,51 @@ + + + Naglo-load... + Error + Error sa pag-load ng nilalaman + Mga Paborito + Kasaysayan + Mga Download + Tagapagbigay + Kasalukuyan + Menu + Nilalaman ng tahanan + Walang nilalaman mula sa tagapagbigay + Hindi natagpuan ang tagapagbigay + Pinagmulan + Mga Pinagmulan + Kuwento + Tauhan + Error sa pag-load ng mga detalye + Listahan ng Episodyo + Season + Mga Season + Episodyo + Walang natagpuang episodyo + Hindi serye sa TV + Idinagdag sa mga paborito + Inalis sa mga paborito + Walang natagpuang paborito + Sinisimulan ang pag-playback... + Gumagana + Walang natagpuang link + Walang natagpuang puwedeng i-play na nilalaman + Hindi ma-load ang mga detalye + Error sa pag-load ng mga link + Pagkasyahin sa Screen + Punuin ang Screen + Walang napiling pinagmulan + Walang magagamit na pinagmulan + Napiling pinagmulan + Maghanap + Walang natagpuang resulta + Hindi natagpuan ang \'Ituloy ang Panonood\' + Walang natagpuang download + Hindi natagpuan ang file + Walang wastong episodyo na natagpuan + Piliin ang Tagapagbigay + Napili + Aklatan + Mga Bookmark + Ipinagpapatuloy ang %1$s... + diff --git a/app/src/main/res-car/values-b+tr/strings_car.xml b/app/src/main/res-car/values-b+tr/strings_car.xml new file mode 100644 index 00000000000..17b162f542f --- /dev/null +++ b/app/src/main/res-car/values-b+tr/strings_car.xml @@ -0,0 +1,51 @@ + + + Yükleniyor... + Hata + İçerik yüklenirken hata + Favoriler + Geçmiş + İndirilenler + Sağlayıcı + Mevcut + Menü + Ana Sayfa İçeriği + Sağlayıcıdan içerik yok + Sağlayıcı bulunamadı + Kaynak + Kaynaklar + Konu + Oyuncular + Detaylar yüklenirken hata + Bölüm Listesi + Sezon + Sezonlar + Bölüm + Bölüm bulunamadı + TV dizisi değil + Favorilere eklendi + Favorilerden çıkarıldı + Favori bulunamadı + Oynatma başlatılıyor... + Oynatılıyor + Bağlantı bulunamadı + Oynatılabilir içerik bulunamadı + Detaylar yüklenemedi + Bağlantılar yüklenirken hata + Ekrana Sığdır + Ekranı Doldur + Kaynak bulunamadı + Mevcut kaynak yok + Kaynak seçildi + Ara + Sonuç bulunamadı + \'İzlemeye Devam Et\' bulunamadı + İndirme bulunamadı + Dosya bulunamadı + Geçerli bölüm bulunamadı + Sağlayıcı Seç + Seçildi + Kütüphane + Yer İmleri + %1$s devam ettiriliyor... + diff --git a/app/src/main/res-car/values-b+uk/strings_car.xml b/app/src/main/res-car/values-b+uk/strings_car.xml new file mode 100644 index 00000000000..5cd25097ff6 --- /dev/null +++ b/app/src/main/res-car/values-b+uk/strings_car.xml @@ -0,0 +1,51 @@ + + + Завантаження... + Помилка + Помилка завантаження вмісту + Обране + Історія + Завантаження + Провайдер + Поточний + Меню + Домашній вміст + Немає вмісту від провайдера + Провайдера не знайдено + Джерело + Джерела + Сюжет + Актори + Помилка завантаження деталей + Список епізодів + Сезон + Сезони + Епізод + Епізодів не знайдено + Не серіал + Додано до обраного + Видалено з обраного + Немає обраного + Початок відтворення... + Відтворення + Посилання не знайдено + Вміст для відтворення не знайдено + Не вдалося завантажити деталі + Помилка завантаження посилань + Припасувати до екрану + Заповнити екран + Джерело не знайдено + Джерела недоступні + Джерело вибрано + Пошук + Результатів не знайдено + \'Продовжити перегляд\' не знайдено + Завантажень не знайдено + Файл не знайдено + Дійсний епізод не знайдено + Вибрати провайдера + Вибрано + Бібліотека + Закладки + Відновлення %1$s... + diff --git a/app/src/main/res-car/values-b+ur/strings_car.xml b/app/src/main/res-car/values-b+ur/strings_car.xml new file mode 100644 index 00000000000..43b74a6a62e --- /dev/null +++ b/app/src/main/res-car/values-b+ur/strings_car.xml @@ -0,0 +1,51 @@ + + + لوڈ ہو رہا ہے... + خرابی + مواد لوڈ کرنے میں خرابی + پسندیدہ + تاریخچہ + ڈاؤن لوڈز + فراہم کنندہ + موجودہ + مینو + ہوم مواد + فراہم کنندہ سے کوئی مواد نہیں + فراہم کنندہ نہیں ملا + ماخذ + ماخذات + پلاٹ + کاسٹ + تفصیلات لوڈ کرنے میں خرابی + اقساط کی فہرست + سیزن + سیزنز + قسط + کوئی قسط نہیں ملی + ٹی وی سیریز نہیں + پسندیدہ میں شامل کر دیا گیا + پسندیدہ سے ہٹا دیا گیا + کوئی پسندیدہ نہیں ملا + پلے بیک شروع ہو رہا ہے... + پلے ہو رہا ہے + کوئی لنک نہیں ملا + کوئی قابل پلے مواد نہیں ملا + تفصیلات لوڈ نہیں ہو سکیں + لنکس لوڈ کرنے میں خرابی + اسکرین پر فٹ کریں + اسکرین بھریں + کوئی ماخذ نہیں ملا + کوئی ماخذ دستیاب نہیں + ماخذ منتخب ہو گیا + تلاش + کوئی نتیجہ نہیں ملا + \'دیکھنا جاری رکھیں\' نہیں ملا + کوئی ڈاؤن لوڈ نہیں ملا + فائل نہیں ملی + کوئی درست قسط نہیں ملی + فراہم کنندہ منتخب کریں + منتخب شدہ + لائبریری + بک مارکس + %1$s دوبارہ شروع ہو رہا ہے... + diff --git a/app/src/main/res-car/values-b+uz/strings_car.xml b/app/src/main/res-car/values-b+uz/strings_car.xml new file mode 100644 index 00000000000..30f36208f3f --- /dev/null +++ b/app/src/main/res-car/values-b+uz/strings_car.xml @@ -0,0 +1,51 @@ + + + Yuklanmoqda... + Xato + Kontentni yuklashda xato + Sevimlilar + Tarix + Yuklanmalar + Provayder + Joriy + Menyu + Bosh sahifa kontenti + Provayderdan kontent yo\'q + Provayder topilmadi + Manba + Manbalar + Syujet + Rollarda + Tafsilotlarni yuklashda xato + Qismlar ro\'yxati + Mavsum + Mavsumlar + Qism + Qismlar topilmadi + TV serial emas + Sevimlilarga qo\'shildi + Sevimlilardan olib tashlandi + Sevimlilar topilmadi + Ijro boshlanmoqda... + Ijro etilmoqda + Havola topilmadi + Ijro etib bo\'ladigan kontent topilmadi + Tafsilotlarni yuklab bo\'lmadi + Havolalarni yuklashda xato + Ekranga moslash + Ekranni to\'ldirish + Manba topilmadi + Mavjud manba yo\'q + Manba tanlandi + Qidirish + Natijalar topilmadi + \'Ko\'rishni davom ettirish\' topilmadi + Yuklanmalar topilmadi + Fayl topilmadi + Yaroqli qism topilmadi + Provayderni tanlash + Tanlandi + Kutubxona + Xatcho\'plar + %1$s davom ettirilmoqda... + diff --git a/app/src/main/res-car/values-b+vi/strings_car.xml b/app/src/main/res-car/values-b+vi/strings_car.xml new file mode 100644 index 00000000000..68c2393b14b --- /dev/null +++ b/app/src/main/res-car/values-b+vi/strings_car.xml @@ -0,0 +1,51 @@ + + + Đang tải... + Lỗi + Lỗi tải nội dung + Yêu thích + Lịch sử + Tải xuống + Nguồn phát + Hiện tại + Menu + Nội dung trang chủ + Không có nội dung từ nguồn + Không tìm thấy nguồn + Nguồn + Nguồn + Cốt truyện + Diễn viên + Lỗi tải chi tiết + Danh sách tập + Mùa + Mùa + Tập + Không tìm thấy tập nào + Không phải phim bộ + Đã thêm vào yêu thích + Đã xóa khỏi yêu thích + Không có yêu thích + Đang bắt đầu phát... + Đang phát + Không tìm thấy liên kết + Không có nội dung phát được + Không thể tải chi tiết + Lỗi tải liên kết + Vừa màn hình + Lấp đầy màn hình + Không tìm thấy nguồn + Không có nguồn khả dụng + Đã chọn nguồn + Tìm kiếm + Không tìm thấy kết quả + Không tìm thấy \'Tiếp tục xem\' + Không tìm thấy bản tải xuống + Không tìm thấy tệp + Không có tập hợp lệ + Chọn nguồn + Đã chọn + Thư viện + Dấu trang + Đang tiếp tục %1$s... + diff --git a/app/src/main/res-car/values-b+zh+TW/strings_car.xml b/app/src/main/res-car/values-b+zh+TW/strings_car.xml new file mode 100644 index 00000000000..ac0a25531bb --- /dev/null +++ b/app/src/main/res-car/values-b+zh+TW/strings_car.xml @@ -0,0 +1,74 @@ + + + + Loading... + Error + Error loading content + + + Favorites + History + Downloads + Provider + Current + Menu + Home Content + No content from provider + Provider not found + + + Source + Sources + Plot + Cast + Error loading details + + + Episode List + Season + Seasons + Episode + No episodes found + Not a TV series + + + Added to favorites + Removed from favorites + No favorites found + + + Starting playback... + Playing + No link found + No playable content found + Unable to load details + Error loading links + Fit to screen + Fill screen + + + No source found + No source available + Source selected + + + Search + No results found + + + No \'Continue watching\' items found + + + No completed downloads found + File not found + No valid episode found + + + Select Provider + Selected + + + Library + Bookmarks + Resuming %1$s... + diff --git a/app/src/main/res-car/values-b+zh/strings_car.xml b/app/src/main/res-car/values-b+zh/strings_car.xml new file mode 100644 index 00000000000..8f950f7828b --- /dev/null +++ b/app/src/main/res-car/values-b+zh/strings_car.xml @@ -0,0 +1,51 @@ + + + 加载中... + 错误 + 加载内容错误 + 收藏 + 历史 + 下载 + 提供商 + 当前 + 菜单 + 首页内容 + 无提供商内容 + 未找到提供商 + 来源 + 来源 + 剧情 + 演员 + 加载详情错误 + 剧集列表 + + + + 未找到剧集 + 非电视剧 + 已添加到收藏 + 已从收藏移除 + 无收藏 + 开始播放... + 播放中 + 无链接 + 无由播放内容 + 无法加载详情 + 加载链接错误 + 适应屏幕 + 充满屏幕 + 未找到来源 + 无可用来源 + 已选来源 + 搜索 + 无结果 + 无继续观看 + 无下载 + 文件未找到 + 无有效剧集 + 选择提供商 + 已选 + + 书签 + 恢复播放 %1$s... + diff --git a/app/src/main/res-car/values-b+zu/strings_car.xml b/app/src/main/res-car/values-b+zu/strings_car.xml new file mode 100644 index 00000000000..28edfa24bb2 --- /dev/null +++ b/app/src/main/res-car/values-b+zu/strings_car.xml @@ -0,0 +1,51 @@ + + + Iyalayisha... + Iphutha + Iphutha ekulayisheni okuqukethwe + Izintandokazi + Umlando + Okulandiwe + Umhlinzeki + Okwamanje + Imenyu + Okuqukethwe Kwasekhaya + Akukho okuqukethwe okuvela kumhlinzeki + Umhlinzeki akatholakalanga + Umthombo + Imithombo + Icebo + Abalingisi + Iphutha ekulayisheni imininingwane + Uhlu Lweziqephu + Isizini + Izinkathi + Isiqephu + Azikho iziqephu ezitholiwe + Akulona uchungechunge lwe-TV + Kungezwe kuzintandokazi + Kususiwe kuzintandokazi + Azikho izintandokazi ezitholiwe + Iqala ukudlala... + Iyadlala + Asikho isixhumanisi esitholiwe + Akukho okuqukethwe okudlalekayo okutholiwe + Ayikwazi ukulayisha imininingwane + Iphutha ekulayisheni izixhumanisi + Lingana nesikrini + Gcwalisa Isikrini + Awukho umthombo otholiwe + Awukho umthombo otholakalayo + Umthombo ukhethiwe + Sesha + Ayikho imiphumela etholiwe + \'Qhubeka nokubuka\' ayitholakali + Akukho okulandiwe okutholiwe + Ifayela alitholakalanga + Asikho isiqephu esivumelekile esitholiwe + Khetha Umhlinzeki + Kukhethiwe + Umtapo wolwazi + Amabhukhimakhi + Iyaqhubeka %1$s... + diff --git a/app/src/main/res-car/values-it/strings_car.xml b/app/src/main/res-car/values-it/strings_car.xml new file mode 100644 index 00000000000..081a7ed36b4 --- /dev/null +++ b/app/src/main/res-car/values-it/strings_car.xml @@ -0,0 +1,74 @@ + + + + Caricamento... + Errore + Errore caricamento contenuti + + + Preferiti + Cronologia + Download + Provider + Attuale + Menu + Contenuti Home + Nessun contenuto dal provider + Provider non trovato + + + Sorgente + Sorgenti + Trama + Cast + Errore caricamento dettagli + + + Lista Episodi + Stagione + Stagioni + Episodio + Nessun episodio trovato + Non è una serie TV + + + Aggiunto ai preferiti + Rimosso dai preferiti + Nessun preferito trovato + + + Avvio riproduzione... + In riproduzione + Nessun link trovato + Nessun contenuto riproducibile trovato + Impossibile caricare i dettagli + Errore caricamento link + Adatta allo schermo + Riempi schermo + + + Nessuna sorgente trovata + Nessuna sorgente disponibile + Sorgente selezionata + + + Cerca + Nessun risultato trovato + + + Nessun elemento \'Continua a guardare\' trovato + + + Nessun download completato trovato + File non trovato + Nessun episodio valido trovato + + + Seleziona Provider + Selezionato + + + Libreria + Segnalibri + Riprendo %1$s... + diff --git a/app/src/main/res-car/values/strings_car.xml b/app/src/main/res-car/values/strings_car.xml new file mode 100644 index 00000000000..ac0a25531bb --- /dev/null +++ b/app/src/main/res-car/values/strings_car.xml @@ -0,0 +1,74 @@ + + + + Loading... + Error + Error loading content + + + Favorites + History + Downloads + Provider + Current + Menu + Home Content + No content from provider + Provider not found + + + Source + Sources + Plot + Cast + Error loading details + + + Episode List + Season + Seasons + Episode + No episodes found + Not a TV series + + + Added to favorites + Removed from favorites + No favorites found + + + Starting playback... + Playing + No link found + No playable content found + Unable to load details + Error loading links + Fit to screen + Fill screen + + + No source found + No source available + Source selected + + + Search + No results found + + + No \'Continue watching\' items found + + + No completed downloads found + File not found + No valid episode found + + + Select Provider + Selected + + + Library + Bookmarks + Resuming %1$s... + diff --git a/app/src/main/res/values-b+es/array.xml b/app/src/main/res/values-es/array.xml similarity index 100% rename from app/src/main/res/values-b+es/array.xml rename to app/src/main/res/values-es/array.xml diff --git a/app/src/main/res/values-b+es/strings.xml b/app/src/main/res/values-es/strings.xml similarity index 100% rename from app/src/main/res/values-b+es/strings.xml rename to app/src/main/res/values-es/strings.xml diff --git a/app/src/main/res/values-b+it/strings.xml b/app/src/main/res/values-it/strings.xml similarity index 100% rename from app/src/main/res/values-b+it/strings.xml rename to app/src/main/res/values-it/strings.xml From 95e8f12aab7e2482c6cc2f5be22da5db68c031ae Mon Sep 17 00:00:00 2001 From: Michele Granato Date: Fri, 16 Jan 2026 19:13:52 +0100 Subject: [PATCH 11/20] Hello, World :) --- app/build.gradle.kts | 2 +- .../cloudstream3/ui/car/AboutMeScreen.kt | 98 ++++++++++++++++++ .../cloudstream3/ui/car/MainCarScreen.kt | 9 ++ .../main/res-car/values-it/strings_car.xml | 1 + app/src/main/res-car/values/strings_car.xml | 1 + app/src/main/res/raw/aboutme.mp4 | Bin 0 -> 954084 bytes 6 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/car/AboutMeScreen.kt create mode 100644 app/src/main/res/raw/aboutme.mp4 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 07b24928368..e1688171dd2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -63,7 +63,7 @@ android { minSdk = libs.versions.minSdk.get().toInt() targetSdk = libs.versions.targetSdk.get().toInt() versionCode = 67 - versionName = "4.6.12" + versionName = "4.6.13" resValue("string", "commit_hash", getGitCommitHash()) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/AboutMeScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/AboutMeScreen.kt new file mode 100644 index 00000000000..7e4c98a2780 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/AboutMeScreen.kt @@ -0,0 +1,98 @@ +package com.lagradost.cloudstream3.ui.car + +import android.net.Uri +import androidx.car.app.AppManager +import androidx.car.app.CarContext +import androidx.car.app.Screen +import androidx.car.app.SurfaceCallback +import androidx.car.app.SurfaceContainer +import androidx.car.app.model.Action +import androidx.car.app.model.ActionStrip +import androidx.car.app.model.CarIcon +import androidx.car.app.model.Template +import androidx.car.app.navigation.model.NavigationTemplate +import androidx.core.graphics.drawable.IconCompat +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import androidx.media3.common.MediaItem +import androidx.media3.common.Player +import androidx.media3.exoplayer.ExoPlayer +import com.lagradost.cloudstream3.R + +class AboutMeScreen(carContext: CarContext) : Screen(carContext), DefaultLifecycleObserver, SurfaceCallback { + + private var player: ExoPlayer? = null + + init { + lifecycle.addObserver(this) + } + + override fun onCreate(owner: LifecycleOwner) { + super.onCreate(owner) + try { + player = ExoPlayer.Builder(carContext).build().apply { + val audioAttributes = androidx.media3.common.AudioAttributes.Builder() + .setUsage(androidx.media3.common.C.USAGE_MEDIA) + .setContentType(androidx.media3.common.C.AUDIO_CONTENT_TYPE_MOVIE) + .build() + setAudioAttributes(audioAttributes, true) + + repeatMode = Player.REPEAT_MODE_ONE + volume = 1.0f + // android.resource://package/id + val uri = Uri.parse("android.resource://${carContext.packageName}/${R.raw.aboutme}") + setMediaItem(MediaItem.fromUri(uri)) + prepare() + playWhenReady = true + } + } catch (e: Exception) { + e.printStackTrace() + } + } + + override fun onDestroy(owner: LifecycleOwner) { + player?.release() + player = null + super.onDestroy(owner) + } + + override fun onStart(owner: LifecycleOwner) { + super.onStart(owner) + carContext.getCarService(AppManager::class.java).setSurfaceCallback(this) + player?.play() + } + + override fun onStop(owner: LifecycleOwner) { + player?.pause() + carContext.getCarService(AppManager::class.java).setSurfaceCallback(null) + super.onStop(owner) + } + + override fun onSurfaceAvailable(surfaceContainer: SurfaceContainer) { + val surface = surfaceContainer.surface + if (surface != null) { + player?.setVideoSurface(surface) + } + } + + + + override fun onSurfaceDestroyed(surfaceContainer: SurfaceContainer) { + player?.clearVideoSurface() + } + + override fun onGetTemplate(): Template { + val backAction = Action.Builder() + .setIcon(CarIcon.Builder(IconCompat.createWithResource(carContext, androidx.appcompat.R.drawable.abc_ic_ab_back_material)).build()) + .setOnClickListener { screenManager.pop() } + .build() + + return NavigationTemplate.Builder() + .setActionStrip( + ActionStrip.Builder() + .addAction(backAction) + .build() + ) + .build() + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt index cd736e65a4b..66940783bc2 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/car/MainCarScreen.kt @@ -123,6 +123,15 @@ class MainCarScreen(carContext: CarContext) : Screen(carContext), DefaultLifecyc .build() ) + menuListBuilder.addItem( + Row.Builder() + .setTitle(CarStrings.get(R.string.car_about_me)) + .setImage(CarIcon.Builder(IconCompat.createWithResource(carContext, android.R.drawable.ic_menu_info_details)).build()) + .setOnClickListener { screenManager.push(AboutMeScreen(carContext)) } + .setBrowsable(true) + .build() + ) + // 2. Content Section Builder diff --git a/app/src/main/res-car/values-it/strings_car.xml b/app/src/main/res-car/values-it/strings_car.xml index 081a7ed36b4..cb20b104b35 100644 --- a/app/src/main/res-car/values-it/strings_car.xml +++ b/app/src/main/res-car/values-it/strings_car.xml @@ -15,6 +15,7 @@ Contenuti Home Nessun contenuto dal provider Provider non trovato + Info su di me Sorgente diff --git a/app/src/main/res-car/values/strings_car.xml b/app/src/main/res-car/values/strings_car.xml index ac0a25531bb..607af3ff28a 100644 --- a/app/src/main/res-car/values/strings_car.xml +++ b/app/src/main/res-car/values/strings_car.xml @@ -15,6 +15,7 @@ Home Content No content from provider Provider not found + About me Source diff --git a/app/src/main/res/raw/aboutme.mp4 b/app/src/main/res/raw/aboutme.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..cfb4479ea70ec6c23b428d45ef6b79ed021255c6 GIT binary patch literal 954084 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%0DHK*8lzzqUXeu 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