mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-14 14:20:30 +05:30
commit
42400ca2be
@ -15,19 +15,6 @@
|
||||
"versionName": "0.5.1",
|
||||
"outputFile": "app-universal-release.apk"
|
||||
},
|
||||
{
|
||||
"type": "ONE_OF_MANY",
|
||||
"filters": [
|
||||
{
|
||||
"filterType": "ABI",
|
||||
"value": "x86_64"
|
||||
}
|
||||
],
|
||||
"attributes": [],
|
||||
"versionCode": 18,
|
||||
"versionName": "0.5.1",
|
||||
"outputFile": "app-x86_64-release.apk"
|
||||
},
|
||||
{
|
||||
"type": "ONE_OF_MANY",
|
||||
"filters": [
|
||||
@ -41,19 +28,6 @@
|
||||
"versionName": "0.5.1",
|
||||
"outputFile": "app-armeabi-v7a-release.apk"
|
||||
},
|
||||
{
|
||||
"type": "ONE_OF_MANY",
|
||||
"filters": [
|
||||
{
|
||||
"filterType": "ABI",
|
||||
"value": "x86"
|
||||
}
|
||||
],
|
||||
"attributes": [],
|
||||
"versionCode": 18,
|
||||
"versionName": "0.5.1",
|
||||
"outputFile": "app-x86-release.apk"
|
||||
},
|
||||
{
|
||||
"type": "ONE_OF_MANY",
|
||||
"filters": [
|
||||
@ -66,6 +40,32 @@
|
||||
"versionCode": 18,
|
||||
"versionName": "0.5.1",
|
||||
"outputFile": "app-arm64-v8a-release.apk"
|
||||
},
|
||||
{
|
||||
"type": "ONE_OF_MANY",
|
||||
"filters": [
|
||||
{
|
||||
"filterType": "ABI",
|
||||
"value": "x86_64"
|
||||
}
|
||||
],
|
||||
"attributes": [],
|
||||
"versionCode": 18,
|
||||
"versionName": "0.5.1",
|
||||
"outputFile": "app-x86_64-release.apk"
|
||||
},
|
||||
{
|
||||
"type": "ONE_OF_MANY",
|
||||
"filters": [
|
||||
{
|
||||
"filterType": "ABI",
|
||||
"value": "x86"
|
||||
}
|
||||
],
|
||||
"attributes": [],
|
||||
"versionCode": 18,
|
||||
"versionName": "0.5.1",
|
||||
"outputFile": "app-x86-release.apk"
|
||||
}
|
||||
],
|
||||
"elementType": "File"
|
||||
|
@ -16,9 +16,7 @@ import com.github.libretube.api.CronetHelper
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
import com.github.libretube.constants.BACKGROUND_CHANNEL_ID
|
||||
import com.github.libretube.constants.DOWNLOAD_CHANNEL_ID
|
||||
import com.github.libretube.constants.PIPED_API_URL
|
||||
import com.github.libretube.constants.PUSH_CHANNEL_ID
|
||||
import com.github.libretube.constants.PreferenceKeys
|
||||
import com.github.libretube.db.DatabaseHolder
|
||||
import com.github.libretube.db.obj.WatchHistoryItem
|
||||
import com.github.libretube.db.obj.WatchPosition
|
||||
@ -55,7 +53,9 @@ class MyApp : Application() {
|
||||
/**
|
||||
* Set the api and the auth api url
|
||||
*/
|
||||
initializeRetrofit()
|
||||
RetrofitInstance.initialize()
|
||||
CronetHelper.initCronet(this)
|
||||
ImageHelper.initializeImageLoader(this)
|
||||
|
||||
/**
|
||||
* Initialize the notification listener in the background
|
||||
@ -82,26 +82,6 @@ class MyApp : Application() {
|
||||
databaseMigration()
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the api urls needed for the [RetrofitInstance]
|
||||
*/
|
||||
private fun initializeRetrofit() {
|
||||
RetrofitInstance.url =
|
||||
PreferenceHelper.getString(PreferenceKeys.FETCH_INSTANCE, PIPED_API_URL)
|
||||
// set auth instance
|
||||
RetrofitInstance.authUrl =
|
||||
if (PreferenceHelper.getBoolean(PreferenceKeys.AUTH_INSTANCE_TOGGLE, false)) {
|
||||
PreferenceHelper.getString(
|
||||
PreferenceKeys.AUTH_INSTANCE,
|
||||
PIPED_API_URL
|
||||
)
|
||||
} else {
|
||||
RetrofitInstance.url
|
||||
}
|
||||
CronetHelper.initCronet(this)
|
||||
ImageHelper.initializeImageLoader(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the required [NotificationChannel]s for the app.
|
||||
*/
|
||||
|
@ -3,12 +3,10 @@ package com.github.libretube.activities
|
||||
import android.content.Intent
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.res.Configuration
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
@ -27,11 +25,11 @@ import androidx.navigation.NavController
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.constants.PreferenceKeys
|
||||
import com.github.libretube.databinding.ActivityMainBinding
|
||||
import com.github.libretube.dialogs.ErrorDialog
|
||||
import com.github.libretube.extensions.BaseActivity
|
||||
import com.github.libretube.extensions.TAG
|
||||
import com.github.libretube.fragments.PlayerFragment
|
||||
import com.github.libretube.models.PlayerViewModel
|
||||
import com.github.libretube.models.SearchViewModel
|
||||
@ -316,95 +314,39 @@ class MainActivity : BaseActivity() {
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val intentData: Uri? = intent?.data
|
||||
// check whether an URI got submitted over the intent data
|
||||
if (intentData != null && intentData.host != null && intentData.path != null) {
|
||||
Log.d(TAG(), "intentData: ${intentData.host} ${intentData.path} ")
|
||||
// load the URI of the submitted link (e.g. video)
|
||||
loadIntentData(intentData)
|
||||
// check whether an URI got submitted over the intent data and load it
|
||||
when {
|
||||
intent?.getStringExtra(IntentData.channelId) != null -> navController.navigate(
|
||||
R.id.channelFragment,
|
||||
bundleOf(
|
||||
IntentData.channelName to intent?.getStringExtra(IntentData.channelId)!!
|
||||
)
|
||||
)
|
||||
intent?.getStringExtra(IntentData.channelName) != null -> navController.navigate(
|
||||
R.id.channelFragment,
|
||||
bundleOf(
|
||||
IntentData.channelName to intent?.getStringExtra(IntentData.channelName)
|
||||
)
|
||||
)
|
||||
intent?.getStringExtra(IntentData.playlistId) != null -> navController.navigate(
|
||||
R.id.playlistFragment,
|
||||
bundleOf(
|
||||
IntentData.playlistId to intent?.getStringExtra(IntentData.playlistId)!!
|
||||
)
|
||||
)
|
||||
intent?.getStringExtra(IntentData.videoId) != null -> loadVideo(
|
||||
videoId = intent?.getStringExtra(IntentData.videoId)!!,
|
||||
timeStamp = intent?.getLongExtra(IntentData.timeStamp, 0L)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadIntentData(data: Uri) {
|
||||
if (data.path!!.contains("/channel/")
|
||||
) {
|
||||
val channelId = data.path!!
|
||||
.replace("/channel/", "")
|
||||
|
||||
loadChannel(channelId = channelId)
|
||||
} else if (
|
||||
data.path!!.contains("/c/") ||
|
||||
data.path!!.contains("/user/")
|
||||
) {
|
||||
val channelName = data.path!!
|
||||
.replace("/c/", "")
|
||||
.replace("/user/", "")
|
||||
|
||||
loadChannel(channelName = channelName)
|
||||
} else if (
|
||||
data.path!!.contains("/playlist")
|
||||
) {
|
||||
var playlistId = data.query!!
|
||||
if (playlistId.contains("&")) {
|
||||
for (v in playlistId.split("&")) {
|
||||
if (v.contains("list=")) {
|
||||
playlistId = v.replace("list=", "")
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
playlistId = playlistId.replace("list=", "")
|
||||
}
|
||||
|
||||
loadPlaylist(playlistId)
|
||||
} else if (
|
||||
data.path!!.contains("/shorts/") ||
|
||||
data.path!!.contains("/embed/") ||
|
||||
data.path!!.contains("/v/")
|
||||
) {
|
||||
val videoId = data.path!!
|
||||
.replace("/shorts/", "")
|
||||
.replace("/v/", "")
|
||||
.replace("/embed/", "")
|
||||
|
||||
loadVideo(videoId, data.query)
|
||||
} else if (data.path!!.contains("/watch") && data.query != null) {
|
||||
var videoId = data.query!!
|
||||
|
||||
if (videoId.contains("&")) {
|
||||
val watches = videoId.split("&")
|
||||
for (v in watches) {
|
||||
if (v.contains("v=")) {
|
||||
videoId = v.replace("v=", "")
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
videoId = videoId
|
||||
.replace("v=", "")
|
||||
}
|
||||
|
||||
loadVideo(videoId, data.query)
|
||||
} else {
|
||||
val videoId = data.path!!.replace("/", "")
|
||||
|
||||
loadVideo(videoId, data.query)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadVideo(videoId: String, query: String?) {
|
||||
Log.i(TAG(), "URI type: Video")
|
||||
|
||||
private fun loadVideo(videoId: String, timeStamp: Long?) {
|
||||
val bundle = Bundle()
|
||||
Log.e(TAG(), videoId)
|
||||
|
||||
// for time stamped links
|
||||
if (query != null && query.contains("t=")) {
|
||||
val timeStamp = query.toString().split("t=")[1]
|
||||
bundle.putLong("timeStamp", timeStamp.toLong())
|
||||
}
|
||||
bundle.putString(IntentData.videoId, videoId)
|
||||
if (timeStamp != null) bundle.putLong(IntentData.timeStamp, timeStamp)
|
||||
|
||||
bundle.putString("videoId", videoId)
|
||||
val frag = PlayerFragment()
|
||||
frag.arguments = bundle
|
||||
|
||||
@ -421,27 +363,6 @@ class MainActivity : BaseActivity() {
|
||||
}, 100)
|
||||
}
|
||||
|
||||
private fun loadChannel(
|
||||
channelId: String? = null,
|
||||
channelName: String? = null
|
||||
) {
|
||||
Log.i(TAG(), "Uri Type: Channel")
|
||||
|
||||
val bundle = if (channelId != null) {
|
||||
bundleOf("channel_id" to channelId)
|
||||
} else {
|
||||
bundleOf("channel_name" to channelName)
|
||||
}
|
||||
navController.navigate(R.id.channelFragment, bundle)
|
||||
}
|
||||
|
||||
private fun loadPlaylist(playlistId: String) {
|
||||
Log.i(TAG(), "Uri Type: Playlist")
|
||||
|
||||
val bundle = bundleOf("playlist_id" to playlistId)
|
||||
navController.navigate(R.id.playlistFragment, bundle)
|
||||
}
|
||||
|
||||
private fun minimizePlayer() {
|
||||
binding.mainMotionLayout.transitionToEnd()
|
||||
findViewById<ConstraintLayout>(R.id.main_container).isClickable = false
|
||||
|
@ -6,6 +6,7 @@ import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.extensions.BaseActivity
|
||||
import com.github.libretube.extensions.TAG
|
||||
import com.github.libretube.util.ThemeHelper
|
||||
@ -35,13 +36,87 @@ class RouterActivity : BaseActivity() {
|
||||
return hostsList.contains(intentDataHost)
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the uri and return a bundle with the arguments
|
||||
*/
|
||||
private fun resolveType(intent: Intent, uri: Uri): Intent {
|
||||
when {
|
||||
uri.path!!.contains("/channel/") -> {
|
||||
val channelId = uri.path!!
|
||||
.replace("/channel/", "")
|
||||
|
||||
intent.putExtra(IntentData.channelId, channelId)
|
||||
}
|
||||
uri.path!!.contains("/c/") || uri.path!!.contains("/user/") -> {
|
||||
val channelName = uri.path!!
|
||||
.replace("/c/", "")
|
||||
.replace("/user/", "")
|
||||
|
||||
intent.putExtra(IntentData.channelName, channelName)
|
||||
}
|
||||
uri.path!!.contains("/playlist") -> {
|
||||
var playlistId = uri.query!!
|
||||
if (playlistId.contains("&")) {
|
||||
for (v in playlistId.split("&")) {
|
||||
if (v.contains("list=")) {
|
||||
playlistId = v.replace("list=", "")
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
playlistId = playlistId.replace("list=", "")
|
||||
}
|
||||
|
||||
intent.putExtra(IntentData.playlistId, playlistId)
|
||||
}
|
||||
uri.path!!.contains("/shorts/") ||
|
||||
uri.path!!.contains("/embed/") ||
|
||||
uri.path!!.contains("/v/")
|
||||
-> {
|
||||
val videoId = uri.path!!
|
||||
.replace("/shorts/", "")
|
||||
.replace("/v/", "")
|
||||
.replace("/embed/", "")
|
||||
|
||||
intent.putExtra(IntentData.videoId, videoId)
|
||||
}
|
||||
uri.path!!.contains("/watch") && uri.query != null -> {
|
||||
var videoId = uri.query!!
|
||||
|
||||
if (videoId.contains("&")) {
|
||||
val watches = videoId.split("&")
|
||||
for (v in watches) {
|
||||
if (v.contains("v=")) {
|
||||
videoId = v.replace("v=", "")
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
videoId = videoId
|
||||
.replace("v=", "")
|
||||
}
|
||||
|
||||
intent.putExtra(IntentData.videoId, videoId)
|
||||
} else -> {
|
||||
val timeStamp = uri.getQueryParameter("t")
|
||||
val videoId = uri.path!!.replace("/", "")
|
||||
|
||||
intent.putExtra(IntentData.videoId, videoId)
|
||||
if (timeStamp != null) intent.putExtra(IntentData.timeStamp, timeStamp.toLong())
|
||||
}
|
||||
}
|
||||
return intent
|
||||
}
|
||||
|
||||
private fun handleSendText(uri: Uri) {
|
||||
Log.i(TAG(), uri.toString())
|
||||
|
||||
val pm: PackageManager = this.packageManager
|
||||
val intent = pm.getLaunchIntentForPackage(this.packageName)
|
||||
intent?.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
intent?.data = uri
|
||||
this.startActivity(intent)
|
||||
this.startActivity(
|
||||
resolveType(intent!!, uri)
|
||||
)
|
||||
this.finishAndRemoveTask()
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ class ChannelAdapter(
|
||||
root.setOnClickListener {
|
||||
NavigationHelper.navigateVideo(root.context, trending.url)
|
||||
}
|
||||
val videoId = trending.url.toID()
|
||||
val videoId = trending.url!!.toID()
|
||||
root.setOnLongClickListener {
|
||||
VideoOptionsDialog(videoId)
|
||||
.show(childFragmentManager, VideoOptionsDialog::class.java.name)
|
||||
|
@ -33,7 +33,7 @@ class LegacySubscriptionAdapter(
|
||||
root.setOnClickListener {
|
||||
NavigationHelper.navigateChannel(
|
||||
root.context,
|
||||
subscription.url.toID()
|
||||
subscription.url!!.toID()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ class SearchAdapter(
|
||||
root.setOnClickListener {
|
||||
NavigationHelper.navigateVideo(root.context, item.url)
|
||||
}
|
||||
val videoId = item.url.toID()
|
||||
val videoId = item.url!!.toID()
|
||||
root.setOnLongClickListener {
|
||||
VideoOptionsDialog(videoId)
|
||||
.show(childFragmentManager, VideoOptionsDialog::class.java.name)
|
||||
@ -121,7 +121,7 @@ class SearchAdapter(
|
||||
root.setOnClickListener {
|
||||
NavigationHelper.navigateChannel(root.context, item.url)
|
||||
}
|
||||
val channelId = item.url.toID()
|
||||
val channelId = item.url!!.toID()
|
||||
|
||||
isSubscribed(channelId, binding)
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class SubscriptionChannelAdapter(private val subscriptions: MutableList<Subscrip
|
||||
NavigationHelper.navigateChannel(root.context, subscription.url)
|
||||
}
|
||||
subscriptionSubscribe.setOnClickListener {
|
||||
val channelId = subscription.url.toID()
|
||||
val channelId = subscription.url!!.toID()
|
||||
if (subscribed) {
|
||||
subscriptionSubscribe.text = root.context.getString(R.string.subscribe)
|
||||
SubscriptionHelper.unsubscribe(channelId)
|
||||
|
17
app/src/main/java/com/github/libretube/api/ExternalApi.kt
Normal file
17
app/src/main/java/com/github/libretube/api/ExternalApi.kt
Normal file
@ -0,0 +1,17 @@
|
||||
package com.github.libretube.api
|
||||
|
||||
import com.github.libretube.constants.GITHUB_API_URL
|
||||
import com.github.libretube.constants.PIPED_INSTANCES_URL
|
||||
import com.github.libretube.obj.Instances
|
||||
import com.github.libretube.update.UpdateInfo
|
||||
import retrofit2.http.GET
|
||||
|
||||
interface ExternalApi {
|
||||
// only for fetching servers list
|
||||
@GET(PIPED_INSTANCES_URL)
|
||||
suspend fun getInstances(): List<Instances>
|
||||
|
||||
// fetch latest version info
|
||||
@GET(GITHUB_API_URL)
|
||||
suspend fun getUpdateInfo(): UpdateInfo
|
||||
}
|
@ -3,7 +3,6 @@ package com.github.libretube.api
|
||||
import com.github.libretube.obj.Channel
|
||||
import com.github.libretube.obj.CommentsPage
|
||||
import com.github.libretube.obj.DeleteUserRequest
|
||||
import com.github.libretube.obj.Instances
|
||||
import com.github.libretube.obj.Login
|
||||
import com.github.libretube.obj.Message
|
||||
import com.github.libretube.obj.Playlist
|
||||
@ -23,7 +22,6 @@ import retrofit2.http.Header
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.Path
|
||||
import retrofit2.http.Query
|
||||
import retrofit2.http.Url
|
||||
|
||||
interface PipedApi {
|
||||
@GET("trending")
|
||||
@ -165,8 +163,4 @@ interface PipedApi {
|
||||
@Header("Authorization") token: String,
|
||||
@Body playlistId: PlaylistId
|
||||
): Message
|
||||
|
||||
// only for fetching servers list
|
||||
@GET
|
||||
suspend fun getInstances(@Url url: String): List<Instances>
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
package com.github.libretube.api
|
||||
|
||||
import com.github.libretube.constants.PIPED_API_URL
|
||||
import com.github.libretube.constants.PreferenceKeys
|
||||
import com.github.libretube.util.PreferenceHelper
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.jackson.JacksonConverterFactory
|
||||
|
||||
@ -7,20 +10,55 @@ object RetrofitInstance {
|
||||
lateinit var url: String
|
||||
lateinit var authUrl: String
|
||||
val lazyMgr = resettableManager()
|
||||
val jacksonConverterFactory = JacksonConverterFactory.create()
|
||||
|
||||
val api: PipedApi by resettableLazy(lazyMgr) {
|
||||
Retrofit.Builder()
|
||||
.baseUrl(url)
|
||||
.callFactory(CronetHelper.callFactory)
|
||||
.addConverterFactory(JacksonConverterFactory.create())
|
||||
.addConverterFactory(jacksonConverterFactory)
|
||||
.build()
|
||||
.create(PipedApi::class.java)
|
||||
}
|
||||
|
||||
val authApi: PipedApi by resettableLazy(lazyMgr) {
|
||||
Retrofit.Builder()
|
||||
.baseUrl(authUrl)
|
||||
.callFactory(CronetHelper.callFactory)
|
||||
.addConverterFactory(JacksonConverterFactory.create())
|
||||
.addConverterFactory(jacksonConverterFactory)
|
||||
.build()
|
||||
.create(PipedApi::class.java)
|
||||
}
|
||||
|
||||
val externalApi: ExternalApi by resettableLazy(lazyMgr) {
|
||||
Retrofit.Builder()
|
||||
.baseUrl(url)
|
||||
.callFactory(CronetHelper.callFactory)
|
||||
.addConverterFactory(jacksonConverterFactory)
|
||||
.build()
|
||||
.create(ExternalApi::class.java)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the api urls needed for the [RetrofitInstance]
|
||||
*/
|
||||
fun initialize() {
|
||||
url =
|
||||
PreferenceHelper.getString(PreferenceKeys.FETCH_INSTANCE, PIPED_API_URL)
|
||||
// set auth instance
|
||||
authUrl =
|
||||
if (
|
||||
PreferenceHelper.getBoolean(
|
||||
PreferenceKeys.AUTH_INSTANCE_TOGGLE,
|
||||
false
|
||||
)
|
||||
) {
|
||||
PreferenceHelper.getString(
|
||||
PreferenceKeys.AUTH_INSTANCE,
|
||||
PIPED_API_URL
|
||||
)
|
||||
} else {
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ const val YOUTUBE_FRONTEND_URL = "https://www.youtube.com"
|
||||
* Retrofit Instance
|
||||
*/
|
||||
const val PIPED_API_URL = "https://pipedapi.kavin.rocks/"
|
||||
const val PIPED_INSTANCES_URL = "https://piped-instances.kavin.rocks/"
|
||||
|
||||
/**
|
||||
* Notification IDs
|
||||
|
@ -0,0 +1,10 @@
|
||||
package com.github.libretube.constants
|
||||
|
||||
object IntentData {
|
||||
const val videoId = "videoId"
|
||||
const val channelId = "channelId"
|
||||
const val channelName = "channelName"
|
||||
const val playlistId = "playlistId"
|
||||
const val timeStamp = "timeStamp"
|
||||
const val position = "position"
|
||||
}
|
@ -11,6 +11,7 @@ import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.databinding.DialogAddtoplaylistBinding
|
||||
import com.github.libretube.extensions.TAG
|
||||
import com.github.libretube.models.PlaylistViewModel
|
||||
@ -29,7 +30,7 @@ class AddToPlaylistDialog : DialogFragment() {
|
||||
private lateinit var token: String
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
videoId = arguments?.getString("videoId")!!
|
||||
videoId = arguments?.getString(IntentData.videoId)!!
|
||||
binding = DialogAddtoplaylistBinding.inflate(layoutInflater)
|
||||
binding.title.text = ThemeHelper.getStyledAppName(requireContext())
|
||||
|
||||
|
@ -63,7 +63,7 @@ class PlaylistOptionsDialog(
|
||||
}
|
||||
BackgroundHelper.playOnBackground(
|
||||
context = requireContext(),
|
||||
videoId = playlist.relatedStreams!![0].url.toID(),
|
||||
videoId = playlist.relatedStreams!![0].url!!.toID(),
|
||||
playlistId = playlistId
|
||||
)
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import android.widget.Toast
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.github.libretube.Globals
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.constants.PLAYER_NOTIFICATION_ID
|
||||
import com.github.libretube.util.BackgroundHelper
|
||||
import com.github.libretube.util.PreferenceHelper
|
||||
@ -79,7 +80,7 @@ class VideoOptionsDialog(
|
||||
if (token != "") {
|
||||
val newFragment = AddToPlaylistDialog()
|
||||
val bundle = Bundle()
|
||||
bundle.putString("videoId", videoId)
|
||||
bundle.putString(IntentData.videoId, videoId)
|
||||
newFragment.arguments = bundle
|
||||
newFragment.show(
|
||||
parentFragmentManager,
|
||||
|
@ -3,8 +3,8 @@ package com.github.libretube.extensions
|
||||
/**
|
||||
* format a Piped route to an ID
|
||||
*/
|
||||
fun Any?.toID(): String {
|
||||
return this!!
|
||||
fun Any.toID(): String {
|
||||
return this
|
||||
.toString()
|
||||
.replace("/watch?v=", "") // videos
|
||||
.replace("/channel/", "") // channels
|
||||
|
@ -11,6 +11,7 @@ import com.github.libretube.R
|
||||
import com.github.libretube.adapters.ChannelAdapter
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
import com.github.libretube.api.SubscriptionHelper
|
||||
import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.databinding.FragmentChannelBinding
|
||||
import com.github.libretube.extensions.BaseFragment
|
||||
import com.github.libretube.extensions.TAG
|
||||
@ -34,10 +35,11 @@ class ChannelFragment : BaseFragment() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
arguments?.let {
|
||||
channelId = it.getString("channel_id").toID()
|
||||
channelName = it.getString("channel_name")
|
||||
channelId = it.getString(IntentData.channelId)?.toID()
|
||||
channelName = it.getString(IntentData.channelName)
|
||||
?.replace("/c/", "")
|
||||
?.replace("/user/", "")
|
||||
Log.e(TAG(), channelName.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,7 +61,6 @@ class ChannelFragment : BaseFragment() {
|
||||
val refreshChannel = {
|
||||
binding.channelRefresh.isRefreshing = true
|
||||
fetchChannel()
|
||||
isSubscribed()
|
||||
}
|
||||
refreshChannel()
|
||||
binding.channelRefresh.setOnRefreshListener {
|
||||
@ -81,31 +82,6 @@ class ChannelFragment : BaseFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun isSubscribed() {
|
||||
lifecycleScope.launchWhenCreated {
|
||||
isSubscribed = SubscriptionHelper.isSubscribed(channelId!!)
|
||||
if (isSubscribed == null) return@launchWhenCreated
|
||||
|
||||
runOnUiThread {
|
||||
if (isSubscribed == true) {
|
||||
binding.channelSubscribe.text = getString(R.string.unsubscribe)
|
||||
}
|
||||
|
||||
binding.channelSubscribe.setOnClickListener {
|
||||
binding.channelSubscribe.text = if (isSubscribed == true) {
|
||||
SubscriptionHelper.unsubscribe(channelId!!)
|
||||
isSubscribed = false
|
||||
getString(R.string.subscribe)
|
||||
} else {
|
||||
SubscriptionHelper.subscribe(channelId!!)
|
||||
isSubscribed = true
|
||||
getString(R.string.unsubscribe)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun fetchChannel() {
|
||||
fun run() {
|
||||
lifecycleScope.launchWhenCreated {
|
||||
@ -125,9 +101,35 @@ class ChannelFragment : BaseFragment() {
|
||||
Log.e(TAG(), "HttpException, unexpected response")
|
||||
return@launchWhenCreated
|
||||
}
|
||||
// needed if the channel gets loaded by the ID
|
||||
channelId = response.id
|
||||
|
||||
// fetch and update the subscription status
|
||||
isSubscribed = SubscriptionHelper.isSubscribed(channelId!!)
|
||||
if (isSubscribed == null) return@launchWhenCreated
|
||||
|
||||
runOnUiThread {
|
||||
if (isSubscribed == true) {
|
||||
binding.channelSubscribe.text = getString(R.string.unsubscribe)
|
||||
}
|
||||
|
||||
binding.channelSubscribe.setOnClickListener {
|
||||
binding.channelSubscribe.text = if (isSubscribed == true) {
|
||||
SubscriptionHelper.unsubscribe(channelId!!)
|
||||
isSubscribed = false
|
||||
getString(R.string.subscribe)
|
||||
} else {
|
||||
SubscriptionHelper.subscribe(channelId!!)
|
||||
isSubscribed = true
|
||||
getString(R.string.unsubscribe)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nextPage = response.nextpage
|
||||
isLoading = false
|
||||
binding.channelRefresh.isRefreshing = false
|
||||
|
||||
runOnUiThread {
|
||||
binding.channelScrollView.visibility = View.VISIBLE
|
||||
binding.channelName.text = response.name
|
||||
|
@ -44,6 +44,7 @@ import com.github.libretube.adapters.TrendingAdapter
|
||||
import com.github.libretube.api.CronetHelper
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
import com.github.libretube.api.SubscriptionHelper
|
||||
import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.constants.PreferenceKeys
|
||||
import com.github.libretube.constants.PreferenceRanges
|
||||
import com.github.libretube.databinding.DialogSliderBinding
|
||||
@ -193,8 +194,8 @@ class PlayerFragment : BaseFragment() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
arguments?.let {
|
||||
videoId = it.getString("videoId").toID()
|
||||
playlistId = it.getString("playlistId")
|
||||
videoId = it.getString(IntentData.videoId)!!.toID()
|
||||
playlistId = it.getString(IntentData.playlistId)
|
||||
}
|
||||
}
|
||||
|
||||
@ -979,7 +980,7 @@ class PlayerFragment : BaseFragment() {
|
||||
// seek to saved watch position if available
|
||||
private fun seekToWatchPosition() {
|
||||
// support for time stamped links
|
||||
val timeStamp: Long? = arguments?.getLong("timeStamp")
|
||||
val timeStamp: Long? = arguments?.getLong(IntentData.timeStamp)
|
||||
if (timeStamp != null && timeStamp != 0L) {
|
||||
exoPlayer.seekTo(timeStamp * 1000)
|
||||
return
|
||||
@ -1205,7 +1206,7 @@ class PlayerFragment : BaseFragment() {
|
||||
|
||||
binding.playerChannel.setOnClickListener {
|
||||
val activity = view?.context as MainActivity
|
||||
val bundle = bundleOf("channel_id" to response.uploaderUrl)
|
||||
val bundle = bundleOf(IntentData.channelId to response.uploaderUrl)
|
||||
activity.navController.navigate(R.id.channelFragment, bundle)
|
||||
activity.binding.mainMotionLayout.transitionToEnd()
|
||||
binding.playerMotionLayout.transitionToEnd()
|
||||
@ -1218,7 +1219,7 @@ class PlayerFragment : BaseFragment() {
|
||||
binding.relPlayerSave.setOnClickListener {
|
||||
val newFragment = AddToPlaylistDialog()
|
||||
val bundle = Bundle()
|
||||
bundle.putString("videoId", videoId)
|
||||
bundle.putString(IntentData.videoId, videoId)
|
||||
newFragment.arguments = bundle
|
||||
newFragment.show(childFragmentManager, AddToPlaylistDialog::class.java.name)
|
||||
}
|
||||
@ -1599,7 +1600,7 @@ class PlayerFragment : BaseFragment() {
|
||||
|
||||
private fun isSubscribed() {
|
||||
fun run() {
|
||||
val channelId = streams.uploaderUrl.toID()
|
||||
val channelId = streams.uploaderUrl!!.toID()
|
||||
lifecycleScope.launchWhenCreated {
|
||||
isSubscribed = SubscriptionHelper.isSubscribed(channelId)
|
||||
|
||||
|
@ -12,6 +12,7 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.adapters.PlaylistAdapter
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.databinding.FragmentPlaylistBinding
|
||||
import com.github.libretube.dialogs.PlaylistOptionsDialog
|
||||
import com.github.libretube.extensions.BaseFragment
|
||||
@ -32,7 +33,7 @@ class PlaylistFragment : BaseFragment() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
arguments?.let {
|
||||
playlistId = it.getString("playlist_id")
|
||||
playlistId = it.getString(IntentData.playlistId)
|
||||
isOwner = it.getBoolean("isOwner")
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ class SubscriptionsViewModel : ViewModel() {
|
||||
this@SubscriptionsViewModel.videoFeed.postValue(videoFeed)
|
||||
if (videoFeed.isNotEmpty()) {
|
||||
// save the last recent video to the prefs for the notification worker
|
||||
PreferenceHelper.setLatestVideoId(videoFeed[0].url.toID())
|
||||
PreferenceHelper.setLatestVideoId(videoFeed[0].url!!.toID())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ class InstanceSettings : MaterialPreferenceFragment() {
|
||||
// fetch official public instances
|
||||
|
||||
val response = try {
|
||||
RetrofitInstance.api.getInstances("https://instances.tokhmi.xyz/")
|
||||
RetrofitInstance.externalApi.getInstances()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
emptyList()
|
||||
|
@ -6,9 +6,9 @@ import androidx.preference.Preference
|
||||
import com.github.libretube.BuildConfig
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.activities.SettingsActivity
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
import com.github.libretube.dialogs.UpdateDialog
|
||||
import com.github.libretube.extensions.getStyledSnackBar
|
||||
import com.github.libretube.update.UpdateChecker
|
||||
import com.github.libretube.util.NetworkHelper
|
||||
import com.github.libretube.views.MaterialPreferenceFragment
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@ -102,8 +102,12 @@ class MainSettings : MaterialPreferenceFragment() {
|
||||
return@launch
|
||||
}
|
||||
// check for update
|
||||
val updateInfo = UpdateChecker.getLatestReleaseInfo()
|
||||
if (updateInfo?.name == null) {
|
||||
val updateInfo = try {
|
||||
RetrofitInstance.externalApi.getUpdateInfo()
|
||||
} catch (e: Exception) {
|
||||
return@launch
|
||||
}
|
||||
if (updateInfo.name == null) {
|
||||
// request failed
|
||||
(activity as? SettingsActivity)?.binding?.root?.getStyledSnackBar(R.string.unknown_error)
|
||||
?.show()
|
||||
|
@ -15,6 +15,7 @@ import com.github.libretube.Globals
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
import com.github.libretube.constants.BACKGROUND_CHANNEL_ID
|
||||
import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.constants.PLAYER_NOTIFICATION_ID
|
||||
import com.github.libretube.constants.PreferenceKeys
|
||||
import com.github.libretube.extensions.toID
|
||||
@ -120,9 +121,9 @@ class BackgroundMode : Service() {
|
||||
Globals.playingQueue.clear()
|
||||
|
||||
// get the intent arguments
|
||||
videoId = intent?.getStringExtra("videoId")!!
|
||||
playlistId = intent.getStringExtra("playlistId")
|
||||
val position = intent.getLongExtra("position", 0L)
|
||||
videoId = intent?.getStringExtra(IntentData.videoId)!!
|
||||
playlistId = intent.getStringExtra(IntentData.playlistId)
|
||||
val position = intent.getLongExtra(IntentData.position, 0L)
|
||||
|
||||
// initialize the playlist autoPlay Helper
|
||||
autoPlayHelper = AutoPlayHelper(playlistId)
|
||||
@ -220,7 +221,7 @@ class BackgroundMode : Service() {
|
||||
*/
|
||||
private fun setNextStream() {
|
||||
if (streams!!.relatedStreams!!.isNotEmpty()) {
|
||||
nextStreamId = streams?.relatedStreams!![0].url.toID()
|
||||
nextStreamId = streams?.relatedStreams!![0].url!!.toID()
|
||||
}
|
||||
|
||||
if (playlistId == null) return
|
||||
|
@ -1,34 +0,0 @@
|
||||
package com.github.libretube.update
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.github.libretube.constants.GITHUB_API_URL
|
||||
import com.github.libretube.extensions.await
|
||||
import java.net.URL
|
||||
|
||||
object UpdateChecker {
|
||||
fun getLatestReleaseInfo(): UpdateInfo? {
|
||||
var versionInfo: UpdateInfo? = null
|
||||
// run http request as thread to make it async
|
||||
Thread {
|
||||
// otherwise crashes without internet
|
||||
versionInfo = getUpdateInfo()
|
||||
try {
|
||||
versionInfo = getUpdateInfo()
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
}.await()
|
||||
|
||||
// return the information about the latest version
|
||||
return versionInfo
|
||||
}
|
||||
|
||||
private fun getUpdateInfo(): UpdateInfo? {
|
||||
// get the github API response
|
||||
val latestVersionApiUrl = URL(GITHUB_API_URL)
|
||||
val json = latestVersionApiUrl.readText()
|
||||
|
||||
// Parse and return the json data
|
||||
val mapper = ObjectMapper()
|
||||
return mapper.readValue(json, UpdateInfo::class.java)
|
||||
}
|
||||
}
|
@ -55,7 +55,7 @@ class AutoPlayHelper(
|
||||
)
|
||||
)
|
||||
) {
|
||||
nextStreamId = relatedStreams[index].url.toID()
|
||||
nextStreamId = relatedStreams[index].url!!.toID()
|
||||
if (index + 1 < relatedStreams.size) {
|
||||
index += 1
|
||||
} else {
|
||||
@ -94,7 +94,7 @@ class AutoPlayHelper(
|
||||
)
|
||||
}
|
||||
// save the playlist urls to the list
|
||||
playlistStreamIds += playlist.relatedStreams!!.map { it.url.toID() }
|
||||
playlistStreamIds += playlist.relatedStreams!!.map { it.url!!.toID() }
|
||||
// save playlistNextPage for usage if video is not contained
|
||||
playlistNextPage = playlist.nextpage
|
||||
return@withContext getNextPlaylistVideoId(currentVideoId)
|
||||
|
@ -3,6 +3,7 @@ package com.github.libretube.util
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.services.BackgroundMode
|
||||
|
||||
/**
|
||||
@ -17,8 +18,8 @@ object BackgroundHelper {
|
||||
) {
|
||||
// create an intent for the background mode service
|
||||
val intent = Intent(context, BackgroundMode::class.java)
|
||||
intent.putExtra("videoId", videoId)
|
||||
if (playlistId != null) intent.putExtra("playlistId", playlistId)
|
||||
intent.putExtra(IntentData.videoId, videoId)
|
||||
if (playlistId != null) intent.putExtra(IntentData.playlistId, playlistId)
|
||||
if (position != null) intent.putExtra("position", position)
|
||||
|
||||
// start the background mode as foreground service
|
||||
|
@ -7,6 +7,7 @@ import androidx.constraintlayout.motion.widget.MotionLayout
|
||||
import androidx.core.os.bundleOf
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.activities.MainActivity
|
||||
import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.extensions.toID
|
||||
import com.github.libretube.fragments.PlayerFragment
|
||||
|
||||
@ -17,7 +18,7 @@ object NavigationHelper {
|
||||
) {
|
||||
if (channelId != null) {
|
||||
val activity = context as MainActivity
|
||||
val bundle = bundleOf("channel_id" to channelId)
|
||||
val bundle = bundleOf(IntentData.channelId to channelId)
|
||||
activity.navController.navigate(R.id.channelFragment, bundle)
|
||||
try {
|
||||
val mainMotionLayout =
|
||||
@ -39,8 +40,8 @@ object NavigationHelper {
|
||||
) {
|
||||
if (videoId != null) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString("videoId", videoId.toID())
|
||||
if (playlistId != null) bundle.putString("playlistId", playlistId)
|
||||
bundle.putString(IntentData.videoId, videoId.toID())
|
||||
if (playlistId != null) bundle.putString(IntentData.playlistId, playlistId)
|
||||
val frag = PlayerFragment()
|
||||
frag.arguments = bundle
|
||||
val activity = context as AppCompatActivity
|
||||
@ -61,7 +62,7 @@ object NavigationHelper {
|
||||
if (playlistId != null) {
|
||||
val activity = context as MainActivity
|
||||
val bundle = Bundle()
|
||||
bundle.putString("playlist_id", playlistId)
|
||||
bundle.putString(IntentData.playlistId, playlistId)
|
||||
bundle.putBoolean("isOwner", isOwner)
|
||||
activity.navController.navigate(R.id.playlistFragment, bundle)
|
||||
}
|
||||
|
@ -35,18 +35,12 @@
|
||||
android:name="com.github.libretube.fragments.ChannelFragment"
|
||||
android:label="channel"
|
||||
tools:layout="@layout/fragment_channel">
|
||||
<argument
|
||||
android:name="channel_id"
|
||||
app:argType="string" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/playlistFragment"
|
||||
android:name="com.github.libretube.fragments.PlaylistFragment"
|
||||
android:label="fragment_playlist"
|
||||
tools:layout="@layout/fragment_playlist">
|
||||
<argument
|
||||
android:name="playlist_id"
|
||||
app:argType="string" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/watchHistoryFragment"
|
||||
|
Loading…
Reference in New Issue
Block a user