Skip to content

Commit

Permalink
Merge pull request #6034 from Bnyro/master
Browse files Browse the repository at this point in the history
feat: download popup that can be displayed over other apps
  • Loading branch information
Bnyro authored May 14, 2024
2 parents 4ecd751 + f609486 commit 916b8a4
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 70 deletions.
36 changes: 26 additions & 10 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<application
android:name=".LibreTubeApp"
android:allowBackup="true"
android:banner="@mipmap/ic_launcher"
android:enableOnBackInvokedCallback="true"
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
Expand All @@ -32,7 +33,6 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/StartupTheme"
android:enableOnBackInvokedCallback="true"
tools:targetApi="tiramisu">

<activity
Expand Down Expand Up @@ -79,6 +79,22 @@

</activity>

<activity
android:name=".ui.activities.DownloadActivity"
android:enabled="true"
android:exported="true"
android:label="@string/download"
android:launchMode="singleTop"
android:theme="@style/Theme.Material3.DayNight.Dialog">

<intent-filter android:label="@string/download">
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>

</activity>

<activity
android:name=".ui.activities.OfflinePlayerActivity"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
Expand Down Expand Up @@ -356,27 +372,27 @@

<service
android:name=".services.DownloadService"
android:foregroundServiceType="dataSync"
android:enabled="true"
android:exported="false" />
android:exported="false"
android:foregroundServiceType="dataSync" />

<service
android:name=".services.PlaylistDownloadEnqueueService"
android:foregroundServiceType="dataSync"
android:enabled="true"
android:exported="false" />
android:exported="false"
android:foregroundServiceType="dataSync" />

<service
android:name=".services.OnlinePlayerService"
android:foregroundServiceType="mediaPlayback"
android:enabled="true"
android:exported="false" />
android:exported="false"
android:foregroundServiceType="mediaPlayback" />

<service
android:name=".services.OfflinePlayerService"
android:foregroundServiceType="mediaPlayback"
android:enabled="true"
android:exported="false" />
android:exported="false"
android:foregroundServiceType="mediaPlayback" />

<receiver
android:name=".receivers.NotificationReceiver"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ import com.github.libretube.obj.NewPipeSubscriptions
import com.github.libretube.obj.PipedImportPlaylist
import com.github.libretube.obj.PipedPlaylistFile
import com.github.libretube.ui.dialogs.ShareDialog
import com.github.libretube.util.TextUtils
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.decodeFromStream
import kotlinx.serialization.json.encodeToStream
import java.util.Date
import java.util.stream.Collectors

