diff --git a/app/src/main/java/foundation/e/apps/MainActivity.kt b/app/src/main/java/foundation/e/apps/MainActivity.kt index 63d0ac77e0611112815b562a429e6b1c1d280ec0..b0997bed7f0b0c84093b51152c81c55d66343a07 100644 --- a/app/src/main/java/foundation/e/apps/MainActivity.kt +++ b/app/src/main/java/foundation/e/apps/MainActivity.kt @@ -202,11 +202,6 @@ class MainActivity : AppCompatActivity() { viewModel.isAppPurchased.observe(this) { if (it.isNotEmpty()) { startInstallationOfPurchasedApp(viewModel, it) - ApplicationDialogFragment( - title = "Purchase complete!", - message = "Your app will automatically be downloaded in this device", - positiveButtonText = "OK" - ).show(supportFragmentManager, TAG) } } @@ -252,8 +247,17 @@ class MainActivity : AppCompatActivity() { val fusedDownload = viewModel.updateAwaitingForPurchasedApp(it) if (fusedDownload != null) { InstallWorkManager.enqueueWork(fusedDownload) + ApplicationDialogFragment( + title = getString(R.string.purchase_complete), + message = getString(R.string.download_automatically_message), + positiveButtonText = getString(R.string.ok) + ).show(supportFragmentManager, TAG) } else { - showSnackbarMessage(getString(R.string.paid_app_anonymous_message)) + ApplicationDialogFragment( + title = getString(R.string.purchase_error), + message = getString(R.string.something_went_wrong), + positiveButtonText = getString(R.string.ok) + ).show(supportFragmentManager, TAG) } } } diff --git a/app/src/main/java/foundation/e/apps/MainActivityViewModel.kt b/app/src/main/java/foundation/e/apps/MainActivityViewModel.kt index 19d8bbc30eecc46cc696067ef35e08722f73a6f5..8d56c305a19ee6d94040438e9f53647ae4221e1d 100644 --- a/app/src/main/java/foundation/e/apps/MainActivityViewModel.kt +++ b/app/src/main/java/foundation/e/apps/MainActivityViewModel.kt @@ -188,12 +188,20 @@ class MainActivityViewModel @Inject constructor( * * Issue: https://gitlab.e.foundation/e/os/backlog/-/issues/178 */ - fun checkUnsupportedApplication(fusedApp: FusedApp, alertDialogContext: Context? = null): Boolean { + fun checkUnsupportedApplication( + fusedApp: FusedApp, + alertDialogContext: Context? = null + ): Boolean { if (!fusedApp.isFree && fusedApp.price.isBlank()) { alertDialogContext?.let { context -> AlertDialog.Builder(context).apply { setTitle(R.string.unsupported_app_title) - setMessage(context.getString(R.string.unsupported_app_unreleased, fusedApp.name)) + setMessage( + context.getString( + R.string.unsupported_app_unreleased, + fusedApp.name + ) + ) setPositiveButton(android.R.string.ok, null) }.show() } @@ -288,8 +296,11 @@ class MainActivityViewModel @Inject constructor( Origin.GPLAY, fusedDownload ) + } catch (e: ApiException.AppNotPurchased) { + e.printStackTrace() + return null } catch (e: Exception) { - Log.e(TAG, e.stackTraceToString()) + e.printStackTrace() _errorMessage.value = e return null } @@ -344,12 +355,16 @@ class MainActivityViewModel @Inject constructor( emitSource(ReactiveNetwork().observeInternetConnectivity().asLiveData(Dispatchers.Default)) } - fun updateStatusOfFusedApps(fusedAppList: List, fusedDownloadList: List) { + fun updateStatusOfFusedApps( + fusedAppList: List, + fusedDownloadList: List + ) { fusedAppList.forEach { val downloadingItem = fusedDownloadList.find { fusedDownload -> fusedDownload.origin == it.origin && (fusedDownload.packageName == it.package_name || fusedDownload.id == it._id) } - it.status = downloadingItem?.status ?: fusedAPIRepository.getFusedAppInstallationStatus(it) + it.status = + downloadingItem?.status ?: fusedAPIRepository.getFusedAppInstallationStatus(it) } } } diff --git a/app/src/main/java/foundation/e/apps/applicationlist/model/ApplicationListRVAdapter.kt b/app/src/main/java/foundation/e/apps/applicationlist/model/ApplicationListRVAdapter.kt index b94d70af43631d0471fe4907f2075b0d05d82311..3a559f1375415142aa2c8bc50d80dfd4cf660a0d 100644 --- a/app/src/main/java/foundation/e/apps/applicationlist/model/ApplicationListRVAdapter.kt +++ b/app/src/main/java/foundation/e/apps/applicationlist/model/ApplicationListRVAdapter.kt @@ -26,6 +26,8 @@ import android.view.ViewGroup import android.widget.ImageView import androidx.core.content.ContextCompat import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import androidx.navigation.findNavController import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView @@ -78,7 +80,9 @@ class ApplicationListRVAdapter( .build() inner class ViewHolder(val binding: ApplicationListItemBinding) : - RecyclerView.ViewHolder(binding.root) + RecyclerView.ViewHolder(binding.root) { + var isPurchasedLiveData: LiveData = MutableLiveData() + } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { return ViewHolder( @@ -160,6 +164,7 @@ class ApplicationListRVAdapter( } else -> Log.wtf(TAG, "${searchApp.package_name} is from an unknown origin") } + removeIsPurchasedObserver(holder) when (searchApp.status) { Status.INSTALLED -> { handleInstalled(view, searchApp) @@ -168,7 +173,7 @@ class ApplicationListRVAdapter( handleUpdatable(view, searchApp) } Status.UNAVAILABLE -> { - handleUnavailable(view, searchApp) + handleUnavailable(view, searchApp, holder) } Status.QUEUED, Status.AWAITING, Status.DOWNLOADING -> { handleDownloading(view, searchApp) @@ -188,6 +193,10 @@ class ApplicationListRVAdapter( } } + private fun removeIsPurchasedObserver(holder: ViewHolder) { + holder.isPurchasedLiveData.removeObservers(lifecycleOwner) + } + private fun ApplicationListItemBinding.handleInstallationIssue( view: View, searchApp: FusedApp, @@ -308,9 +317,10 @@ class ApplicationListRVAdapter( private fun ApplicationListItemBinding.handleUnavailable( view: View, searchApp: FusedApp, + holder: ViewHolder, ) { installButton.apply { - updateUIByPaymentType(searchApp, this, this@handleUnavailable) + updateUIByPaymentType(searchApp, this, this@handleUnavailable, holder) setTextColor(context.getColor(R.color.colorAccent)) backgroundTintList = ContextCompat.getColorStateList(view.context, android.R.color.transparent) @@ -331,7 +341,8 @@ class ApplicationListRVAdapter( private fun updateUIByPaymentType( searchApp: FusedApp, materialButton: MaterialButton, - applicationListItemBinding: ApplicationListItemBinding + applicationListItemBinding: ApplicationListItemBinding, + holder: ViewHolder ) { when { mainActivityViewModel.checkUnsupportedApplication(searchApp) -> { @@ -347,7 +358,8 @@ class ApplicationListRVAdapter( materialButton.isEnabled = false materialButton.text = "" applicationListItemBinding.progressBarInstall.visibility = View.VISIBLE - appInfoFetchViewModel.isAppPurchased(searchApp).observe(lifecycleOwner) { + holder.isPurchasedLiveData = appInfoFetchViewModel.isAppPurchased(searchApp) + holder.isPurchasedLiveData.observe(lifecycleOwner) { materialButton.isEnabled = true applicationListItemBinding.progressBarInstall.visibility = View.GONE materialButton.text = diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3e8be04122310c6aa884321c535d07900cc750c1..c5f83dbe66dcd832b83c74f1ed16f4ec2ad6047b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -105,6 +105,8 @@ Unknown Error! There is not enough space available to download this application! Your application was not found. + Something went wrong! + Update All @@ -160,7 +162,10 @@ CONFIRM CANCEL Paid apps cannot be installed in anonymous mode. Please log into your Google account to install paid apps. - + Purchase complete! + Your app will automatically be downloaded in this device + Purchase error! + Unsupported app! The app %s is currently unsupported. This can be because the app is not yet widely released, or there is some other error.