Loading app/src/main/java/foundation/e/apps/data/application/data/Application.kt +29 −5 Original line number Diff line number Diff line /* * Apps Quickly and easily install Android apps onto your device! * Copyright (C) 2021 E FOUNDATION * Copyright (C) 2021-2024 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by Loading @@ -14,17 +13,22 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.data.application.data import android.content.Context import android.net.Uri import com.aurora.gplayapi.Constants.Restriction import com.google.gson.annotations.SerializedName import foundation.e.apps.R import foundation.e.apps.data.enums.FilterLevel import foundation.e.apps.data.enums.Origin import foundation.e.apps.data.enums.Status import foundation.e.apps.data.enums.Type import foundation.e.apps.data.enums.Type.NATIVE import foundation.e.apps.data.enums.Type.PWA import foundation.e.apps.di.CommonUtilsModule.LIST_OF_NULL data class Application( Loading Loading @@ -57,7 +61,7 @@ data class Application( val is_pwa: Boolean = false, var pwaPlayerDbId: Long = -1, val url: String = String(), var type: Type = Type.NATIVE, var type: Type = NATIVE, var privacyScore: Int = -1, var isPurchased: Boolean = false, Loading Loading @@ -94,10 +98,12 @@ data class Application( * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5720 */ var filterLevel: FilterLevel = FilterLevel.UNKNOWN, var isGplayReplaced: Boolean = false var isGplayReplaced: Boolean = false, @SerializedName(value = "on_fdroid") val isFDroidApp: Boolean = false ) { fun updateType() { this.type = if (this.is_pwa) Type.PWA else Type.NATIVE this.type = if (this.is_pwa) PWA else NATIVE } fun updateSource(context: Context) { Loading @@ -108,3 +114,21 @@ data class Application( } } } val Application.shareUri: Uri get() = when (type) { PWA -> Uri.parse(url) NATIVE -> when { isFDroidApp -> buildFDroidUri(package_name) else -> Uri.parse(shareUrl) } } private fun buildFDroidUri(packageName: String): Uri { return Uri.Builder() .scheme("https") .authority("f-droid.org") .appendPath("packages") .appendPath(packageName) .build() } app/src/main/java/foundation/e/apps/ui/application/AppShareIntent.kt 0 → 100644 +46 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.ui.application import android.content.Intent import android.net.Uri object AppShareIntent { fun create(appName: String, appShareUri: Uri): Intent { val extraText = "$appName \n$appShareUri" val uriIntent = Intent(Intent.ACTION_SEND).apply { setData(appShareUri) putExtra(Intent.EXTRA_TITLE, appName) } val textIntent = Intent(Intent.ACTION_SEND).apply { setType("text/plain") putExtra(Intent.EXTRA_SUBJECT, appName) putExtra(Intent.EXTRA_TITLE, appName) putExtra(Intent.EXTRA_TEXT, extraText) } val shareIntent = Intent(textIntent).apply { putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayOf(uriIntent)) } return shareIntent } } app/src/main/java/foundation/e/apps/ui/application/ApplicationFragment.kt +37 −6 Original line number Diff line number Diff line /* * Apps Quickly and easily install Android apps onto your device! * Copyright (C) 2021 E FOUNDATION * Copyright (C) 2021-2024 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by Loading @@ -14,6 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.ui.application Loading @@ -35,7 +35,9 @@ import androidx.core.graphics.BlendModeCompat import androidx.core.view.isVisible import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.navigation.findNavController import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs Loading @@ -47,32 +49,37 @@ import com.google.android.material.textview.MaterialTextView import dagger.hilt.android.AndroidEntryPoint import foundation.e.apps.MainActivity import foundation.e.apps.R import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.application.data.shareUri import foundation.e.apps.data.cleanapk.CleanApkRetrofit import foundation.e.apps.data.enums.Origin import foundation.e.apps.data.enums.ResultStatus import foundation.e.apps.data.enums.Status import foundation.e.apps.data.enums.User import foundation.e.apps.data.enums.isInitialized import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.login.AuthObject import foundation.e.apps.data.login.exceptions.GPlayLoginException import foundation.e.apps.databinding.FragmentApplicationBinding import foundation.e.apps.di.CommonUtilsModule.LIST_OF_NULL import foundation.e.apps.install.download.data.DownloadProgress import foundation.e.apps.install.pkg.PWAManager import foundation.e.apps.install.pkg.AppLoungePackageManager import foundation.e.apps.install.pkg.PWAManager import foundation.e.apps.ui.AppInfoFetchViewModel import foundation.e.apps.ui.MainActivityViewModel import foundation.e.apps.ui.PrivacyInfoViewModel import foundation.e.apps.ui.application.ShareButtonVisibilityState.Hidden import foundation.e.apps.ui.application.ShareButtonVisibilityState.Visible import foundation.e.apps.ui.application.model.ApplicationScreenshotsRVAdapter import foundation.e.apps.ui.application.subFrags.ApplicationDialogFragment import foundation.e.apps.ui.parentFragment.TimeoutFragment import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch import timber.log.Timber import java.util.Locale import javax.inject.Inject @AndroidEntryPoint class ApplicationFragment : TimeoutFragment(R.layout.fragment_application) { Loading Loading @@ -218,6 +225,8 @@ class ApplicationFragment : TimeoutFragment(R.layout.fragment_application) { observeDownloadList() observeDownloadStatus(binding.root) stopLoadingUI() collectShareVisibilityState() } private fun showWarningMessage(it: Application) { Loading Loading @@ -445,6 +454,27 @@ class ApplicationFragment : TimeoutFragment(R.layout.fragment_application) { view.findNavController().navigateUp() } } binding.actionShare.setOnClickListener { openShareSheet() } } private fun openShareSheet() { val application = applicationViewModel.application.value?.first ?: return val shareIntent = AppShareIntent.create(application.name, application.shareUri) startActivity(Intent.createChooser(shareIntent, null)) } private fun collectShareVisibilityState() { lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.RESUMED) { applicationViewModel.shareButtonVisibilityState.collectLatest { state -> when (state) { Hidden -> binding.actionShare.visibility = View.GONE Visible -> binding.actionShare.visibility = View.VISIBLE } } } } } override fun loadData(authObjectList: List<AuthObject>) { Loading Loading @@ -780,7 +810,8 @@ class ApplicationFragment : TimeoutFragment(R.layout.fragment_application) { if (application.is_pwa) { pwaManager.launchPwa(application) } else { val launchIntent = appLoungePackageManager.getLaunchIntent(application.package_name) val launchIntent = appLoungePackageManager.getLaunchIntent(application.package_name) launchIntent?.run { startActivity(this) } } } Loading app/src/main/java/foundation/e/apps/ui/application/ApplicationViewModel.kt +30 −5 Original line number Diff line number Diff line /* * Apps Quickly and easily install Android apps onto your device! * Copyright (C) 2021 E FOUNDATION * Copyright (C) 2021-2024 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by Loading @@ -14,6 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.ui.application Loading @@ -24,11 +24,12 @@ import com.aurora.gplayapi.data.models.AuthData import com.aurora.gplayapi.exceptions.ApiException import dagger.hilt.android.lifecycle.HiltViewModel import foundation.e.apps.R import foundation.e.apps.data.application.ApplicationRepository import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.application.data.shareUri import foundation.e.apps.data.enums.Origin import foundation.e.apps.data.enums.ResultStatus import foundation.e.apps.data.enums.Status import foundation.e.apps.data.application.ApplicationRepository import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.fusedDownload.FusedManagerRepository import foundation.e.apps.data.fusedDownload.models.FusedDownload import foundation.e.apps.data.login.AuthObject Loading @@ -36,8 +37,12 @@ import foundation.e.apps.data.login.exceptions.CleanApkException import foundation.e.apps.data.login.exceptions.GPlayException import foundation.e.apps.install.download.data.DownloadProgress import foundation.e.apps.install.download.data.DownloadProgressLD import foundation.e.apps.ui.application.ShareButtonVisibilityState.Hidden import foundation.e.apps.ui.application.ShareButtonVisibilityState.Visible import foundation.e.apps.ui.parentFragment.LoadingViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import javax.inject.Inject Loading @@ -54,6 +59,9 @@ class ApplicationViewModel @Inject constructor( private val _errorMessageLiveData: MutableLiveData<Int> = MutableLiveData() val errorMessageLiveData: MutableLiveData<Int> = _errorMessageLiveData private val _shareButtonVisibilityState = MutableStateFlow<ShareButtonVisibilityState>(Hidden) val shareButtonVisibilityState = _shareButtonVisibilityState.asStateFlow() fun loadData( id: String, packageName: String, Loading Loading @@ -105,6 +113,8 @@ class ApplicationViewModel @Inject constructor( ) application.postValue(appData) updateShareVisibilityState(appData.first.shareUri.toString()) val status = appData.second if (appData.second != ResultStatus.OK) { Loading @@ -130,6 +140,11 @@ class ApplicationViewModel @Inject constructor( } } private fun updateShareVisibilityState(shareUri: String) { val isValidUri = shareUri.isNotBlank() _shareButtonVisibilityState.value = if (isValidUri) Visible else Hidden } /* * Dedicated method to get app details from cleanapk using package name. * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5509 Loading @@ -142,6 +157,7 @@ class ApplicationViewModel @Inject constructor( _errorMessageLiveData.postValue(R.string.app_not_found) } else { application.postValue(this) updateShareVisibilityState(first.shareUri.toString()) } } } catch (e: Exception) { Loading Loading @@ -170,12 +186,16 @@ class ApplicationViewModel @Inject constructor( fun getFusedApp(): Application? { return application.value?.first } fun handleRatingFormat(rating: Double): String { return fusedManagerRepository.handleRatingFormat(rating) } suspend fun calculateProgress(progress: DownloadProgress): Pair<Long, Long> { return fusedManagerRepository.getCalculateProgressWithTotalSize(application.value?.first, progress) return fusedManagerRepository.getCalculateProgressWithTotalSize( application.value?.first, progress ) } fun updateApplicationStatus(downloadList: List<FusedDownload>) { Loading @@ -187,3 +207,8 @@ class ApplicationViewModel @Inject constructor( fun isOpenSourceSelected() = applicationRepository.isOpenSourceSelected() } sealed class ShareButtonVisibilityState { object Visible : ShareButtonVisibilityState() object Hidden : ShareButtonVisibilityState() } app/src/main/res/drawable/ic_share.xml 0 → 100644 +28 −0 Original line number Diff line number Diff line <!-- ~ Copyright (C) 2024 MURENA SAS ~ ~ This program is free software: you can redistribute it and/or modify ~ it under the terms of the GNU General Public License as published by ~ the Free Software Foundation, either version 3 of the License, or ~ (at your option) any later version. ~ ~ This program is distributed in the hope that it will be useful, ~ but WITHOUT ANY WARRANTY; without even the implied warranty of ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ~ GNU General Public License for more details. ~ ~ You should have received a copy of the GNU General Public License ~ along with this program. If not, see <https://www.gnu.org/licenses/>. ~ --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:pathData="M18,16.08C17.24,16.08 16.56,16.38 16.04,16.85L8.91,12.7C8.96,12.47 9,12.24 9,12C9,11.76 8.96,11.53 8.91,11.3L15.96,7.19C16.5,7.69 17.21,8 18,8C19.66,8 21,6.66 21,5C21,3.34 19.66,2 18,2C16.34,2 15,3.34 15,5C15,5.24 15.04,5.47 15.09,5.7L8.04,9.81C7.5,9.31 6.79,9 6,9C4.34,9 3,10.34 3,12C3,13.66 4.34,15 6,15C6.79,15 7.5,14.69 8.04,14.19L15.16,18.35C15.11,18.56 15.08,18.78 15.08,19C15.08,20.61 16.39,21.92 18,21.92C19.61,21.92 20.92,20.61 20.92,19C20.92,17.39 19.61,16.08 18,16.08Z" android:fillColor="#000000" android:fillType="evenOdd"/> </vector> Loading
app/src/main/java/foundation/e/apps/data/application/data/Application.kt +29 −5 Original line number Diff line number Diff line /* * Apps Quickly and easily install Android apps onto your device! * Copyright (C) 2021 E FOUNDATION * Copyright (C) 2021-2024 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by Loading @@ -14,17 +13,22 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.data.application.data import android.content.Context import android.net.Uri import com.aurora.gplayapi.Constants.Restriction import com.google.gson.annotations.SerializedName import foundation.e.apps.R import foundation.e.apps.data.enums.FilterLevel import foundation.e.apps.data.enums.Origin import foundation.e.apps.data.enums.Status import foundation.e.apps.data.enums.Type import foundation.e.apps.data.enums.Type.NATIVE import foundation.e.apps.data.enums.Type.PWA import foundation.e.apps.di.CommonUtilsModule.LIST_OF_NULL data class Application( Loading Loading @@ -57,7 +61,7 @@ data class Application( val is_pwa: Boolean = false, var pwaPlayerDbId: Long = -1, val url: String = String(), var type: Type = Type.NATIVE, var type: Type = NATIVE, var privacyScore: Int = -1, var isPurchased: Boolean = false, Loading Loading @@ -94,10 +98,12 @@ data class Application( * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5720 */ var filterLevel: FilterLevel = FilterLevel.UNKNOWN, var isGplayReplaced: Boolean = false var isGplayReplaced: Boolean = false, @SerializedName(value = "on_fdroid") val isFDroidApp: Boolean = false ) { fun updateType() { this.type = if (this.is_pwa) Type.PWA else Type.NATIVE this.type = if (this.is_pwa) PWA else NATIVE } fun updateSource(context: Context) { Loading @@ -108,3 +114,21 @@ data class Application( } } } val Application.shareUri: Uri get() = when (type) { PWA -> Uri.parse(url) NATIVE -> when { isFDroidApp -> buildFDroidUri(package_name) else -> Uri.parse(shareUrl) } } private fun buildFDroidUri(packageName: String): Uri { return Uri.Builder() .scheme("https") .authority("f-droid.org") .appendPath("packages") .appendPath(packageName) .build() }
app/src/main/java/foundation/e/apps/ui/application/AppShareIntent.kt 0 → 100644 +46 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.ui.application import android.content.Intent import android.net.Uri object AppShareIntent { fun create(appName: String, appShareUri: Uri): Intent { val extraText = "$appName \n$appShareUri" val uriIntent = Intent(Intent.ACTION_SEND).apply { setData(appShareUri) putExtra(Intent.EXTRA_TITLE, appName) } val textIntent = Intent(Intent.ACTION_SEND).apply { setType("text/plain") putExtra(Intent.EXTRA_SUBJECT, appName) putExtra(Intent.EXTRA_TITLE, appName) putExtra(Intent.EXTRA_TEXT, extraText) } val shareIntent = Intent(textIntent).apply { putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayOf(uriIntent)) } return shareIntent } }
app/src/main/java/foundation/e/apps/ui/application/ApplicationFragment.kt +37 −6 Original line number Diff line number Diff line /* * Apps Quickly and easily install Android apps onto your device! * Copyright (C) 2021 E FOUNDATION * Copyright (C) 2021-2024 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by Loading @@ -14,6 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.ui.application Loading @@ -35,7 +35,9 @@ import androidx.core.graphics.BlendModeCompat import androidx.core.view.isVisible import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.navigation.findNavController import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs Loading @@ -47,32 +49,37 @@ import com.google.android.material.textview.MaterialTextView import dagger.hilt.android.AndroidEntryPoint import foundation.e.apps.MainActivity import foundation.e.apps.R import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.application.data.shareUri import foundation.e.apps.data.cleanapk.CleanApkRetrofit import foundation.e.apps.data.enums.Origin import foundation.e.apps.data.enums.ResultStatus import foundation.e.apps.data.enums.Status import foundation.e.apps.data.enums.User import foundation.e.apps.data.enums.isInitialized import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.login.AuthObject import foundation.e.apps.data.login.exceptions.GPlayLoginException import foundation.e.apps.databinding.FragmentApplicationBinding import foundation.e.apps.di.CommonUtilsModule.LIST_OF_NULL import foundation.e.apps.install.download.data.DownloadProgress import foundation.e.apps.install.pkg.PWAManager import foundation.e.apps.install.pkg.AppLoungePackageManager import foundation.e.apps.install.pkg.PWAManager import foundation.e.apps.ui.AppInfoFetchViewModel import foundation.e.apps.ui.MainActivityViewModel import foundation.e.apps.ui.PrivacyInfoViewModel import foundation.e.apps.ui.application.ShareButtonVisibilityState.Hidden import foundation.e.apps.ui.application.ShareButtonVisibilityState.Visible import foundation.e.apps.ui.application.model.ApplicationScreenshotsRVAdapter import foundation.e.apps.ui.application.subFrags.ApplicationDialogFragment import foundation.e.apps.ui.parentFragment.TimeoutFragment import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch import timber.log.Timber import java.util.Locale import javax.inject.Inject @AndroidEntryPoint class ApplicationFragment : TimeoutFragment(R.layout.fragment_application) { Loading Loading @@ -218,6 +225,8 @@ class ApplicationFragment : TimeoutFragment(R.layout.fragment_application) { observeDownloadList() observeDownloadStatus(binding.root) stopLoadingUI() collectShareVisibilityState() } private fun showWarningMessage(it: Application) { Loading Loading @@ -445,6 +454,27 @@ class ApplicationFragment : TimeoutFragment(R.layout.fragment_application) { view.findNavController().navigateUp() } } binding.actionShare.setOnClickListener { openShareSheet() } } private fun openShareSheet() { val application = applicationViewModel.application.value?.first ?: return val shareIntent = AppShareIntent.create(application.name, application.shareUri) startActivity(Intent.createChooser(shareIntent, null)) } private fun collectShareVisibilityState() { lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.RESUMED) { applicationViewModel.shareButtonVisibilityState.collectLatest { state -> when (state) { Hidden -> binding.actionShare.visibility = View.GONE Visible -> binding.actionShare.visibility = View.VISIBLE } } } } } override fun loadData(authObjectList: List<AuthObject>) { Loading Loading @@ -780,7 +810,8 @@ class ApplicationFragment : TimeoutFragment(R.layout.fragment_application) { if (application.is_pwa) { pwaManager.launchPwa(application) } else { val launchIntent = appLoungePackageManager.getLaunchIntent(application.package_name) val launchIntent = appLoungePackageManager.getLaunchIntent(application.package_name) launchIntent?.run { startActivity(this) } } } Loading
app/src/main/java/foundation/e/apps/ui/application/ApplicationViewModel.kt +30 −5 Original line number Diff line number Diff line /* * Apps Quickly and easily install Android apps onto your device! * Copyright (C) 2021 E FOUNDATION * Copyright (C) 2021-2024 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by Loading @@ -14,6 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.ui.application Loading @@ -24,11 +24,12 @@ import com.aurora.gplayapi.data.models.AuthData import com.aurora.gplayapi.exceptions.ApiException import dagger.hilt.android.lifecycle.HiltViewModel import foundation.e.apps.R import foundation.e.apps.data.application.ApplicationRepository import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.application.data.shareUri import foundation.e.apps.data.enums.Origin import foundation.e.apps.data.enums.ResultStatus import foundation.e.apps.data.enums.Status import foundation.e.apps.data.application.ApplicationRepository import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.fusedDownload.FusedManagerRepository import foundation.e.apps.data.fusedDownload.models.FusedDownload import foundation.e.apps.data.login.AuthObject Loading @@ -36,8 +37,12 @@ import foundation.e.apps.data.login.exceptions.CleanApkException import foundation.e.apps.data.login.exceptions.GPlayException import foundation.e.apps.install.download.data.DownloadProgress import foundation.e.apps.install.download.data.DownloadProgressLD import foundation.e.apps.ui.application.ShareButtonVisibilityState.Hidden import foundation.e.apps.ui.application.ShareButtonVisibilityState.Visible import foundation.e.apps.ui.parentFragment.LoadingViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import javax.inject.Inject Loading @@ -54,6 +59,9 @@ class ApplicationViewModel @Inject constructor( private val _errorMessageLiveData: MutableLiveData<Int> = MutableLiveData() val errorMessageLiveData: MutableLiveData<Int> = _errorMessageLiveData private val _shareButtonVisibilityState = MutableStateFlow<ShareButtonVisibilityState>(Hidden) val shareButtonVisibilityState = _shareButtonVisibilityState.asStateFlow() fun loadData( id: String, packageName: String, Loading Loading @@ -105,6 +113,8 @@ class ApplicationViewModel @Inject constructor( ) application.postValue(appData) updateShareVisibilityState(appData.first.shareUri.toString()) val status = appData.second if (appData.second != ResultStatus.OK) { Loading @@ -130,6 +140,11 @@ class ApplicationViewModel @Inject constructor( } } private fun updateShareVisibilityState(shareUri: String) { val isValidUri = shareUri.isNotBlank() _shareButtonVisibilityState.value = if (isValidUri) Visible else Hidden } /* * Dedicated method to get app details from cleanapk using package name. * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5509 Loading @@ -142,6 +157,7 @@ class ApplicationViewModel @Inject constructor( _errorMessageLiveData.postValue(R.string.app_not_found) } else { application.postValue(this) updateShareVisibilityState(first.shareUri.toString()) } } } catch (e: Exception) { Loading Loading @@ -170,12 +186,16 @@ class ApplicationViewModel @Inject constructor( fun getFusedApp(): Application? { return application.value?.first } fun handleRatingFormat(rating: Double): String { return fusedManagerRepository.handleRatingFormat(rating) } suspend fun calculateProgress(progress: DownloadProgress): Pair<Long, Long> { return fusedManagerRepository.getCalculateProgressWithTotalSize(application.value?.first, progress) return fusedManagerRepository.getCalculateProgressWithTotalSize( application.value?.first, progress ) } fun updateApplicationStatus(downloadList: List<FusedDownload>) { Loading @@ -187,3 +207,8 @@ class ApplicationViewModel @Inject constructor( fun isOpenSourceSelected() = applicationRepository.isOpenSourceSelected() } sealed class ShareButtonVisibilityState { object Visible : ShareButtonVisibilityState() object Hidden : ShareButtonVisibilityState() }
app/src/main/res/drawable/ic_share.xml 0 → 100644 +28 −0 Original line number Diff line number Diff line <!-- ~ Copyright (C) 2024 MURENA SAS ~ ~ This program is free software: you can redistribute it and/or modify ~ it under the terms of the GNU General Public License as published by ~ the Free Software Foundation, either version 3 of the License, or ~ (at your option) any later version. ~ ~ This program is distributed in the hope that it will be useful, ~ but WITHOUT ANY WARRANTY; without even the implied warranty of ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ~ GNU General Public License for more details. ~ ~ You should have received a copy of the GNU General Public License ~ along with this program. If not, see <https://www.gnu.org/licenses/>. ~ --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:pathData="M18,16.08C17.24,16.08 16.56,16.38 16.04,16.85L8.91,12.7C8.96,12.47 9,12.24 9,12C9,11.76 8.96,11.53 8.91,11.3L15.96,7.19C16.5,7.69 17.21,8 18,8C19.66,8 21,6.66 21,5C21,3.34 19.66,2 18,2C16.34,2 15,3.34 15,5C15,5.24 15.04,5.47 15.09,5.7L8.04,9.81C7.5,9.31 6.79,9 6,9C4.34,9 3,10.34 3,12C3,13.66 4.34,15 6,15C6.79,15 7.5,14.69 8.04,14.19L15.16,18.35C15.11,18.56 15.08,18.78 15.08,19C15.08,20.61 16.39,21.92 18,21.92C19.61,21.92 20.92,20.61 20.92,19C20.92,17.39 19.61,16.08 18,16.08Z" android:fillColor="#000000" android:fillType="evenOdd"/> </vector>