object ImportHelper {
Expand Down Expand Up @@ -182,7 +182,7 @@ object ImportHelper {

val playlistName = lines[1].split(",").reversed().getOrNull(2)
// the playlist name can be undefined in some cases, e.g. watch later lists
playlist.name = playlistName ?: Date().toString()
playlist.name = playlistName ?: TextUtils.defaultPlaylistName

// start directly at the beginning if header playlist info such as name is missing
val startIndex = if (playlistName == null) {
Expand Down
33 changes: 33 additions & 0 deletions app/src/main/java/com/github/libretube/helpers/IntentHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.github.libretube.R
import com.github.libretube.constants.IntentData
import com.github.libretube.extensions.toastFromMainThread
import com.github.libretube.ui.sheets.IntentChooserSheet
import com.github.libretube.util.TextUtils.toTimeInSeconds

object IntentHelper {
private fun getResolveIntent(link: String) = Intent(Intent.ACTION_VIEW)
Expand Down Expand Up @@ -67,4 +68,36 @@ object IntentHelper {
Toast.makeText(context, R.string.no_player_found, Toast.LENGTH_SHORT).show()
}
}

/**
* Resolve the uri and return a bundle with the arguments
*/
fun resolveType(intent: Intent, uri: Uri) = with(intent) {
val lastSegment = uri.lastPathSegment
val secondLastSegment = uri.pathSegments.getOrNull(uri.pathSegments.size - 2)
when {
lastSegment == "results" -> {
putExtra(IntentData.query, uri.getQueryParameter("search_query"))
}
secondLastSegment == "channel" -> {
putExtra(IntentData.channelId, lastSegment)
}
secondLastSegment == "c" || secondLastSegment == "user" -> {
putExtra(IntentData.channelName, lastSegment)
}
lastSegment == "playlist" -> {
putExtra(IntentData.playlistId, uri.getQueryParameter("list"))
}
lastSegment == "watch_videos" -> {
putExtra(IntentData.playlistName, uri.getQueryParameter("title"))
val videoIds = uri.getQueryParameter("video_ids")?.split(",")
putExtra(IntentData.videoIds, videoIds?.toTypedArray())
}
else -> {
val id = if (lastSegment == "watch") uri.getQueryParameter("v") else lastSegment
putExtra(IntentData.videoId, id)
putExtra(IntentData.timeStamp, uri.getQueryParameter("t")?.toTimeInSeconds())
}
}
}
}
4 changes: 4 additions & 0 deletions app/src/main/java/com/github/libretube/helpers/ThemeHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ object ThemeHelper {
if (pureThemeEnabled) activity.theme.applyStyle(R.style.Pure, true)
}

fun applyDialogActivityTheme(activity: Activity) {
activity.theme.applyStyle(R.style.DialogActivity, true)
}

/**
* set the theme mode (light, dark, auto)
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Intent
import android.os.Bundle
import androidx.core.net.toUri
import com.github.libretube.constants.IntentData
import com.github.libretube.helpers.IntentHelper
import com.github.libretube.ui.base.BaseActivity
import com.github.libretube.util.PlayingQueue

Expand All @@ -15,31 +16,23 @@ class AddToQueueActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val uri = intent.getStringExtra(Intent.EXTRA_TEXT)!!.toUri()
var videoId: String? = null
listOf("/shorts/", "/v/", "/embed/").forEach {
if (uri.path!!.contains(it)) {
videoId = uri.path!!.replace(it, "")
}
}
if (
uri.path!!.contains("/watch") && uri.query != null
) {
videoId = uri.getQueryParameter("v")
}
val videoId = intent.getStringExtra(Intent.EXTRA_TEXT)
?.let { IntentHelper.resolveType(Intent(), it.toUri()) }
?.getStringExtra(IntentData.videoId)

if (videoId == null) videoId = uri.path!!.replace("/", "")
if (videoId != null) {
val newIntent = packageManager.getLaunchIntentForPackage(packageName)

val intent = packageManager.getLaunchIntentForPackage(packageName)
// if playing a video currently, the video will be added to the queue
if (PlayingQueue.isNotEmpty()) {
PlayingQueue.insertByVideoId(videoId)
} else {
newIntent?.putExtra(IntentData.videoId, videoId)
}

// if playing a video currently, the video will be added to the queue
if (PlayingQueue.isNotEmpty()) {
PlayingQueue.insertByVideoId(videoId!!)
} else {
intent?.putExtra(IntentData.videoId, videoId)
startActivity(newIntent)
}

startActivity(intent)
finishAndRemoveTask()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.github.libretube.ui.activities

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.net.toUri
import androidx.core.os.bundleOf
import com.github.libretube.constants.IntentData
import com.github.libretube.enums.PlaylistType
import com.github.libretube.helpers.IntentHelper
import com.github.libretube.helpers.ThemeHelper
import com.github.libretube.ui.base.BaseActivity
import com.github.libretube.ui.dialogs.DownloadDialog
import com.github.libretube.ui.dialogs.DownloadPlaylistDialog

class DownloadActivity: BaseActivity() {
override val isDialogActivity: Boolean = true

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val intentData = intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
IntentHelper.resolveType(Intent(), it.toUri())
}

val videoId = intentData?.getStringExtra(IntentData.videoId)
val playlistId = intentData?.getStringExtra(IntentData.playlistId)
if (videoId != null) {
DownloadDialog().apply {
arguments = bundleOf(IntentData.videoId to videoId)
}.show(supportFragmentManager, null)
} else if (playlistId != null) {
DownloadPlaylistDialog().apply {
arguments = bundleOf(
IntentData.playlistId to playlistId,
IntentData.playlistType to PlaylistType.PUBLIC,
IntentData.playlistName to intent.getStringExtra(Intent.EXTRA_TITLE)
)
}.show(supportFragmentManager, null)
} else {
finishAndRemoveTask()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import android.net.Uri
import android.os.Bundle
import android.util.Log
import androidx.core.net.toUri
import com.github.libretube.constants.IntentData
import com.github.libretube.extensions.TAG
import com.github.libretube.helpers.IntentHelper
import com.github.libretube.helpers.NavigationHelper
import com.github.libretube.ui.base.BaseActivity
import com.github.libretube.util.TextUtils.toTimeInSeconds

class RouterActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
Expand All @@ -25,42 +24,12 @@ class RouterActivity : BaseActivity() {
}
}

/**
* Resolve the uri and return a bundle with the arguments
*/
private fun Intent.resolveType(uri: Uri) = apply {
val lastSegment = uri.lastPathSegment
val secondLastSegment = uri.pathSegments.getOrNull(uri.pathSegments.size - 2)
when {
lastSegment == "results" -> {
putExtra(IntentData.query, uri.getQueryParameter("search_query"))
}
secondLastSegment == "channel" -> {
putExtra(IntentData.channelId, lastSegment)
}
secondLastSegment == "c" || secondLastSegment == "user" -> {
putExtra(IntentData.channelName, lastSegment)
}
lastSegment == "playlist" -> {
putExtra(IntentData.playlistId, uri.getQueryParameter("list"))
}
lastSegment == "watch_videos" -> {
putExtra(IntentData.playlistName, uri.getQueryParameter("title"))
val videoIds = uri.getQueryParameter("video_ids")?.split(",")
putExtra(IntentData.videoIds, videoIds?.toTypedArray())
}
else -> {
val id = if (lastSegment == "watch") uri.getQueryParameter("v") else lastSegment
putExtra(IntentData.videoId, id)
putExtra(IntentData.timeStamp, uri.getQueryParameter("t")?.toTimeInSeconds())
}
}
}

private fun handleSendText(uri: Uri) {
Log.i(TAG(), uri.toString())

val intent = packageManager.getLaunchIntentForPackage(packageName)!!.resolveType(uri)
val intent = packageManager.getLaunchIntentForPackage(packageName)!!.let { intent ->
IntentHelper.resolveType(intent, uri)
}
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(intent)
finishAndRemoveTask()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import com.github.libretube.helpers.WindowHelper
* Activity that applies the LibreTube theme and the in-app language
*/
open class BaseActivity : AppCompatActivity() {
open val isDialogActivity: Boolean = false

val screenOrientationPref by lazy {
val orientationPref = PreferenceHelper.getString(
PreferenceKeys.ORIENTATION,
Expand All @@ -36,6 +38,7 @@ open class BaseActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// set the app theme (e.g. Material You)
ThemeHelper.updateTheme(this)
if (isDialogActivity) ThemeHelper.applyDialogActivityTheme(this)

// Set the navigation and statusBar color if SDK < 23
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.github.libretube.extensions.getWhileDigit
import com.github.libretube.extensions.serializable
import com.github.libretube.helpers.LocaleHelper
import com.github.libretube.services.PlaylistDownloadEnqueueService
import com.github.libretube.util.TextUtils
import com.google.android.material.dialog.MaterialAlertDialogBuilder

class DownloadPlaylistDialog : DialogFragment() {
Expand All @@ -25,7 +26,7 @@ class DownloadPlaylistDialog : DialogFragment() {
super.onCreate(savedInstanceState)

playlistId = requireArguments().getString(IntentData.playlistId)!!
playlistName = requireArguments().getString(IntentData.playlistName)!!
playlistName = requireArguments().getString(IntentData.playlistName) ?: TextUtils.defaultPlaylistName
playlistType = requireArguments().serializable(IntentData.playlistType)!!
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ import com.github.libretube.constants.IntentData
import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.toastFromMainDispatcher
import com.github.libretube.obj.PipedImportPlaylist
import com.github.libretube.util.TextUtils
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.Date

class ImportTempPlaylistDialog : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val title = arguments?.getString(IntentData.playlistName)
?.takeIf { it.isNotEmpty() }
?: Date().toString()
?: TextUtils.defaultPlaylistName
val videoIds = arguments?.getStringArray(IntentData.videoIds).orEmpty()

return MaterialAlertDialogBuilder(requireContext())
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/com/github/libretube/util/TextUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
import java.time.temporal.ChronoUnit
import java.util.Date
import kotlin.time.Duration
import kotlinx.datetime.LocalDate as KotlinLocalDate

Expand All @@ -33,6 +34,8 @@ object TextUtils {
*/
private val MEDIUM_DATE_FORMATTER = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)

val defaultPlaylistName get() = Date().toString()

/**
* Localize the date from a date string, using the medium format.
* @param date The date to parse
Expand Down
Loading

0 comments on commit 916b8a4

Please sign in to comment.