From 4d985fff61b95839e3663e3cc4f76e1c45d52f90 Mon Sep 17 00:00:00 2001 From: LivingWithHippos Date: Fri, 25 Sep 2020 20:53:14 +0200 Subject: [PATCH 01/11] register app to receive magnet/torrent intent --- app/app/src/main/AndroidManifest.xml | 122 +++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/app/app/src/main/AndroidManifest.xml b/app/app/src/main/AndroidManifest.xml index 992298cc1..eacc0e819 100644 --- a/app/app/src/main/AndroidManifest.xml +++ b/app/app/src/main/AndroidManifest.xml @@ -20,6 +20,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Date: Sat, 26 Sep 2020 16:56:33 +0200 Subject: [PATCH 02/11] support null for isMagnet extension --- .../unchained/utilities/extension/StringExtension.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/app/src/main/java/com/github/livingwithhippos/unchained/utilities/extension/StringExtension.kt b/app/app/src/main/java/com/github/livingwithhippos/unchained/utilities/extension/StringExtension.kt index d357ba3c2..cd30c9bfc 100644 --- a/app/app/src/main/java/com/github/livingwithhippos/unchained/utilities/extension/StringExtension.kt +++ b/app/app/src/main/java/com/github/livingwithhippos/unchained/utilities/extension/StringExtension.kt @@ -18,7 +18,9 @@ fun String.isWebUrl(): Boolean = /** * check if a String is a magnet link */ -fun String.isMagnet(): Boolean { +fun String?.isMagnet(): Boolean { + if (this == null) + return false val m: Matcher = Pattern.compile(MAGNET_PATTERN).matcher(this) return m.lookingAt() } From a45f4204d06c9b9d21b1eb774aca2b0c17253fd0 Mon Sep 17 00:00:00 2001 From: LivingWithHippos Date: Sat, 26 Sep 2020 16:57:07 +0200 Subject: [PATCH 03/11] added Context version of showToast extension --- .../unchained/utilities/extension/Extension.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/app/src/main/java/com/github/livingwithhippos/unchained/utilities/extension/Extension.kt b/app/app/src/main/java/com/github/livingwithhippos/unchained/utilities/extension/Extension.kt index 19c56506d..bebf8c3fd 100644 --- a/app/app/src/main/java/com/github/livingwithhippos/unchained/utilities/extension/Extension.kt +++ b/app/app/src/main/java/com/github/livingwithhippos/unchained/utilities/extension/Extension.kt @@ -25,6 +25,10 @@ fun Fragment.showToast(stringResource: Int, length: Int = Toast.LENGTH_SHORT) { Toast.makeText(requireContext(), getString(stringResource), length).show() } +fun Context.showToast(stringResource: Int, length: Int = Toast.LENGTH_SHORT) { + Toast.makeText(this, getString(stringResource), length).show() +} + /** * Show a toast message * @param message: the message and shown From 17e124e420bbb979aacbbbaaa77a899127884619 Mon Sep 17 00:00:00 2001 From: LivingWithHippos Date: Mon, 28 Sep 2020 11:26:17 +0200 Subject: [PATCH 04/11] added livedata extension functions --- .../utilities/extension/Extension.kt | 58 ++++++++++++++++++- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/app/app/src/main/java/com/github/livingwithhippos/unchained/utilities/extension/Extension.kt b/app/app/src/main/java/com/github/livingwithhippos/unchained/utilities/extension/Extension.kt index bebf8c3fd..90fd3b4c4 100644 --- a/app/app/src/main/java/com/github/livingwithhippos/unchained/utilities/extension/Extension.kt +++ b/app/app/src/main/java/com/github/livingwithhippos/unchained/utilities/extension/Extension.kt @@ -11,9 +11,13 @@ import android.net.Uri import android.util.Log import android.widget.Toast import androidx.fragment.app.Fragment +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.LiveData +import androidx.lifecycle.MediatorLiveData +import androidx.lifecycle.Observer import com.github.livingwithhippos.unchained.BuildConfig import com.github.livingwithhippos.unchained.R -import java.util.* +import java.util.Locale /** * Show a toast message @@ -25,8 +29,10 @@ fun Fragment.showToast(stringResource: Int, length: Int = Toast.LENGTH_SHORT) { Toast.makeText(requireContext(), getString(stringResource), length).show() } -fun Context.showToast(stringResource: Int, length: Int = Toast.LENGTH_SHORT) { - Toast.makeText(this, getString(stringResource), length).show() +fun Context.showToast(stringResource: Int, length: Int = Toast.LENGTH_SHORT) = this.showToast(getString(stringResource, length)) + +fun Context.showToast(message: String, length: Int = Toast.LENGTH_SHORT) { + Toast.makeText(this, message, length).show() } /** @@ -111,4 +117,50 @@ fun Activity.getUpdatedLocaleContext(context: Context, language: String): Contex Locale.setDefault(locale) configuration.setLocale(locale) return context.createConfigurationContext(configuration) +} + +fun LiveData.combineWith( + liveData: LiveData, + block: (T?, K?) -> R +): LiveData { + val result = MediatorLiveData() + result.addSource(this) { + result.value = block(this.value, liveData.value) + } + result.addSource(liveData) { + result.value = block(this.value, liveData.value) + } + return result +} + +fun zipLiveData(t: LiveData, k: LiveData): LiveData> { + return MediatorLiveData>().apply { + var lastT: T? = null + var lastK: K? = null + + fun update() { + val localLastT = lastT + val localLastK = lastK + if (localLastT != null && localLastK != null) + this.value = Pair(localLastT, localLastK) + } + + addSource(t) { + lastT = it + update() + } + addSource(k) { + lastK = it + update() + } + } +} + +fun LiveData.observeOnce(lifecycleOwner: LifecycleOwner, observer: Observer) { + observe(lifecycleOwner, object : Observer { + override fun onChanged(t: T?) { + observer.onChanged(t) + removeObserver(this) + } + }) } \ No newline at end of file From 44663b71346eb5abb061b1469e0ba97b0b6ac4f8 Mon Sep 17 00:00:00 2001 From: LivingWithHippos Date: Mon, 28 Sep 2020 11:28:00 +0200 Subject: [PATCH 05/11] process external click on magnet links as a new download --- .../unchained/base/MainActivity.kt | 41 ++++++++++++++++++- .../newdownload/view/NewDownloadFragment.kt | 9 ++++ .../start/viewmodel/MainActivityViewModel.kt | 7 ++++ app/app/src/main/res/values-it/strings.xml | 4 +- app/app/src/main/res/values/strings.xml | 2 + 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/app/app/src/main/java/com/github/livingwithhippos/unchained/base/MainActivity.kt b/app/app/src/main/java/com/github/livingwithhippos/unchained/base/MainActivity.kt index 3586a00fd..312158cb0 100644 --- a/app/app/src/main/java/com/github/livingwithhippos/unchained/base/MainActivity.kt +++ b/app/app/src/main/java/com/github/livingwithhippos/unchained/base/MainActivity.kt @@ -1,5 +1,8 @@ package com.github.livingwithhippos.unchained.base + +import com.github.livingwithhippos.unchained.utilities.extension.observeOnce + import android.content.Intent import android.os.Bundle import androidx.activity.viewModels @@ -13,6 +16,8 @@ import com.github.livingwithhippos.unchained.databinding.ActivityMainBinding import com.github.livingwithhippos.unchained.settings.SettingsActivity import com.github.livingwithhippos.unchained.start.viewmodel.MainActivityViewModel import com.github.livingwithhippos.unchained.utilities.BottomNavManager +import com.github.livingwithhippos.unchained.utilities.extension.isMagnet +import com.github.livingwithhippos.unchained.utilities.extension.showToast import com.google.android.material.bottomnavigation.BottomNavigationView import dagger.hilt.android.AndroidEntryPoint @@ -27,6 +32,8 @@ class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding + val viewModel: MainActivityViewModel by viewModels() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -47,7 +54,6 @@ class MainActivity : AppCompatActivity() { } } - val viewModel: MainActivityViewModel by viewModels() viewModel.authenticationState.observe(this, Observer { state -> when (state.peekContent()) { // go to login fragment @@ -71,6 +77,39 @@ class MainActivity : AppCompatActivity() { } } }) + + getIntentData() + } + + private fun getIntentData() { + + intent?.let{ + /* Implicit intent with path to torrent file, http or magnet link */ + + // clicks on magnets arrive here + val data = it.data + // check uri content + if (data!=null && data.toString().isMagnet()) { + // check auth state before loading them + viewModel.authenticationState.observeOnce(this, { auth -> + when (auth.peekContent()) { + AuthenticationState.AUTHENTICATED -> processMagnetIntent(data.toString()) + AuthenticationState.AUTHENTICATED_NO_PREMIUM -> baseContext.showToast(R.string.premium_needed_torrent) + else -> showToast(R.string.please_login) + } + }) + + } + } + } + + private fun processMagnetIntent(magnet: String) { + // simulate click on new download tab + val bottomNav = findViewById(R.id.bottom_nav_view) + if (bottomNav.selectedItemId != R.id.navigation_download) { + bottomNav.selectedItemId = R.id.navigation_download + } + viewModel.addMagnet(magnet) } private fun openSettings() { diff --git a/app/app/src/main/java/com/github/livingwithhippos/unchained/newdownload/view/NewDownloadFragment.kt b/app/app/src/main/java/com/github/livingwithhippos/unchained/newdownload/view/NewDownloadFragment.kt index aab719b0a..286264deb 100644 --- a/app/app/src/main/java/com/github/livingwithhippos/unchained/newdownload/view/NewDownloadFragment.kt +++ b/app/app/src/main/java/com/github/livingwithhippos/unchained/newdownload/view/NewDownloadFragment.kt @@ -192,6 +192,15 @@ class NewDownloadFragment : UnchainedFragment(), NewDownloadListener { downloadBinding.bUnrestrict.runRippleAnimation() } + activityViewModel.externalMagnetLiveData.observe(viewLifecycleOwner, { + it.getContentIfNotHandled()?.let { magnet -> + // set as text input text + downloadBinding.tiLink.setText(magnet, TextView.BufferType.EDITABLE) + // simulate button click + downloadBinding.bUnrestrict.performClick() + } + }) + return downloadBinding.root } diff --git a/app/app/src/main/java/com/github/livingwithhippos/unchained/start/viewmodel/MainActivityViewModel.kt b/app/app/src/main/java/com/github/livingwithhippos/unchained/start/viewmodel/MainActivityViewModel.kt index 17e48ec2f..f478ba81e 100644 --- a/app/app/src/main/java/com/github/livingwithhippos/unchained/start/viewmodel/MainActivityViewModel.kt +++ b/app/app/src/main/java/com/github/livingwithhippos/unchained/start/viewmodel/MainActivityViewModel.kt @@ -13,6 +13,7 @@ import com.github.livingwithhippos.unchained.data.repositoy.UserRepository import com.github.livingwithhippos.unchained.data.model.User import com.github.livingwithhippos.unchained.utilities.Event import com.github.livingwithhippos.unchained.utilities.PRIVATE_TOKEN +import com.github.livingwithhippos.unchained.utilities.extension.zipLiveData import kotlinx.coroutines.launch /** @@ -29,6 +30,8 @@ class MainActivityViewModel @ViewModelInject constructor( val userLiveData = MutableLiveData() + val externalMagnetLiveData = MutableLiveData>() + // fixme: this is here because userLiveData.postValue(user) is throwing an unsafe error // but auto-correcting it changes the value of val authenticationState = MutableLiveData>() to a nullable one @SuppressLint("NullSafeMutableLiveData") @@ -129,4 +132,8 @@ class MainActivityViewModel @ViewModelInject constructor( } } + fun addMagnet(magnet: String) { + externalMagnetLiveData.postValue(Event(magnet)) + } + } \ No newline at end of file diff --git a/app/app/src/main/res/values-it/strings.xml b/app/app/src/main/res/values-it/strings.xml index 19ef7cb37..e10af6b5c 100644 --- a/app/app/src/main/res/values-it/strings.xml +++ b/app/app/src/main/res/values-it/strings.xml @@ -53,7 +53,7 @@ Conversione Magnet In attesa di selezione files In coda - Scaricando + Scaricamento Scaricato Errore Virus @@ -144,4 +144,6 @@ Per utilizzare questa funzionalità è richiesto un account premium Torrent in preparazione, attendere… Inserisci un magnet o un link + Si prega di autenticarsi sull\'account + Per torrent e magnet è richiestoun abbonamento premium \ No newline at end of file diff --git a/app/app/src/main/res/values/strings.xml b/app/app/src/main/res/values/strings.xml index 3f78de59d..f3e7e52fd 100644 --- a/app/app/src/main/res/values/strings.xml +++ b/app/app/src/main/res/values/strings.xml @@ -356,6 +356,8 @@ ]]> A premium subscription is required to use this + A premium subscription is required for magnet and torrents Preparing torrent, please wait… Please insert a magnet or a link + Please log in your account \ No newline at end of file From ebd5ed9309cfc30e1b891fe323d6491b499e6b44 Mon Sep 17 00:00:00 2001 From: LivingWithHippos Date: Mon, 28 Sep 2020 11:41:42 +0200 Subject: [PATCH 06/11] some layout updates --- .../res/layout/fragment_torrent_details.xml | 6 +++-- .../main/res/layout/fragment_user_profile.xml | 23 ++++++++----------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/app/app/src/main/res/layout/fragment_torrent_details.xml b/app/app/src/main/res/layout/fragment_torrent_details.xml index d5cd5fc58..3c214eb93 100644 --- a/app/app/src/main/res/layout/fragment_torrent_details.xml +++ b/app/app/src/main/res/layout/fragment_torrent_details.xml @@ -53,7 +53,8 @@