From 833987f48d945138152fa04ea06f4c87020939c0 Mon Sep 17 00:00:00 2001 From: SayantanRC Date: Fri, 27 May 2022 19:51:02 +0530 Subject: [PATCH 1/9] issue_5509: Add deeplink support for f-droid links and programmatically assign origin based on it. --- .../e/apps/application/ApplicationFragment.kt | 26 +++++++++++++++---- .../res/navigation/navigation_resource.xml | 7 +++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt b/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt index 14aef8e72..5718c55be 100644 --- a/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt +++ b/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt @@ -74,6 +74,21 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) { private var _binding: FragmentApplicationBinding? = null private val binding get() = _binding!! + /* + * We have no way to pass the "origin" argument as CLEANAPK for f-droid deep links. + * Instead we manually check the intent uri, see if it is + * an f-droid.org link, then we use Origin.CLEANAPK. + * + * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5509 + */ + private val origin by lazy { + if (activity?.intent?.data?.toString()?.contains("f-droid.org") == true) { + Origin.CLEANAPK + } else { + args.origin + } + } + @Inject lateinit var pkgManagerModule: PkgManagerModule @@ -103,9 +118,10 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) { if (hasInternet) { applicationViewModel.getApplicationDetails( args.id, - args.packageName, + /* Remove trailing slash (if present) that can become part of the packageName */ + args.packageName.run { if (endsWith('/')) dropLast(1) else this }, authData, - args.origin + origin ) } } @@ -125,7 +141,7 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) { val notAvailable = getString(R.string.not_available) - val screenshotsRVAdapter = ApplicationScreenshotsRVAdapter(args.origin) + val screenshotsRVAdapter = ApplicationScreenshotsRVAdapter(origin) binding.recyclerView.apply { adapter = screenshotsRVAdapter layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) @@ -150,7 +166,7 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) { appAuthor.text = it.author appInfoFetchViewModel.setAuthorNameIfNeeded(appAuthor, it) categoryTitle.text = it.category - if (args.origin == Origin.CLEANAPK) { + if (origin == Origin.CLEANAPK) { appIcon.load(CleanAPKInterface.ASSET_URL + it.icon_image_path) } else { appIcon.load(it.icon_image_path) @@ -209,7 +225,7 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) { binding.infoInclude.apply { appUpdatedOn.text = getString( R.string.updated_on, - if (args.origin == Origin.CLEANAPK) getString(R.string.not_available) else it.last_modified + if (origin == Origin.CLEANAPK) getString(R.string.not_available) else it.last_modified ) appRequires.text = getString(R.string.min_android_version, notAvailable) appVersion.text = getString( diff --git a/app/src/main/res/navigation/navigation_resource.xml b/app/src/main/res/navigation/navigation_resource.xml index 5fd2fa9ca..72cc30c0d 100644 --- a/app/src/main/res/navigation/navigation_resource.xml +++ b/app/src/main/res/navigation/navigation_resource.xml @@ -106,6 +106,13 @@ + + -- GitLab From 74e75223395394e101800f52b98d62d78950ce9a Mon Sep 17 00:00:00 2001 From: SayantanRC Date: Mon, 30 May 2022 21:07:28 +0530 Subject: [PATCH 2/9] issue_5509: create method getApplicationDetailsCleanapk(packageName) in FusedAPIImpl --- .../e/apps/api/fused/FusedAPIImpl.kt | 18 ++++++++++++++++++ .../e/apps/api/fused/FusedAPIRepository.kt | 4 ++++ 2 files changed, 22 insertions(+) diff --git a/app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt b/app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt index 8130bf9ae..b3b88a869 100644 --- a/app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt +++ b/app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt @@ -304,6 +304,24 @@ class FusedAPIImpl @Inject constructor( } } + /* + * Function to search cleanapk using package name. + * Will be used to handle f-droid deeplink. + * + * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5509 + */ + suspend fun getApplicationDetailsCleanapk(packageName: String): FusedApp? { + val result = cleanAPKRepository.searchApps( + keyword = packageName, + by = "package_name" + ).body() + return if (result?.apps?.isNotEmpty() == true && result.numberOfResults == 1) { + cleanAPKRepository.getAppOrPWADetailsByID(result.apps[0]._id).body()?.app + } else { + null + } + } + suspend fun getApplicationDetails( packageNameList: List, authData: AuthData, diff --git a/app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt b/app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt index 745dd0773..afce7f501 100644 --- a/app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt +++ b/app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt @@ -54,6 +54,10 @@ class FusedAPIRepository @Inject constructor( return fusedAPIImpl.getApplicationDetails(packageNameList, authData, origin) } + suspend fun getApplicationDetailsCleanapk(packageName: String): FusedApp? { + return fusedAPIImpl.getApplicationDetailsCleanapk(packageName) + } + suspend fun getApplicationDetails( id: String, packageName: String, -- GitLab From 04bfeca5812eb6011709da8ba80beba2d5682511 Mon Sep 17 00:00:00 2001 From: SayantanRC Date: Mon, 30 May 2022 21:09:41 +0530 Subject: [PATCH 3/9] issue_5509: create method searchCleanapkUsingPackageName(packageName) in ApplicationViewModel --- .../apps/application/ApplicationViewModel.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/src/main/java/foundation/e/apps/application/ApplicationViewModel.kt b/app/src/main/java/foundation/e/apps/application/ApplicationViewModel.kt index ea96457cb..27664f341 100644 --- a/app/src/main/java/foundation/e/apps/application/ApplicationViewModel.kt +++ b/app/src/main/java/foundation/e/apps/application/ApplicationViewModel.kt @@ -71,6 +71,26 @@ class ApplicationViewModel @Inject constructor( } } + /* + * Dedicated method to get app details from cleanapk using package name. + * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5509 + */ + fun searchCleanapkUsingPackageName(packageName: String) { + viewModelScope.launch { + try { + fusedAPIRepository.getApplicationDetailsCleanapk(packageName).run { + if (this == null) { + _errorMessageLiveData.postValue(R.string.app_not_found) + } else { + fusedApp.postValue(this) + } + } + } catch (e: Exception) { + _errorMessageLiveData.postValue(R.string.unknown_error) + } + } + } + fun transformPermsToString(): String { var permissionString = "" fusedApp.value?.let { -- GitLab From b51684dfa0d16ddbed57ba375bc2786e5121b51f Mon Sep 17 00:00:00 2001 From: SayantanRC Date: Mon, 30 May 2022 21:12:40 +0530 Subject: [PATCH 4/9] issue_5509: implement fetching f-droid info in ApplicationFragment --- .../e/apps/application/ApplicationFragment.kt | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt b/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt index 5718c55be..3a2a2554e 100644 --- a/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt +++ b/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt @@ -75,14 +75,24 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) { private val binding get() = _binding!! /* - * We have no way to pass the "origin" argument as CLEANAPK for f-droid deep links. - * Instead we manually check the intent uri, see if it is - * an f-droid.org link, then we use Origin.CLEANAPK. + * We have no way to pass an argument for a specific deeplink to signify it is an f-droid link. + * Hence we check the intent from the activity. + * This boolean is later used to lock the origin to Origin.CLEANAPK, + * and call a different method to fetch from cleanapk. + * + * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5509 + */ + private val isFdroidDeepLink: Boolean by lazy { + activity?.intent?.data?.host?.equals("f-droid.org") ?: false + } + + /* + * We will use this variable in all cases instead of directly calling args.origin. * * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5509 */ private val origin by lazy { - if (activity?.intent?.data?.toString()?.contains("f-droid.org") == true) { + if (isFdroidDeepLink) { Origin.CLEANAPK } else { args.origin @@ -116,13 +126,18 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) { mainActivityViewModel.internetConnection.observe(viewLifecycleOwner) { hasInternet -> mainActivityViewModel.authData.observe(viewLifecycleOwner) { authData -> if (hasInternet) { - applicationViewModel.getApplicationDetails( - args.id, - /* Remove trailing slash (if present) that can become part of the packageName */ - args.packageName.run { if (endsWith('/')) dropLast(1) else this }, - authData, - origin - ) + /* Remove trailing slash (if present) that can become part of the packageName */ + val packageName = args.packageName.run { if (endsWith('/')) dropLast(1) else this } + if (isFdroidDeepLink) { + applicationViewModel.searchCleanapkUsingPackageName(packageName) + } else { + applicationViewModel.getApplicationDetails( + args.id, + packageName, + authData, + origin + ) + } } } } -- GitLab From b72916865ec0bc7b230df3020caa2439ed869338 Mon Sep 17 00:00:00 2001 From: SayantanRC Date: Mon, 30 May 2022 21:25:22 +0530 Subject: [PATCH 5/9] issue_5509: show loading progress bar while fetching the app. --- .../java/foundation/e/apps/application/ApplicationFragment.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt b/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt index 3a2a2554e..cb2701d8a 100644 --- a/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt +++ b/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt @@ -126,6 +126,8 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) { mainActivityViewModel.internetConnection.observe(viewLifecycleOwner) { hasInternet -> mainActivityViewModel.authData.observe(viewLifecycleOwner) { authData -> if (hasInternet) { + /* Show the loading bar. */ + binding.progressBar.visibility = View.VISIBLE /* Remove trailing slash (if present) that can become part of the packageName */ val packageName = args.packageName.run { if (endsWith('/')) dropLast(1) else this } if (isFdroidDeepLink) { -- GitLab From a54fe62eeaedf53e2e7adba592dd6c3092b3e27b Mon Sep 17 00:00:00 2001 From: SayantanRC Date: Mon, 30 May 2022 22:37:05 +0530 Subject: [PATCH 6/9] issue_5509: prevent repeatedly loading app details --- .../foundation/e/apps/application/ApplicationFragment.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt b/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt index cb2701d8a..b7c5cf364 100644 --- a/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt +++ b/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt @@ -99,6 +99,8 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) { } } + private var isDetailsLoaded = false + @Inject lateinit var pkgManagerModule: PkgManagerModule @@ -125,7 +127,7 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) { mainActivityViewModel.internetConnection.observe(viewLifecycleOwner) { hasInternet -> mainActivityViewModel.authData.observe(viewLifecycleOwner) { authData -> - if (hasInternet) { + if (hasInternet && !isDetailsLoaded) { /* Show the loading bar. */ binding.progressBar.visibility = View.VISIBLE /* Remove trailing slash (if present) that can become part of the packageName */ @@ -171,6 +173,7 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) { } applicationViewModel.fusedApp.observe(viewLifecycleOwner) { + isDetailsLoaded = true if (applicationViewModel.appStatus.value == null) { applicationViewModel.appStatus.value = it.status } -- GitLab From 0a06961c0a006f5240c7313429d07f58cf39e852 Mon Sep 17 00:00:00 2001 From: SayantanRC Date: Thu, 9 Jun 2022 17:16:40 +0530 Subject: [PATCH 7/9] issue_5509: implement checking for timeout while loading app details --- .../e/apps/api/fused/FusedAPIImpl.kt | 24 +++++++++++-------- .../e/apps/api/fused/FusedAPIRepository.kt | 4 ++-- .../apps/application/ApplicationViewModel.kt | 4 ++-- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt b/app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt index 7d94105ae..34927bd2b 100644 --- a/app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt +++ b/app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt @@ -356,16 +356,20 @@ class FusedAPIImpl @Inject constructor( * * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5509 */ - suspend fun getApplicationDetailsCleanapk(packageName: String): FusedApp? { - val result = cleanAPKRepository.searchApps( - keyword = packageName, - by = "package_name" - ).body() - return if (result?.apps?.isNotEmpty() == true && result.numberOfResults == 1) { - cleanAPKRepository.getAppOrPWADetailsByID(result.apps[0]._id).body()?.app - } else { - null - } + suspend fun searchCleanapkUsingPackageName(packageName: String): Pair { + var fusedApp = FusedApp() + val status = runCodeBlockWithTimeout({ + val result = cleanAPKRepository.searchApps( + keyword = packageName, + by = "package_name" + ).body() + if (result?.apps?.isNotEmpty() == true && result.numberOfResults == 1) { + fusedApp = + cleanAPKRepository.getAppOrPWADetailsByID(result.apps[0]._id).body()?.app + ?: FusedApp() + } + }) + return Pair(fusedApp, status) } suspend fun getApplicationDetails( diff --git a/app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt b/app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt index 8a219cad1..ed46dbbfe 100644 --- a/app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt +++ b/app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt @@ -59,8 +59,8 @@ class FusedAPIRepository @Inject constructor( return fusedAPIImpl.getApplicationDetails(packageNameList, authData, origin) } - suspend fun getApplicationDetailsCleanapk(packageName: String): FusedApp? { - return fusedAPIImpl.getApplicationDetailsCleanapk(packageName) + suspend fun searchCleanapkUsingPackageName(packageName: String): Pair { + return fusedAPIImpl.searchCleanapkUsingPackageName(packageName) } suspend fun getApplicationDetails( diff --git a/app/src/main/java/foundation/e/apps/application/ApplicationViewModel.kt b/app/src/main/java/foundation/e/apps/application/ApplicationViewModel.kt index 8a61c23da..26990dda1 100644 --- a/app/src/main/java/foundation/e/apps/application/ApplicationViewModel.kt +++ b/app/src/main/java/foundation/e/apps/application/ApplicationViewModel.kt @@ -79,8 +79,8 @@ class ApplicationViewModel @Inject constructor( fun searchCleanapkUsingPackageName(packageName: String) { viewModelScope.launch { try { - fusedAPIRepository.getApplicationDetailsCleanapk(packageName).run { - if (this == null) { + fusedAPIRepository.searchCleanapkUsingPackageName(packageName).run { + if (this.first.package_name.isBlank()) { _errorMessageLiveData.postValue(R.string.app_not_found) } else { fusedApp.postValue(this) -- GitLab From 1ff9e86d6f2bbda3973ada819ee5c9c3532ac4ac Mon Sep 17 00:00:00 2001 From: SayantanRC Date: Thu, 9 Jun 2022 18:49:23 +0530 Subject: [PATCH 8/9] issue_5509: rename searchCleanapkUsingPackageName to getCleanapkAppDetails --- app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt | 2 +- .../java/foundation/e/apps/api/fused/FusedAPIRepository.kt | 4 ++-- .../java/foundation/e/apps/application/ApplicationFragment.kt | 2 +- .../foundation/e/apps/application/ApplicationViewModel.kt | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt b/app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt index 34927bd2b..1f94ca7cb 100644 --- a/app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt +++ b/app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt @@ -356,7 +356,7 @@ class FusedAPIImpl @Inject constructor( * * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5509 */ - suspend fun searchCleanapkUsingPackageName(packageName: String): Pair { + suspend fun getCleanapkAppDetails(packageName: String): Pair { var fusedApp = FusedApp() val status = runCodeBlockWithTimeout({ val result = cleanAPKRepository.searchApps( diff --git a/app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt b/app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt index ed46dbbfe..585e921a9 100644 --- a/app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt +++ b/app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt @@ -59,8 +59,8 @@ class FusedAPIRepository @Inject constructor( return fusedAPIImpl.getApplicationDetails(packageNameList, authData, origin) } - suspend fun searchCleanapkUsingPackageName(packageName: String): Pair { - return fusedAPIImpl.searchCleanapkUsingPackageName(packageName) + suspend fun getCleanapkAppDetails(packageName: String): Pair { + return fusedAPIImpl.getCleanapkAppDetails(packageName) } suspend fun getApplicationDetails( diff --git a/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt b/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt index 03b7805de..fa1f7467c 100644 --- a/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt +++ b/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt @@ -341,7 +341,7 @@ class ApplicationFragment : TimeoutFragment(R.layout.fragment_application) { /* Remove trailing slash (if present) that can become part of the packageName */ val packageName = args.packageName.run { if (endsWith('/')) dropLast(1) else this } if (isFdroidDeepLink) { - applicationViewModel.searchCleanapkUsingPackageName(packageName) + applicationViewModel.getCleanapkAppDetails(packageName) } else { applicationViewModel.getApplicationDetails( args.id, diff --git a/app/src/main/java/foundation/e/apps/application/ApplicationViewModel.kt b/app/src/main/java/foundation/e/apps/application/ApplicationViewModel.kt index 26990dda1..dc094e5ff 100644 --- a/app/src/main/java/foundation/e/apps/application/ApplicationViewModel.kt +++ b/app/src/main/java/foundation/e/apps/application/ApplicationViewModel.kt @@ -76,10 +76,10 @@ class ApplicationViewModel @Inject constructor( * Dedicated method to get app details from cleanapk using package name. * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5509 */ - fun searchCleanapkUsingPackageName(packageName: String) { + fun getCleanapkAppDetails(packageName: String) { viewModelScope.launch { try { - fusedAPIRepository.searchCleanapkUsingPackageName(packageName).run { + fusedAPIRepository.getCleanapkAppDetails(packageName).run { if (this.first.package_name.isBlank()) { _errorMessageLiveData.postValue(R.string.app_not_found) } else { -- GitLab From fc239052497062e37ae23caa0ddfc40b97fbd0af Mon Sep 17 00:00:00 2001 From: SayantanRC Date: Thu, 9 Jun 2022 19:15:54 +0530 Subject: [PATCH 9/9] issue_5509: move location of getCleanapkAppDetails() to avoid potential merge conflicts --- .../foundation/e/apps/api/fused/FusedAPIRepository.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt b/app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt index 585e921a9..c1cd78252 100644 --- a/app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt +++ b/app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt @@ -59,10 +59,6 @@ class FusedAPIRepository @Inject constructor( return fusedAPIImpl.getApplicationDetails(packageNameList, authData, origin) } - suspend fun getCleanapkAppDetails(packageName: String): Pair { - return fusedAPIImpl.getCleanapkAppDetails(packageName) - } - suspend fun getApplicationDetails( id: String, packageName: String, @@ -72,6 +68,10 @@ class FusedAPIRepository @Inject constructor( return fusedAPIImpl.getApplicationDetails(id, packageName, authData, origin) } + suspend fun getCleanapkAppDetails(packageName: String): Pair { + return fusedAPIImpl.getCleanapkAppDetails(packageName) + } + suspend fun updateFusedDownloadWithDownloadingInfo( authData: AuthData, origin: Origin, -- GitLab