mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-29 08:20:32 +05:30
In-built browser intent chooser (#3511)
Co-authored-by: Isira Seneviratne <31027858+Isira-Seneviratne@users.noreply.github.com>
This commit is contained in:
parent
ad20a1821f
commit
e7995b4bd9
@ -338,11 +338,6 @@
|
||||
android:enabled="true"
|
||||
android:exported="false" />
|
||||
|
||||
<service
|
||||
android:name=".services.UpdateService"
|
||||
android:enabled="true"
|
||||
android:exported="false" />
|
||||
|
||||
<service
|
||||
android:name=".services.BackgroundMode"
|
||||
android:enabled="true"
|
||||
@ -354,4 +349,10 @@
|
||||
android:exported="false" />
|
||||
</application>
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<data android:scheme="*" />
|
||||
</intent>
|
||||
</queries>
|
||||
</manifest>
|
||||
|
@ -2,18 +2,41 @@ package com.github.libretube.helpers
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import androidx.core.net.toUri
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.extensions.toastFromMainThread
|
||||
import com.github.libretube.ui.sheets.IntentChooserSheet
|
||||
|
||||
object IntentHelper {
|
||||
fun openLinkFromHref(context: Context, link: String) {
|
||||
val uri = Uri.parse(link)
|
||||
val launchIntent = Intent(Intent.ACTION_VIEW).setData(uri)
|
||||
fun openLinkFromHref(context: Context, fragmentManager: FragmentManager, link: String) {
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
.setData(link.toUri())
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
val resolveInfoList = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
context.packageManager
|
||||
.queryIntentActivities(
|
||||
intent,
|
||||
PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_ALL.toLong())
|
||||
)
|
||||
} else {
|
||||
context.packageManager
|
||||
.queryIntentActivities(intent, PackageManager.MATCH_ALL)
|
||||
}
|
||||
|
||||
if (resolveInfoList.isEmpty()) {
|
||||
try {
|
||||
context.startActivity(launchIntent)
|
||||
context.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
context.toastFromMainThread(R.string.unknown_error)
|
||||
context.toastFromMainThread(R.string.error)
|
||||
}
|
||||
} else {
|
||||
IntentChooserSheet(resolveInfoList, link)
|
||||
.show(fragmentManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ class AboutActivity : BaseActivity() {
|
||||
|
||||
private fun setupCard(card: MaterialCardView, link: String) {
|
||||
card.setOnClickListener {
|
||||
IntentHelper.openLinkFromHref(this, link)
|
||||
IntentHelper.openLinkFromHref(this, supportFragmentManager, link)
|
||||
}
|
||||
card.setOnLongClickListener {
|
||||
onLongClick(link)
|
||||
@ -77,7 +77,7 @@ class AboutActivity : BaseActivity() {
|
||||
Snackbar.LENGTH_LONG
|
||||
)
|
||||
.setAction(R.string.open_copied) {
|
||||
IntentHelper.openLinkFromHref(this, href)
|
||||
IntentHelper.openLinkFromHref(this, supportFragmentManager, href)
|
||||
}
|
||||
.setAnimationMode(Snackbar.ANIMATION_MODE_FADE)
|
||||
.show()
|
||||
|
@ -35,7 +35,7 @@ class HelpActivity : BaseActivity() {
|
||||
|
||||
private fun setupCard(card: MaterialCardView, link: String) {
|
||||
card.setOnClickListener {
|
||||
IntentHelper.openLinkFromHref(this, link)
|
||||
IntentHelper.openLinkFromHref(this, supportFragmentManager, link)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,44 @@
|
||||
package com.github.libretube.ui.adapters
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.net.toUri
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.libretube.databinding.IntentChooserItemBinding
|
||||
import com.github.libretube.ui.viewholders.IntentChooserViewHolder
|
||||
|
||||
/**
|
||||
* An adapter for opening an intent chooser inside the app, example-wise for urls
|
||||
* @param packages A list of resolved packages found by a package query
|
||||
*/
|
||||
class IntentChooserAdapter(
|
||||
private val packages: List<ResolveInfo>,
|
||||
private val queryUrl: String
|
||||
) : RecyclerView.Adapter<IntentChooserViewHolder>() {
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): IntentChooserViewHolder {
|
||||
val layoutInflater = LayoutInflater.from(parent.context)
|
||||
val binding = IntentChooserItemBinding.inflate(layoutInflater, parent, false)
|
||||
return IntentChooserViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun getItemCount() = packages.size
|
||||
|
||||
override fun onBindViewHolder(holder: IntentChooserViewHolder, position: Int) {
|
||||
val currentPackage = packages[position]
|
||||
holder.binding.apply {
|
||||
val drawable = currentPackage.loadIcon(root.context.packageManager)
|
||||
appIconIV.setImageDrawable(drawable)
|
||||
val appLabel = currentPackage.loadLabel(root.context.packageManager)
|
||||
appNameTV.text = appLabel
|
||||
root.setOnClickListener {
|
||||
runCatching {
|
||||
val intent = Intent(Intent.ACTION_VIEW, queryUrl.toUri())
|
||||
.setPackage(currentPackage.activityInfo.packageName)
|
||||
root.context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.github.libretube.ui.sheets
|
||||
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.github.libretube.databinding.BottomSheetBinding
|
||||
import com.github.libretube.ui.adapters.IntentChooserAdapter
|
||||
|
||||
class IntentChooserSheet(
|
||||
private val packages: List<ResolveInfo>,
|
||||
private val url: String
|
||||
) : BaseBottomSheet() {
|
||||
private var _binding: BottomSheetBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = BottomSheetBinding.inflate(inflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
binding.optionsRecycler.layoutManager = GridLayoutManager(context, 3)
|
||||
binding.optionsRecycler.adapter = IntentChooserAdapter(packages, url)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
@ -18,9 +18,7 @@ import com.github.libretube.ui.dialogs.DownloadDialog
|
||||
import com.github.libretube.ui.dialogs.ShareDialog
|
||||
import com.github.libretube.ui.fragments.SubscriptionsFragment
|
||||
import com.github.libretube.util.PlayingQueue
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,8 @@
|
||||
package com.github.libretube.ui.viewholders
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.libretube.databinding.IntentChooserItemBinding
|
||||
|
||||
class IntentChooserViewHolder(
|
||||
val binding: IntentChooserItemBinding
|
||||
) : RecyclerView.ViewHolder(binding.root)
|
30
app/src/main/res/layout/intent_chooser_item.xml
Normal file
30
app/src/main/res/layout/intent_chooser_item.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="10dp"
|
||||
android:background="@drawable/rounded_ripple"
|
||||
android:orientation="vertical"
|
||||
android:paddingVertical="10dp">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/appIconIV"
|
||||
android:layout_width="75dp"
|
||||
android:layout_height="75dp"
|
||||
android:layout_gravity="center"
|
||||
android:padding="10dp"
|
||||
app:shapeAppearance="@style/CircleImageView"
|
||||
tools:src="@mipmap/ic_launcher_round" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/appNameTV"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textSize="11sp" />
|
||||
|
||||
</LinearLayout>
|
Loading…
x
Reference in New Issue
Block a user