diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8f5d7d3c2..b5efba744 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -272,9 +272,15 @@ + + \ No newline at end of file diff --git a/app/src/main/java/com/github/libretube/MainActivity.kt b/app/src/main/java/com/github/libretube/MainActivity.kt index 357250e75..5c694a275 100644 --- a/app/src/main/java/com/github/libretube/MainActivity.kt +++ b/app/src/main/java/com/github/libretube/MainActivity.kt @@ -34,6 +34,7 @@ import androidx.navigation.findNavController import androidx.navigation.ui.setupWithNavController import com.github.libretube.fragments.PlayerFragment import com.github.libretube.fragments.isFullScreen +import com.github.libretube.services.ClosingService import com.github.libretube.util.CronetHelper import com.github.libretube.util.LocaleHelper import com.github.libretube.util.PreferenceHelper @@ -52,6 +53,10 @@ class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { DynamicColors.applyToActivityIfAvailable(this) super.onCreate(savedInstanceState) + + // start service that gets called on closure + startService(Intent(this, ClosingService::class.java)) + CronetHelper.initCronet(this.applicationContext) RetrofitInstance.url = diff --git a/app/src/main/java/com/github/libretube/adapters/PlaylistAdapter.kt b/app/src/main/java/com/github/libretube/adapters/PlaylistAdapter.kt index 448060c49..05f26b331 100644 --- a/app/src/main/java/com/github/libretube/adapters/PlaylistAdapter.kt +++ b/app/src/main/java/com/github/libretube/adapters/PlaylistAdapter.kt @@ -60,6 +60,7 @@ class PlaylistAdapter( holder.v.setOnClickListener { var bundle = Bundle() bundle.putString("videoId", streamItem.url!!.replace("/watch?v=", "")) + bundle.putString("playlistId", playlistId) var frag = PlayerFragment() frag.arguments = bundle val activity = holder.v.context as AppCompatActivity diff --git a/app/src/main/java/com/github/libretube/dialogs/DownloadDialog.kt b/app/src/main/java/com/github/libretube/dialogs/DownloadDialog.kt index 9fae8cd8b..cc467c313 100644 --- a/app/src/main/java/com/github/libretube/dialogs/DownloadDialog.kt +++ b/app/src/main/java/com/github/libretube/dialogs/DownloadDialog.kt @@ -17,10 +17,10 @@ import android.widget.TextView import androidx.core.app.ActivityCompat import androidx.core.text.HtmlCompat import androidx.fragment.app.DialogFragment -import com.github.libretube.DownloadService import com.github.libretube.MainActivity import com.github.libretube.R import com.github.libretube.obj.Streams +import com.github.libretube.services.DownloadService import com.google.android.material.dialog.MaterialAlertDialogBuilder class DownloadDialog : DialogFragment() { diff --git a/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt index 54fe27fd7..05d306338 100644 --- a/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt @@ -38,7 +38,6 @@ import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.github.libretube.IS_DOWNLOAD_RUNNING import com.github.libretube.MainActivity import com.github.libretube.R import com.github.libretube.adapters.ChaptersAdapter @@ -50,12 +49,14 @@ import com.github.libretube.dialogs.ShareDialog import com.github.libretube.hideKeyboard import com.github.libretube.obj.ChapterSegment import com.github.libretube.obj.PipedStream +import com.github.libretube.obj.Playlist import com.github.libretube.obj.Segment import com.github.libretube.obj.Segments import com.github.libretube.obj.SponsorBlockPrefs import com.github.libretube.obj.StreamItem import com.github.libretube.obj.Streams import com.github.libretube.obj.Subscribe +import com.github.libretube.services.IS_DOWNLOAD_RUNNING import com.github.libretube.util.CronetHelper import com.github.libretube.util.DescriptionAdapter import com.github.libretube.util.PreferenceHelper @@ -86,6 +87,9 @@ import com.google.android.material.button.MaterialButton import com.google.android.material.card.MaterialCardView import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.squareup.picasso.Picasso +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.chromium.net.CronetEngine import retrofit2.HttpException import java.io.IOException @@ -99,6 +103,7 @@ class PlayerFragment : Fragment() { private val TAG = "PlayerFragment" private var videoId: String? = null + private var playlistId: String? = null private var sId: Int = 0 private var eId: Int = 0 private var paused = false @@ -119,8 +124,13 @@ class PlayerFragment : Fragment() { private lateinit var motionLayout: MotionLayout private lateinit var exoPlayer: ExoPlayer private lateinit var segmentData: Segments - private var relatedStreams: List? = arrayListOf() private var relatedStreamsEnabled = true + + private var relatedStreams: List? = arrayListOf() + private var nextStreamId: String? = null + private var playlistStreamIds: MutableList = arrayListOf() + private var playlistNextPage: String? = null + private var isPlayerLocked: Boolean = false private lateinit var relDownloadVideo: LinearLayout @@ -138,6 +148,7 @@ class PlayerFragment : Fragment() { super.onCreate(savedInstanceState) arguments?.let { videoId = it.getString("videoId") + playlistId = it.getString("playlistId") } } @@ -155,8 +166,9 @@ class PlayerFragment : Fragment() { hideKeyboard() setSponsorBlockPrefs() + createExoPlayer(view) initializeTransitionLayout(view) - fetchJsonAndInitPlayer(view) + playVideo(view) } private fun initializeTransitionLayout(view: View) { @@ -252,14 +264,12 @@ class PlayerFragment : Fragment() { } } + // video description and chapters toggle + val descLinLayout = view.findViewById(R.id.desc_linLayout) view.findViewById(R.id.player_title_layout).setOnClickListener { val arrowImageView = view.findViewById(R.id.player_description_arrow) - arrowImageView.animate().rotationBy(180F).setDuration(100).start() - if (playerDescription.isVisible) { - playerDescription.visibility = View.GONE - } else { - playerDescription.visibility = View.VISIBLE - } + arrowImageView.animate().rotationBy(180F).setDuration(250).start() + descLinLayout.visibility = if (descLinLayout.isVisible) View.GONE else View.VISIBLE } view.findViewById(R.id.comments_toggle) @@ -375,7 +385,12 @@ class PlayerFragment : Fragment() { val isScreenOn = pm.isInteractive // pause player if screen off and setting enabled - if (exoPlayer != null && !isScreenOn && pausePlayerOnScreenOffEnabled) { + if ( + this::exoPlayer.isInitialized && + exoPlayer != null && + !isScreenOn && + pausePlayerOnScreenOffEnabled + ) { exoPlayer.pause() } super.onPause() @@ -419,7 +434,7 @@ class PlayerFragment : Fragment() { } } - private fun fetchJsonAndInitPlayer(view: View) { + private fun playVideo(view: View) { fun run() { lifecycleScope.launchWhenCreated { val response = try { @@ -439,19 +454,19 @@ class PlayerFragment : Fragment() { uploader = response.uploader!! thumbnailUrl = response.thumbnailUrl!! - // check whether related streams and autoplay are enabled + // save whether related streams and autoplay are enabled autoplay = PreferenceHelper.getBoolean(requireContext(), "autoplay", false) relatedStreamsEnabled = PreferenceHelper.getBoolean(requireContext(), "related_streams_toggle", true) // save related streams for autoplay relatedStreams = response.relatedStreams + runOnUiThread { - createExoPlayer(view) - prepareExoPlayerView() if (response.chapters != null) initializeChapters(response.chapters) // set media sources for the player setResolutionAndSubtitles(view, response) exoPlayer.prepare() + prepareExoPlayerView() initializePlayerView(view, response) // support for time stamped links if (arguments?.getLong("timeStamp") != null) { @@ -464,12 +479,78 @@ class PlayerFragment : Fragment() { fetchSponsorBlockSegments() // show comments if related streams disabled if (!relatedStreamsEnabled) toggleComments() + // prepare for autoplay + initAutoPlay() } } } run() } + // the function is working recursively + private fun initAutoPlay() { + // save related streams for autoplay + if (autoplay) { + // if it's a playlist use the next video + if (playlistId != null) { + lateinit var playlist: Playlist // var for saving the list in + // runs only the first time when starting a video from a playlist + if (playlistStreamIds.isEmpty()) { + CoroutineScope(Dispatchers.IO).launch { + // fetch the playlists videos + playlist = RetrofitInstance.api.getPlaylist(playlistId!!) + // save the playlist urls in the array + playlist.relatedStreams?.forEach { video -> + playlistStreamIds += video.url?.replace("/watch?v=", "")!! + } + // save playlistNextPage for usage if video is not contained + playlistNextPage = playlist.nextpage + // restart the function after videos are loaded + initAutoPlay() + } + } + // if the playlists contain the video, then save the next video as next stream + else if (playlistStreamIds.contains(videoId)) { + val index = playlistStreamIds.indexOf(videoId) + // check whether there's a next video + if (index + 1 <= playlistStreamIds.size) { + nextStreamId = playlistStreamIds[index + 1] + } + // fetch the next page of the playlist if the video isn't contained + } else if (playlistNextPage != null) { + CoroutineScope(Dispatchers.IO).launch { + RetrofitInstance.api.getPlaylistNextPage(playlistId!!, playlistNextPage!!) + // append all the playlist item urls to the array + playlist.relatedStreams?.forEach { video -> + playlistStreamIds += video.url?.replace("/watch?v=", "")!! + } + // save playlistNextPage for usage if video is not contained + playlistNextPage = playlist.nextpage + // restart the function after videos are loaded + initAutoPlay() + } + } + // else: the video must be the last video of the playlist so nothing happens + + // if it's not a playlist then use the next related video + } else if (relatedStreams != null && relatedStreams!!.isNotEmpty()) { + // save next video from related streams for autoplay + nextStreamId = relatedStreams!![0].url!!.replace("/watch?v=", "")!! + } + } + } + + // used for autoplay and skipping to next video + private fun playNextVideo() { + // check whether there is a new video in the queue + // by making sure that the next and the current video aren't the same + if (videoId != nextStreamId) { + // save the id of the next stream as videoId and load the next video + videoId = nextStreamId + playVideo(view!!) + } + } + private fun setSponsorBlockPrefs() { sponsorBlockPrefs.sponsorBlockEnabled = PreferenceHelper.getBoolean(requireContext(), "sb_enabled_key", true) @@ -495,7 +576,7 @@ class PlayerFragment : Fragment() { private fun fetchSponsorBlockSegments() { fun run() { - lifecycleScope.launchWhenCreated { + lifecycleScope.launch(Dispatchers.IO) { if (sponsorBlockPrefs.sponsorBlockEnabled) { val categories: ArrayList = arrayListOf() if (sponsorBlockPrefs.introEnabled) { @@ -531,14 +612,10 @@ class PlayerFragment : Fragment() { } catch (e: IOException) { println(e) Log.e(TAG, "IOException, you might not have internet connection") - Toast.makeText(context, R.string.unknown_error, Toast.LENGTH_SHORT) - .show() - return@launchWhenCreated + return@launch } catch (e: HttpException) { Log.e(TAG, "HttpException, unexpected response") - Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT) - .show() - return@launchWhenCreated + return@launch } } } @@ -601,14 +678,13 @@ class PlayerFragment : Fragment() { // check if video has ended, next video is available and autoplay is enabled. if ( playbackState == Player.STATE_ENDED && - relatedStreams != null && - relatedStreams!!.isNotEmpty() && + nextStreamId != null && !transitioning && autoplay ) { transitioning = true - videoId = relatedStreams!![0].url!!.replace("/watch?v=", "") - fetchJsonAndInitPlayer(view) + // check whether autoplay is enabled + if (autoplay) playNextVideo() } if (playWhenReady && playbackState == Player.STATE_READY) { @@ -657,29 +733,28 @@ class PlayerFragment : Fragment() { if (response.hls != null) { view.findViewById(R.id.relPlayer_vlc).setOnClickListener { - exoPlayer.pause() - try { - val vlcRequestCode = 42 - val uri: Uri = Uri.parse(response.hls) - val vlcIntent = Intent(Intent.ACTION_VIEW) - vlcIntent.setPackage("org.videolan.vlc") - vlcIntent.setDataAndTypeAndNormalize(uri, "video/*") - vlcIntent.putExtra("title", response.title) - vlcIntent.putExtra("from_start", false) - vlcIntent.putExtra("position", exoPlayer.currentPosition) - startActivityForResult(vlcIntent, vlcRequestCode) - } catch (e: Exception) { - Toast.makeText(context, R.string.vlcerror, Toast.LENGTH_SHORT) - .show() - } + // start an intent with video as mimetype using the hls stream + val uri: Uri = Uri.parse(response.hls) + val intent = Intent() + + intent.action = Intent.ACTION_VIEW + intent.setDataAndType(uri, "video/*") + intent.putExtra(Intent.EXTRA_TITLE, title) + intent.putExtra("title", title) + intent.putExtra("artist", uploader) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + + startActivity(intent) } } if (relatedStreamsEnabled) { + // only show related streams if enabled relatedRecView.adapter = TrendingAdapter( response.relatedStreams!!, childFragmentManager ) } + // set video description val description = response.description!! view.findViewById(R.id.player_description).text = // detect whether the description is html formatted @@ -717,28 +792,13 @@ class PlayerFragment : Fragment() { } private fun initializeChapters(chapters: List) { - val chaptersToggle = view?.findViewById(R.id.chapters_toggle) val chaptersRecView = view?.findViewById(R.id.chapters_recView) - val chaptersToggleText = view?.findViewById(R.id.chapters_toggle_text) - val chaptersToggleArrow = view?.findViewById(R.id.chapters_toggle_arrow) if (chapters.isNotEmpty()) { - chaptersToggle?.visibility = View.VISIBLE - - chaptersToggle?.setOnClickListener { - if (chaptersRecView?.isVisible!!) { - chaptersRecView?.visibility = View.GONE - chaptersToggleText?.text = getString(R.string.show_chapters) - } else { - chaptersRecView?.visibility = View.VISIBLE - chaptersToggleText?.text = getString(R.string.hide_chapters) - } - chaptersToggleArrow!!.animate().setDuration(100).rotationBy(180F).start() - } - chaptersRecView?.layoutManager = LinearLayoutManager(this.context, LinearLayoutManager.HORIZONTAL, false) chaptersRecView?.adapter = ChaptersAdapter(chapters, exoPlayer) + chaptersRecView?.visibility = View.VISIBLE } } @@ -1121,7 +1181,7 @@ class PlayerFragment : Fragment() { enableTransition(R.id.yt_transition, false) } view?.findViewById(R.id.main_container)?.isClickable = true - view?.findViewById(R.id.top_bar)?.visibility = View.GONE + view?.findViewById(R.id.top_bar)?.visibility = View.GONE val mainActivity = activity as MainActivity mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT isFullScreen = false @@ -1133,7 +1193,7 @@ class PlayerFragment : Fragment() { exoPlayerView.showController() exoPlayerView.useController = true view?.findViewById(R.id.main_container)?.isClickable = false - view?.findViewById(R.id.top_bar)?.visibility = View.VISIBLE + view?.findViewById(R.id.top_bar)?.visibility = View.VISIBLE } } diff --git a/app/src/main/java/com/github/libretube/services/ClosingService.kt b/app/src/main/java/com/github/libretube/services/ClosingService.kt new file mode 100644 index 000000000..716e6dff9 --- /dev/null +++ b/app/src/main/java/com/github/libretube/services/ClosingService.kt @@ -0,0 +1,31 @@ +package com.github.libretube.services + +import android.app.NotificationManager +import android.app.Service +import android.content.Context +import android.content.Intent +import android.os.IBinder +import android.util.Log +import androidx.annotation.Nullable + +class ClosingService : Service() { + private val TAG = "ClosingService" + + @Nullable + override fun onBind(intent: Intent?): IBinder? { + return null + } + + // Handle application closing + override fun onTaskRemoved(rootIntent: Intent?) { + super.onTaskRemoved(rootIntent) + + // destroy all notifications (especially the player notification) + val nManager = this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + nManager.cancelAll() + Log.e(TAG, "closed") + + // Destroy the service + stopSelf() + } +} diff --git a/app/src/main/java/com/github/libretube/DownloadService.kt b/app/src/main/java/com/github/libretube/services/DownloadService.kt similarity index 99% rename from app/src/main/java/com/github/libretube/DownloadService.kt rename to app/src/main/java/com/github/libretube/services/DownloadService.kt index eb7b309aa..8f3c96e71 100644 --- a/app/src/main/java/com/github/libretube/DownloadService.kt +++ b/app/src/main/java/com/github/libretube/services/DownloadService.kt @@ -1,4 +1,4 @@ -package com.github.libretube +package com.github.libretube.services import android.app.DownloadManager import android.app.PendingIntent @@ -18,6 +18,7 @@ import android.util.Log import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import com.arthenica.ffmpegkit.FFmpegKit +import com.github.libretube.R import com.github.libretube.util.PreferenceHelper import java.io.File diff --git a/app/src/main/java/com/github/libretube/util/ThemeHelper.kt b/app/src/main/java/com/github/libretube/util/ThemeHelper.kt index ca9498685..3fb5cd385 100644 --- a/app/src/main/java/com/github/libretube/util/ThemeHelper.kt +++ b/app/src/main/java/com/github/libretube/util/ThemeHelper.kt @@ -17,7 +17,7 @@ object ThemeHelper { } private fun updateAccentColor(context: Context) { - when (PreferenceHelper.getString(context, "accent_color", "red")) { + when (PreferenceHelper.getString(context, "accent_color", "purple")) { "my" -> context.setTheme(R.style.Theme_MY) "red" -> context.setTheme(R.style.Theme_Red) "blue" -> context.setTheme(R.style.Theme_Blue) diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 73ca5679f..904b19f13 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -10,8 +10,8 @@ - + android:layout_width="match_parent" + android:layout_height="55dp" + android:src="@mipmap/ic_launcher" + app:shapeAppearanceOverlay="@style/roundedImageViewRounded" /> - + + - - - - - - - - - - - - - - - - - - - - + android:layout_marginLeft="3dp" + android:layout_marginTop="2dp"> + android:layout_width="12dp" + android:layout_height="12dp" + android:layout_gravity="center" + android:src="@drawable/ic_like" /> + + + + + + - + - + android:orientation="vertical" + android:visibility="gone"> - + + + + + style="@style/PlayerActionsLayout"> + style="@style/PlayerActionsLayout"> + style="@style/PlayerActionsLayout"> + style="@style/PlayerActionsLayout"> - اختر نظير - نظير مخصص + اختر نموذج + نموذج مخصص الجودة تم إنشاء حساب بنجاح! تستطيع الآن أن تشترك بالقنوات التي تريدها. بحث @@ -24,7 +24,7 @@ إنشاء حساب جديد لقد سجلت دخولك من قبل، تستطيع أن تسجل خروجك إذا أردت. اشترك ببعض القنوات أولا. - لم يُقدر على تنزيل هذا البث. + لا بمكن تنزيل هذا البث. المنطقة تم الاشتراك تم التنزيل. @@ -33,7 +33,7 @@ استيراد الاشتراكات سمة التطبيق لا يمكن لاسم المستخدم وكلمة المرور أن يكونوا فارغين. - هذا من أجل حساب LibreTube الخاص بك. + هذا لحساب Piped. جودة الفيديو الافتراضية أعمدة الشبكة لا شيء هنا. @@ -113,7 +113,7 @@ أيقونة مفعل معطل - الانابيب + Piped يوتيوب تشغيل في الخلفية هذا التعليق ليس له ردود. @@ -203,4 +203,8 @@ استعادة الإعدادات الافتراضية هل أنت متأكد؟ سيؤدي ذلك إلى تسجيل خروجك وإعادة تعيين جميع إعداداتك! نسخ قائمة التشغيل + حذف الحساب + الحساب + استعادة + حذف حساب Piped الخاص بك \ No newline at end of file diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index cc6e701ea..fb2362011 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -77,7 +77,7 @@ Şəbəkə xətası. Nəsə xəta baş verdi. Siz istifadəçi adı və şifrə daxil etməlisiniz. - Bu, LibreTube hesabı üçündür. + Bu, Piped hesabı üçündür. Defolt video keyfiyyəti Şəbəkə sütunları Burada heç nə yoxdur. @@ -201,6 +201,10 @@ Avto-fasilə Ekran söndürüldükdə pleyeri dayandırın. Pleylisti klonlayın - Defoltlara bərpa edin + İlkin tənzimləmələrə bərpa edin Siz əminsiz\? Bu, sizi sistemdən çıxaracaq və bütün tənzimləmələrinizi sıfırlayacaq! + Hesab + Bərpa edin + Hesabı silin + Piped hesabınızı silin \ No newline at end of file diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index 55ee8b2ae..d3f366c44 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -177,7 +177,7 @@ ভিডিও শেষ হওয়ার পর স্বয়ংক্রিয়ভাবে নতুন ভিডিও প্লে করুন। আপনি কি নিশ্চিত\? আপনি লগ আউট হয়ে যাবেন এবং সমস্ত সেটিংস আগের অবস্থায় ফিরে যাবে! ভিএলসি অ্যাপে প্রদর্শন করা যাচ্ছে না। সম্ভবত অ্যাপটি ইনস্টল করা হয়নি। - এটি একটি লিবরাটিউব অ্যাকাউন্টের জন্য। + এটি একটি পাইপড অ্যাকাউন্টের জন্য। প্রথমে ইন্টারনেট চালু করুন। হ্যাঁ কোয়ালিটি @@ -203,4 +203,8 @@ লগ ইন কাস্টম ইনস্ট্যান্স ভিএলসি অ্যাপে প্রদর্শন + অ্যাকাউন্ট মুছে ফেলুন + পাইপড অ্যাকাউন্ট মুছে ফেলুন + ফিরিয়ে আনুন + অ্যাকাউন্ট \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 25486728b..fc6165b06 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -30,7 +30,7 @@ Der Server meldet Schwierigkeiten. Versuche eine andere Instanz\? Netzwerkfehler. Etwas ist schiefgelaufen. - Dies ist für ein LibreTube-Konto. + Dies ist für ein Piped-Konto. Standard-Auflösung Spaltenanzahl Gähnende Leere. @@ -181,4 +181,16 @@ Audio Video Wird heruntergeladen + Standardwerte wiederherstellen + Sind Sie sicher\? Dadurch werden Sie abgemeldet und alle Ihre Einstellungen zurückgesetzt! + Konto löschen + Ihr Piped-Konto löschen + Konto + Wiederherstellen + Trendseite ausblenden + Qualität + Verhalten + Qualität und Verhalten des Players + Automatische Pause + Wiedergabeliste klonen \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 1a7cf324c..998e5e9df 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -35,7 +35,7 @@ Tema Algo salió mal. Tienes que introducir un nombre de usuario y una contraseña. - Esto es para una cuenta de LibreTube. + Esto es para una cuenta Piped. Resolución de vídeo predeterminada Columnas de la cuadrícula No hay nada aquí. @@ -44,7 +44,7 @@ Nombre de la lista de reproducción Hecho. Error :( - Por favor, espere hasta que todas las descargas hayan terminado… + Otra descarga ya está en curso, por favor espere hasta que termine. Hay un problema con el servidor. ¿Probar con otra instancia\? Error de red. Eliminar lista de reproducción @@ -108,7 +108,7 @@ Azul Púrpura Negro - Mystic Material 3 + Material místico 3 Icono Piped YouTube @@ -195,7 +195,7 @@ Calidad Comportamiento Calidad y comportamiento del reproductor - Incremento de búsqueda + Incremento de desplazamiento Piped es una interfaz web alternativa de código abierto para YouTube que proporciona la API que usamos. Sin Piped, LibreTube no existiría. ¡Muchas gracias a sus desarrolladores! Pausa automática Pausa el reproductor cuando se apaga la pantalla. @@ -203,4 +203,8 @@ Clonar lista de reproducción Restaurar los valores predeterminados ¿Está seguro\? ¡Esto te cerrará la sesión y restablecerá todos tus ajustes! + Cuenta + Restaurar + Elimina su cuenta Piped + Eliminar cuenta \ No newline at end of file diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 9d2859ea8..850c439ae 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -7,7 +7,7 @@ Kirjautunut ulos. Kirjautunut sisään. Valitse instanssi - Valitse alue + Alue Tilaa Tallenna Käyttäjätunnus @@ -18,7 +18,7 @@ Peruuta Rekisteröityminen onnistui! Voit nyt tilata haluamiasi kanavia. Olet jo kirjautunut sisään, voit kirjautua ulos tililtäsi. - Kirjaudu sisään ja yritä uudelleen! + Kirjaudu sisään ja yritä uudelleen. Kirjaudu sisään/rekisteröidy Kirjaudu sisään tai rekisteröidy asetuksiin ensin! Tilattu @@ -27,17 +27,17 @@ Ei voi avata VLC:ssä. Sitä ei ehkä ole asennettu. Palvelin vastasi ongelmaan. Ehkä kokeile toista instanssia\? Käyttäjätunnus ja salasana eivät voi olla tyhjiä. - Tämä ei ole Gmail-tilisi. + Tämä on sinun Piped-tilillesi. Videon oletustarkkuus Valitse ruudukon sarakkeet Sovelluksen teema Onnistui. Tietoja - Valitse laatu: + Laatu Jaa - Lisää mukautettu instanssi + Mukautettu instanssi Tilaa ensin joitakin kanavia. - Odota kunnes kaikki lataukset ovat valmiita. + Odota kunnes kaikki lataukset ovat valmiita… Ei voi ladata tätä videota. Avaa VLC:ssä Verkkovirhe. @@ -60,11 +60,11 @@ Kieli Järjestelmän kieli Tumma - Järjestelmän oletusarvo + Järjestelmä Vaalea %1$s tilaajaa Kommentit - Ei Internet-yhteyttä + Yhdistä Internetiin ensin. %1$s videota Yritä uudelleen Sijainti @@ -72,9 +72,9 @@ Asetukset Instanssi Verkkosivusto - Sovelluksen kuvake - Käytössä - Pois käytöltä + Kuvake + Päällä + Pois päältä Piped YouTube Valitse hakusuodatin @@ -86,31 +86,125 @@ Hakuhistoria Tyhjennä historia Oletusvälilehti - SponsorBlock + SponsoriBlokki Toista taustalla - Vihreä - Violetti - OLED-teema + Svengaava vihreä + Miellyttävä violetti + Musta Ilmoitukset Tekijät Tähän kommenttiin ei ole vastauksia. - Versio %1$s on saatavilla. + Versio %1$s on saatavilla Ulkonäkö Lataukset Videoformaatti - Sovellus ajan tasalla + Ajetaan viimeisintä versiota. Lahjoita - Soitin, lataukset, historia - Tee sovelluksesta haluamasi näköinen. + Lataukset, historia + Säädä sovelluksesta haluamasi näköinen. Edistynyt Live - YT Musiikki Soittolistat + YT Music Soittolistat Ohitettu segmentti Sponsori Ei maksettu/itsensä mainostaminen Segmentit Väliaika/Intro animaatio - Päällä + Käytössä Samankaltainen kuin \"sponsori\" lukuunottamatta ei maksettua tai itsensä mainostamista. Tämä sisältää osiot, jotka sisältävät kauppatavaraa, lahjoituksia tai tietoa keiden kanssa he tekivät yhteistyötä. Vuorovaikutus muistutus (tykkäys ja tilaus) + Oletko varma\? Tämä kirjaa sinut ulos ja resetoi kaikki sinun asetuksesi! + Poista sinun Piped-tili + Tili + Palauta + Palauta oletukset + Poista tili + YT Music Kappaleet + YT Music Videot + Maksettu mainostaminen, maksetut vittaukset ja suorat mainokset. Ei itsensä mainostamiselle tai ilmaisille maininnoille kampanjoista, luojista, sivustoista ja tuotteista. + Sisäinen tallennustila + SD-kortti + Musiikki kansio + Elokuva kansio + %1$s näyttökertaa + Oletus + Käyttää https://sponsor.ajay.app ohjelmointirajapintaa + Aikaväli ilman mitään todellista sisältöä. Voi olla tauko, staattinen freimi tai toistuva animaatio. Ei tule käyttää siirroksiin, jotka sisältävät tietoa. + Kun on lyhyt muistutus tykätä, tilata tai seurata sisällön keskellä. Jos se on pitkä tai jotain erityistä, sen tulisi olla itsensä mainostamista. + Loppukortit ja krediitit + Aksentit + Tiedot lopun jälkeen. Ei johtopäätöksille, jotka sisältävät tietoa. + Mystinen materiaali 3 + Mene julkaisuihin Githubissa ladataksesi päivityksen\? + Käytös + Lataa kohteeseen + Sijainti, minne ladattu media tallennetaan. + Vieraile sivustolla saadaksesi lisää tietoa sovelluksesta ja sen ominaisuuksista. + GPLv3+ on copyleft-lisenssi. Käytä, opi, muuta ja jaa; kaikkien kanssa. + Tuota ideoita, käännöksiä, design muutoksia, puhdista ja kirjoita koodia. Mitä enemmän tulee tehtyä, sen paremmaksi se tulee! + Trendikäs soihtu + Muodikas tuli + Täydennä nimi ja ohjelmointirajapinnan linkki. + Tyhjennä mukautetut instanssit + YT Music Albumit + Näytä osiot + Piilota osiot + Täytesisältö/Vitsit + Musiikki: Ei musiikkiosio + Esikatselu/Kertaus + Lisenssi + Levollinen punainen + Autuas sininen + Anna sen verran, miten arvokas tämä on sinulle, jos voit. LibreTuben tiimi on pienempi kuin sinun lahjoitus tai apu. + Etsi uutta versiota + Oletustoistonopeus + Käyttö ainoastaan musiikki videoissa. Sen tulisi kattaa videon osat, jotka eivät ole osa virallisia mixejä. Videon tulee muistuttaa Spotifytä tai mitä tahansa muuta mixattua versiota mahdollisimman paljon tai vähentää puhumista tai muita häiriötekijöitä. + Segmenteille, jotka tarkentavat tulevaa sisältöä tässä tai tulevissa videoissa, mutta eivät tarjoa lisää tietoa. Jos se sisältää klippejä, jotka esiintyvät tässä, tämä on todennäköisesti väärä kategoria. + Kellertävä keltainen + Paina selvittääksesi onko sovellus ajan tasalla. + Ääni ja video + Nimi + Kansion nimi, minne ladattu media on tallennettu. + Latauskansio + Jaa linkki kohteeseen + Kadotettu perintö + Hölmösti muotoiltu + Lentävä liekki + Piped, kirjautuminen, tilaukset + Lisää oma instanssi (omalla vastuulla) + Instanssin nimi + Lisää instanssi + Versio %1$s + Tutustu kaikkiin, jotka ovat mukana kehittämässä ja parantamassa sovellusta. + Lipevä liukuväri + Tehostettu lintu + Linkki instanssin ohjelmointirajapintaan + Anna toimiva linkki + Tutustu LibreTuben tiimiin ja siihen, miten se kaikki tapahtuu. + Asiaan liittyvä sisältö + Näytä aiheeseen liittyviä streameja katsomasi ohella. + Epäolennaisille kohtauksille, jotka lisätty vain täytteeksi tai huumori, joka on tarpeetonta ymmärtääkseen videon pääsisällön. + Video formaatti soittimelle + Esikuormitus + Maksimi puskuroitavan videon sekuntimäärä. + Tiedostojen muuntaminen, jos sekä ääni että video ladataan. + Projektin edistäminen + Sinulla on viimeisin versio. + Ei ääntä + Ei videota + Video + Ladataan + Ääni + Automaattinen toisto + Piilota trendaavat sivu + Linkki instanssin käyttöliittymään + Laatu + Käytös + Laatu ja soittimen käytös + Etsi lisäystä + Piped on avoimen lähdekoodin vaihtoehtoinen web-käyttöliittymä YouTubelle, joka tarjoaa rajapinnan, jota käytämme. Ilman Pipediä, LibreTubea ei olisi. Suuret kiitokset sen kehittäjille! + Pysäytä soitin, kun näyttö on pois päältä. + Automaattinen tauko + Automaattisesti toistaa seuraavan videon kun nykyinen on päättynyt. + Kloonaa soittolista \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 88ea14659..57e1828e9 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -38,7 +38,7 @@ Erreur réseau. Quelque chose s\'est mal passé. Le nom d\'utilisateur et le mot de passe ne peuvent pas être vides. - Ceci est pour un compte LibreTube. + Ceci est pour un compte Piped. Résolution vidéo par défaut Ajouter à la liste de lecture Terminé. @@ -203,4 +203,8 @@ Mettre le lecteur en pause lorsque l\'écran est éteint. Lancer automatiquement la vidéo suivante lorsque la vidéo en cours est terminée. Cloner la liste de lecture + Supprimer votre compte Piped + Supprimer le compte + Compte + Restaurer \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 4d30628bc..36c71e832 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -27,9 +27,9 @@ Tema dell\'app Qualcosa è andato storto. Il nome utente e la password non possono essere vuoti. - Questo è per un account LibreTube. + Questo è per un account Piped. Risoluzione video di Default - Si prega di aspettare che tutti gli scaricamenti siano finiti… + Un altro download è in corso, si prega di attendere che termini. Errore di connessione. Il server ha un problema. Prova un\'altra istanza\? Istanza personalizzata @@ -199,8 +199,12 @@ Piped è un\' alternativa web-frontend open-source per YouTube che fornisce l\'API che usiamo. Senza Piped, LibreTube non esisterebbe. Un enorme grazie ai loro sviluppatori! Riproduci automaticamente il video successivo quando quello corrente è finito. Pausa automatica - Metti in pausa il lettore quando lo schermo é spento. + Metti in pausa il player quando lo schermo è spento. Clona playlist Ripristina predefiniti - Sei sicuro\? Questo ti disconnetterà e ripristinerà tutte le tue impostazioni! + Sei sicuro/a\? Questo ti disconnetterà e ripristinerà tutte le tue impostazioni! + Elimina l\'account + Elimina l\'account Piped + Ripristina + Account \ No newline at end of file diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 5c02f795f..109c1f909 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -19,7 +19,7 @@ יש תקלה עם השרת. לנסות עותק אחר\? משהו השתבש. עליך למלא שם משתמש וסיסמה. - זה לחשבון LibreTube. + זה לחשבון Piped. עמודות רשת יצירת רשימת נגינה שם רשימת הנגינה @@ -203,4 +203,8 @@ לנגן את הסרטון הבא אוטומטית כשהנוכחי מסתיים. שחזור ברירות מחדל להמשיך\? פעולה זו תוציא אותך מהמערכת ותאפס את כל ההגדרות שלך! + חשבון + שחזור + מחיקת חשבון + מחיקת חשבון ה־Piped \ No newline at end of file diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index f64da66fe..afa2ef039 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -14,7 +14,7 @@ Noklusējuma video izšķirtspēja Atskaņošanas saraksts izveidots. Jūs jau esat pierakstījies. Jūs varat izrakstīties no sava konta. - Šis ir LibreTube kontam. + Šis ir Piped kontam. Jūsu konts ir reģistrēts. Tagad varat abonēt kanālus. Sākums Pierakstīties/reģistrēties @@ -203,4 +203,8 @@ Iepauzēt atskaņotāju, kamēr ekrāns ir izslēgts. Automātiski atskaņot nākamo video, kad pašreizējais ir beidzies. Duplicēt atskaņošanas sarakstu + Izdzēst kontu + Izdzēst Piped kontu + Atjaunot + Konts \ No newline at end of file diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 7dab3d58f..cc2960562 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -12,7 +12,7 @@ Görünüm Bağlantı hatası. Kullanıcı adı ve parola girmelisiniz. - Bu, LibreTube hesabı içindir. + Bu, Piped hesabı içindir. Varsayılan Video Çözünürlüğü Oynatma listesini sil Oynatma Listesi Oluştur @@ -203,4 +203,8 @@ Oynatma listesini klonla Varsayılanlara sıfırla Emin misin\? Bu, oturumunuzu kapatacak ve tüm ayarlarınızı sıfırlayacaktır! + Piped hesabınızı silin + Hesap + Eski haline getir + Hesabı sil \ No newline at end of file diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index fc7d71d2f..106b0d83e 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -1,6 +1,6 @@ - Іконка Додатку + Іконка Piped YouTube Грати у фоновому режимі @@ -11,8 +11,8 @@ Вам необхідно ввести ім\'я користувача і пароль. Очистити історію Схоже до \"Спонсор\" окрім неоплаченої або само промоції. Це включає секції про мерчандайз, донати, або інформацію про тих з ким вони співпрацювали. - Жовтий - Колір Акценту + Рухливий жовтий + Акценти Головна Підписки Бібліотека @@ -20,7 +20,7 @@ Пошук Відео Підписатися - Обрати якість: + Якість Відписатися Завантажити Зберегти @@ -33,17 +33,17 @@ Вийшли. Зареєстровано. Тепер Ви можете підписуватися на канали. Уже ввійшли. Вам необхідно спершу вийти з аккаунту. - Будь ласка, ввійдіть і спробуйте ще раз! + Будь ласка, ввійдіть і спробуйте ще раз. Виберіть сервер - Додати інший сервер - Виберіть регіон - Вхід/Реєстрація + Інший сервер + Регіон + Вхід/реєстрація Будь ласка, спочатку увійдіть або зареєструйтесь в налаштуваннях Спочатку підпишіться на якісь канали. Підписки додано Неможливо завантажити цей стрім. Завантаження завершене. - Інше завантаження вже в процесі. Будь ласка, зачекайте поки воно завершиться. + Будь ласка, зачекайте поки воно завершиться… Відкрити у VLC Неможливо відкрити у VLC. Ймовірно воно не інстальоване. Імпорт підписок @@ -51,33 +51,33 @@ Тема Помилка мережі. Щось пішло не так. - Це не ваш аккаунт Gmail. + Це для акаунту Piped. Розширення відео по замовчуванню - Виберіть стовбці поля + Стовпці сітки Видалити плейлист Видалити плейлист\? Створити плейлист - Плейлист створено! + Плейлист створено. Назва плейлисту Тут нічого. Назва плейлисту не може бути порожньою Додати до плейлисту - Успіх! + Готово. Невдача :( Про - Зміна мови - Системна мова - По замовчуванню - Світла тема - Темна тема + Мова + Системна + Системна + Світла + Темна %1$s підписників Налаштування Місце знаходження Сервер - Налаштування + Коригування Веб-сторінка %1$s відео - Відсутнє Інтернет з\'єднання + Спочатку підключіться до Інтернету. Повторити Коментарі Вибрати пошукові фільтри @@ -98,47 +98,73 @@ Увімкнено Сегменти Спонсор - Платні промоції, плантні реферали і прямі реклами. Не дня само-промоції або безкоштовних відгуків про причини/творці/веб-сайти/продукти, які їм подобаються. + Платні промоції, платні реферали та пряма реклама. Не для самореклами або чесних відгуків про творців, вебсайти та продукти які їм подобаються. Неоплачена/Само промоція - Нагадування про дію (Підписатися) - Там де є коротке нагадування про лайк, підписку або стежити за ними посеред контенту. Якщо воно довге або про щось специфічне, воно має бути під само-промоцією. + Нагадування про взаємодію (лайк і підписка) + Там де є коротке нагадування про те, щоб поставити лайк, підписатися або слідувати посеред контенту. Якщо це є довгим або про щось специфічне, воно тоді має бути само-промоцією. Антракт/Вступна Анімація - Певний Інтервал без самого контенту. Може бути паузою, статичне зображення, повторювальна анімація. Це не слід використовувати для переходів, що містять інформацію. - Кінцеві картки/Титри - Титри або коли з\'являються кінцеві картки YouTube. Не для висновків з інформацією. + Певний Інтервал без самого контенту. Може бути паузою, статичне зображення, повторювальна анімація. Не слід використовувати для переходів, що містять інформацію. + Кінцеві картки та титри + Інформація яка слідує по завершені. Не для висновків з інформацією. Ліцензія - Червоний - Синій піксель - Зелений - Фіолетовий - Тема для OLED - Material You + Заспокійливий червоний + Блаженний блакитний + Ідеальний зелений + Приємний фіолетовий + Чорний + Містичний Material 3 Сповіщення Увімкнено Вимкнено Цей коментар не має відповідей. Автори Назва теки, у яку будуть збережені завантажені матеріали. - Назва теки + Назва Пам\'ять телефона Тека завантажень - Тека для відео - Тека для музики - Поділитися відео з: + Відео тека + Музична тека + Поділитися посиланням з Версія %1$s доступна - Нове оновлення доступно. Натисніть ОК щоб перейти на сторінку оновлень GitHub. + Перейти до релізів на GitHub, щоб завантажити\? Завантаження Формат відео - Відвідайте наш сайт, щоб взнати більше про додаток та його функції. + Відвідайте сайт для більшої інформації про додаток та його функції. Внесок - Будь-яка допомога: нові ідеї, переклади, зміни у дизайні, чистка або зміни до коду, — допоможе цьому проєкту. Чим більше зроблено, тим краще! - Публічна ліцензія GNU - це безкоштовна копілефт ліцензія для додатків та інших видів робіт. - Оновлення додатку - Натисніть тут, щоб перевірити наявність нових оновлень. - Додаток актуальний + Надавайте ідеї, перекладайте, змінюйте дизайн, чистіть або змінюйте код. Чим більше зроблено, тим краще! + GPLv3+ - це ліцензія на копілефтовану лібре. Використовувати, вивчати, змінювати і ділитися; з усіма. + Шукати нову версію + Натисніть для перевірки чи додаток оновлений. + Це остання версія. Стандартна швидкість відтворення - Програвач - Зробіть додаток таким, яким ви хочете його бачити. - Програвач, завантаження, історія + Аудіо і відео + Змініть додаток так, як вам до вподоби. + Завантаження, історія Пряма трансляція + Розширене + SD карта + %1$s переглядів + По замовчуванню + Де зберігаються завантажені медіа. + Перетворення файлів, якщо аудіо і відео завантажені. + Дайте те, чого це варте для вас, якщо зможете. Команда LibreTube менша, ніж ваша пожертва чи допомога. + Познайомтеся з усіма, хто бере участь у розробці та вдосконаленні програми. + Втрачена популярність + Ви використовуєте останню версію. + Градієнт Glib + Літаючий вогонь + Посилений птах + Катсцени/Жарти + Для катсцен доданих лише для заповнення або гумор який не потребується для розуміння основного змісту відео. + Музика: Немузична секція + Огляд/Підсумок + Красивий вогонь + Популярний факел + Безглуздої форми + Тільки для використання в музичних кліпах. Він повинен охоплювати частини відео, а не частину офіційних міксів. Зрештою, відео має максимально нагадувати Spotify або будь-яку іншу змішану версію, або зменшувати розмови чи інші відволікання. + Для сегментів, що деталізують майбутній вміст у цьому або майбутньому відео у своїй серії, але не надають додаткової інформації. Якщо він включає в себе кліпи, які тільки з\'являються тут, це, швидше за все, неправильна категорія. + Вид + Поведінка + Завантажити до + Пожертвувати \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index c5031eebe..b44eee467 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -69,7 +69,7 @@ 清除历史记录 YT Music 视频 YT Music 播放列表 - 请在此输入 LibreTube 账户。 + 请在此输入 Piped 账户。 默认分辨率 已创建播放列表。 浅色 @@ -203,4 +203,8 @@ 对于详细说明此系列视频或未来视频中即将出现的内容的片段,但不提供其他信息。如果它包含仅出现在此处的剪辑,则这很可能是错误的类别。 恢复默认值 你确定吗?这会让你退出账户并重置你的所有设置! + 删除你的 Piped 账户 + 账户 + 恢复 + 删除账户 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1ac1a750e..3abd7ec36 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -32,7 +32,7 @@ Subscribe to some channels first. Can\'t download this stream. Download completed. - Please wait till all downloads are finished… + Another download is already in progress, please wait until it\'s finished. Download failed. Open in VLC Can\'t open in VLC. It might not be installed. @@ -207,4 +207,4 @@ Delete your Piped account Account Restore - + \ No newline at end of file diff --git a/app/src/main/res/values/style.xml b/app/src/main/res/values/style.xml index 7b03d823a..7b63c7620 100644 --- a/app/src/main/res/values/style.xml +++ b/app/src/main/res/values/style.xml @@ -30,20 +30,12 @@ wrap_content 20dp 20dp - 15dp - 15dp + 12dp + 12dp ?android:attr/selectableItemBackground - - + + \ No newline at end of file