From 01c11de5679206199b62398980f29bc15b5a92c2 Mon Sep 17 00:00:00 2001 From: Philip Magyar Date: Wed, 21 Aug 2024 08:49:11 +0200 Subject: [PATCH 1/5] Auto-switch to google wallet when power menu is open --- QuickAccessWallet/build.gradle | 4 ++-- app/src/main/AndroidManifest.xml | 1 + .../service/root/impl/CPMRootServiceImpl.kt | 7 +++++++ .../ui/screens/powermenu/main/PowerMenuFragment.kt | 11 ++++++++--- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/QuickAccessWallet/build.gradle b/QuickAccessWallet/build.gradle index f142e94..37ce5ed 100644 --- a/QuickAccessWallet/build.gradle +++ b/QuickAccessWallet/build.gradle @@ -4,11 +4,11 @@ plugins { } android { - compileSdk 31 + compileSdk 34 defaultConfig { minSdk 30 - targetSdk 31 + targetSdk 34 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 662bfc0..d7a544d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ xmlns:tools="http://schemas.android.com/tools"> + = Build.VERSION_CODES.TIRAMISU) { + Runtime.getRuntime().exec("pm grant ${BuildConfig.APPLICATION_ID} ${Manifest.permission.WRITE_SECURE_SETTINGS}") + } + } + init { grantNotificationPermission() grantAccessibilityPermission() + grantSecureSettingsPermission() } } \ No newline at end of file diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/powermenu/main/PowerMenuFragment.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/powermenu/main/PowerMenuFragment.kt index 9961c77..0b68e86 100644 --- a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/powermenu/main/PowerMenuFragment.kt +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/powermenu/main/PowerMenuFragment.kt @@ -6,11 +6,11 @@ import android.content.Context import android.content.res.ColorStateList import android.graphics.drawable.ColorDrawable import android.os.Bundle +import android.provider.Settings import android.service.quickaccesswallet.CPMQuickAccessWalletClientImpl -import android.view.Surface +import android.util.Log import android.view.View import androidx.core.graphics.ColorUtils -import androidx.core.view.DisplayCutoutCompat import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.updatePadding @@ -32,7 +32,6 @@ import com.kieronquinn.app.classicpowermenu.model.power.PowerMenuContentItem import com.kieronquinn.app.classicpowermenu.service.container.CPMServiceContainer import com.kieronquinn.app.classicpowermenu.ui.base.BoundFragment import com.kieronquinn.app.classicpowermenu.utils.extensions.* -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.launch @@ -122,6 +121,7 @@ class PowerMenuFragment : setupAppbar() setupSecondaryAlpha() setupInsets(view) + changeDefaultPaymentMethod() } override fun onStop() { @@ -129,6 +129,11 @@ class PowerMenuFragment : contentAdapter?.controlsUiController?.hide() } + private fun changeDefaultPaymentMethod() { + val googlePay = "com.google.android.gms/com.google.android.gms.tapandpay.hce.service.TpHceService" + Settings.Secure.putString(powerMenuApplication.contentResolver, "nfc_payment_default_component", googlePay) + } + private fun setupInsets(view: View) { ViewCompat.setOnApplyWindowInsetsListener(view) { _, insets -> val cutout = insets.displayCutout From 00041420904f59de2e701bd02a9e2286b47f1cdd Mon Sep 17 00:00:00 2001 From: Philip Magyar Date: Thu, 22 Aug 2024 22:23:05 +0200 Subject: [PATCH 2/5] make payment service switch optional, ability to change service for payment service switch, try catch for putString on secure setting --- .../AutoSwitchServicesRepository.kt | 107 ++++++++++++++++++ .../placeholder/PlaceholderContent.kt | 57 ++++++++++ ...ickAccessWalletAutoSwitchServiceAdapter.kt | 52 +++++++++ ...ckAccessWalletAutoSwitchServiceFragment.kt | 98 ++++++++++++++++ ...kAccessWalletAutoSwitchServiceViewModel.kt | 76 +++++++++++++ ...uick_access_wallet_auto_switch_service.xml | 54 +++++++++ .../item_wallet_select_service_card.xml | 87 ++++++++++++++ 7 files changed, 531 insertions(+) create mode 100644 app/src/main/java/com/kieronquinn/app/classicpowermenu/components/quickaccesswallet/autoswitch/AutoSwitchServicesRepository.kt create mode 100644 app/src/main/java/com/kieronquinn/app/classicpowermenu/placeholder/PlaceholderContent.kt create mode 100644 app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceAdapter.kt create mode 100644 app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceFragment.kt create mode 100644 app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceViewModel.kt create mode 100644 app/src/main/res/layout/fragment_settings_quick_access_wallet_auto_switch_service.xml create mode 100644 app/src/main/res/layout/item_wallet_select_service_card.xml diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/components/quickaccesswallet/autoswitch/AutoSwitchServicesRepository.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/components/quickaccesswallet/autoswitch/AutoSwitchServicesRepository.kt new file mode 100644 index 0000000..ca9b7c5 --- /dev/null +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/components/quickaccesswallet/autoswitch/AutoSwitchServicesRepository.kt @@ -0,0 +1,107 @@ +package com.kieronquinn.app.classicpowermenu.components.quickaccesswallet.loyaltycards + +import android.content.Context +import android.database.sqlite.SQLiteDatabase +import android.graphics.BitmapFactory +import android.graphics.drawable.BitmapDrawable +import android.os.ParcelFileDescriptor +import android.util.Log +import androidx.core.content.res.ResourcesCompat +import com.android.systemui.plugin.globalactions.wallet.WalletCardViewInfo +import com.kieronquinn.app.classicpowermenu.IClassicPowerMenu +import com.kieronquinn.app.classicpowermenu.R +import com.kieronquinn.app.classicpowermenu.components.quickaccesswallet.GooglePayConstants +import com.kieronquinn.app.classicpowermenu.components.settings.Settings +import com.kieronquinn.app.classicpowermenu.model.protobuf.loyaltycard.LoyaltyCardProtos +import com.kieronquinn.app.classicpowermenu.model.quickaccesswallet.LoyaltyCard +import com.kieronquinn.app.classicpowermenu.model.quickaccesswallet.WalletLoyaltyCardViewInfo +import com.kieronquinn.app.classicpowermenu.model.quickaccesswallet.extract +import com.kieronquinn.app.classicpowermenu.service.container.CPMServiceContainer +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import java.io.File +import java.util.* +import kotlin.collections.ArrayList +import kotlin.collections.HashMap + +interface LoyaltyCardsRepository { + + suspend fun getLoyaltyCards(onCardClicked: (LoyaltyCard) -> Boolean, ignoreSetting: Boolean = false): List? + +} + +class LoyaltyCardsRepositoryImpl(private val service: CPMServiceContainer, private val context: Context, private val settings: Settings): LoyaltyCardsRepository { + + private val isGooglePayInstalled by lazy { + GooglePayConstants.isGooglePayInstalled(context.packageManager) + } + + private val googleSansMedium by lazy { + ResourcesCompat.getFont(context, R.font.google_sans_text_medium)!! + } + + override suspend fun getLoyaltyCards(onCardClicked: (LoyaltyCard) -> Boolean, ignoreSetting: Boolean): List? { + if((!settings.quickAccessWalletShowLoyaltyCards && !ignoreSetting) || !isGooglePayInstalled) return null + return service.runWithService { service -> + withContext(Dispatchers.IO) { + context.withTemporaryFile { + service.googlePayDatabaseForLoyalty?.loadRemoteFile(it) ?: return@withTemporaryFile null + val database = SQLiteDatabase.openOrCreateDatabase(it, null) + val valuableImageFileNames = getValuableImageList(database) + getValuables(database, valuableImageFileNames, service) + } + } + }?.map { WalletLoyaltyCardViewInfo(context, it, googleSansMedium, onCardClicked) } + } + + private fun getValuableImageList(database: SQLiteDatabase): HashMap { + val valuableImageFileNames = HashMap() + val valuableImagesCursor = database.rawQuery("select valuable_id,file_name from valuable_images", null, null) + valuableImagesCursor.moveToFirst() + if(valuableImagesCursor.isAfterLast) return valuableImageFileNames + do { + if(valuableImagesCursor.isAfterLast) break + valuableImageFileNames[valuableImagesCursor.getString(0)] = valuableImagesCursor.getString(1) + }while (valuableImagesCursor.moveToNext()) + valuableImagesCursor.close() + return valuableImageFileNames + } + + private fun getValuables(database: SQLiteDatabase, valuableImageFileNames: HashMap, service: IClassicPowerMenu): ArrayList { + val loyaltyCards = ArrayList() + //Vertical ID 1 = LOYALTY_CARD (See CommonProto.ValuableType in Google Pay) + val cursor = database.rawQuery("select valuable_id,proto from valuables where vertical_id='1'", null, null) + cursor.moveToFirst() + if(cursor.isAfterLast) return loyaltyCards + do { + if(cursor.isAfterLast) break + val valuableId = cursor.getString(0) + val valuableIcon = valuableImageFileNames[valuableId]?.let { valuableImageFileName -> + val bitmap = context.withTemporaryFile { + service.getGooglePayLoyaltyImageForId(valuableImageFileName)?.loadRemoteFile(it) ?: return@withTemporaryFile null + BitmapFactory.decodeFile(it.absolutePath) + } + bitmap + } + val blob = cursor.getBlob(1) + val loyaltyCard = LoyaltyCardProtos.LoyaltyCard.parseFrom(blob) + loyaltyCards.add(loyaltyCard.extract(valuableIcon, context)) + } while (cursor.moveToNext()) + cursor.close() + return loyaltyCards + } + + private fun ParcelFileDescriptor.loadRemoteFile(into: File){ + ParcelFileDescriptor.AutoCloseInputStream(this).buffered().use { stream -> + stream.copyTo(into.outputStream()) + } + } + + private fun Context.withTemporaryFile(block: (File) -> T): T { + val file = File(cacheDir, UUID.randomUUID().toString()) + val result = block.invoke(file) + file.delete() + return result + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/placeholder/PlaceholderContent.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/placeholder/PlaceholderContent.kt new file mode 100644 index 0000000..f4aa43f --- /dev/null +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/placeholder/PlaceholderContent.kt @@ -0,0 +1,57 @@ +package com.kieronquinn.app.classicpowermenu.placeholder + +import java.util.ArrayList +import java.util.HashMap + +/** + * Helper class for providing sample content for user interfaces created by + * Android template wizards. + * + * TODO: Replace all uses of this class before publishing your app. + */ +object PlaceholderContent { + + /** + * An array of sample (placeholder) items. + */ + val ITEMS: MutableList = ArrayList() + + /** + * A map of sample (placeholder) items, by ID. + */ + val ITEM_MAP: MutableMap = HashMap() + + private val COUNT = 25 + + init { + // Add some sample items. + for (i in 1..COUNT) { + addItem(createPlaceholderItem(i)) + } + } + + private fun addItem(item: PlaceholderItem) { + ITEMS.add(item) + ITEM_MAP.put(item.id, item) + } + + private fun createPlaceholderItem(position: Int): PlaceholderItem { + return PlaceholderItem(position.toString(), "Item " + position, makeDetails(position)) + } + + private fun makeDetails(position: Int): String { + val builder = StringBuilder() + builder.append("Details about Item: ").append(position) + for (i in 0..position - 1) { + builder.append("\nMore details information here.") + } + return builder.toString() + } + + /** + * A placeholder item representing a piece of content. + */ + data class PlaceholderItem(val id: String, val content: String, val details: String) { + override fun toString(): String = content + } +} \ No newline at end of file diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceAdapter.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceAdapter.kt new file mode 100644 index 0000000..09f43e3 --- /dev/null +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceAdapter.kt @@ -0,0 +1,52 @@ +package com.kieronquinn.app.classicpowermenu.ui.screens.settings.quickaccesswallet.autoswitch + +import android.content.Context +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.kieronquinn.app.classicpowermenu.databinding.ItemWalletSelectServiceCardBinding +import com.kieronquinn.monetcompat.core.MonetCompat + +class SettingsQuickAccessWalletChangeDefaultPaymentMethodAdapter(context: Context, var cards: List, val onServiceClicked: (SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModel.SelectAutoSwitchService) -> Unit): RecyclerView.Adapter() { + + init { + setHasStableIds(true) + } + + private val monet by lazy { + MonetCompat.getInstance() + } + + private val layoutInflater by lazy { + context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater + } + + override fun getItemId(position: Int): Long { + return cards[position].componentName.hashCode().toLong() + } + + override fun getItemCount() = cards.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder(ItemWalletSelectServiceCardBinding.inflate(layoutInflater, parent, false)) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val item = cards[position] + with(holder.binding){ + walletSelectServiceCardTitle.text = item.name + walletSelectServiceCardText.text = item.componentName + walletSelectServiceCardImage.clipToOutline = true + walletSelectServiceCardImage.setImageDrawable(item.image) + } + + if (item.selected) holder.itemView.setBackgroundColor(monet.getSecondaryColor(holder.itemView.context)) + + holder.itemView.setOnClickListener { + onServiceClicked(item) + } + } + + data class ViewHolder(val binding: ItemWalletSelectServiceCardBinding): RecyclerView.ViewHolder(binding.root) + +} \ No newline at end of file diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceFragment.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceFragment.kt new file mode 100644 index 0000000..9a0c674 --- /dev/null +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceFragment.kt @@ -0,0 +1,98 @@ +package com.kieronquinn.app.classicpowermenu.ui.screens.settings.quickaccesswallet.autoswitch + +import android.os.Bundle +import android.view.View +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.isVisible +import androidx.core.view.updatePadding +import androidx.lifecycle.lifecycleScope +import androidx.recyclerview.widget.LinearLayoutManager +import com.kieronquinn.app.classicpowermenu.R +import com.kieronquinn.app.classicpowermenu.databinding.FragmentSettingsQuickAccessWalletChangeDefaultPaymentMethodBinding +import com.kieronquinn.app.classicpowermenu.ui.base.BoundFragment +import com.kieronquinn.app.classicpowermenu.ui.base.StandaloneFragment +import com.kieronquinn.app.classicpowermenu.utils.extensions.onApplyInsets +import com.kieronquinn.monetcompat.extensions.views.applyMonet +import org.koin.androidx.viewmodel.ext.android.viewModel + +class SettingsQuickAccessWalletChangeDefaultPaymentMethodFragment: BoundFragment(FragmentSettingsQuickAccessWalletChangeDefaultPaymentMethodBinding::inflate), StandaloneFragment { + + private val adapter by lazy { + SettingsQuickAccessWalletChangeDefaultPaymentMethodAdapter(requireContext(), emptyList(), viewModel::onServiceClicked) + } + + private val viewModel by viewModel() + + override val onBackPressed by lazy { + return@lazy viewModel::onBackPressed + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupToolbar() + setupRecyclerView() + setupState() + setupMonet() + setupInsets() + } + + private fun setupState() = lifecycleScope.launchWhenResumed { + viewModel.state.collect { + handleState(it) + } + } + + private fun handleState(state: SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModel.State){ + when(state){ + is SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModel.State.Loading -> { + binding.quickAccessWalletChangeDefaultPaymentMethodRecyclerview.isVisible = false + binding.quickAccessWalletAutoSwitchServiceLoading.isVisible = true + } + is SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModel.State.Error -> { + //binding.quickAccessWalletRearrangeRecyclerview.isVisible = false + //binding.quickAccessWalletRearrangeEmpty.isVisible = true + //binding.quickAccessWalletRearrangeEmptyText.setText(state.type.contentRes) + //binding.quickAccessWalletRearrangeLoading.isVisible = false + } + is SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModel.State.Loaded -> { + binding.quickAccessWalletChangeDefaultPaymentMethodRecyclerview.isVisible = true + binding.quickAccessWalletAutoSwitchServiceLoading.isVisible = false + adapter.cards = state.services + } + } + } + + + + private fun setupToolbar(){ + with(binding.toolbar){ + setupWithScrollableView(binding.quickAccessWalletChangeDefaultPaymentMethodRecyclerview) + setNavigationOnClickListener { + viewModel.onBackPressed() + } + } + } + + private fun setupRecyclerView() = with(binding.quickAccessWalletChangeDefaultPaymentMethodRecyclerview) { + layoutManager = LinearLayoutManager(context) + adapter = this@SettingsQuickAccessWalletChangeDefaultPaymentMethodFragment.adapter + } + + private fun setupMonet(){ + binding.root.setBackgroundColor(monet.getBackgroundColor(requireContext())) + binding.quickAccessWalletAutoSwitchServiceLoadingBar.applyMonet() + } + + private fun setupInsets(){ + binding.toolbar.onApplyInsets { view, insets -> + val topInset = insets.getInsets(WindowInsetsCompat.Type.statusBars()).top + view.updatePadding(top = topInset) + } + binding.quickAccessWalletChangeDefaultPaymentMethodRecyclerview.onApplyInsets { view, insets -> + val bottomPadding = resources.getDimension(R.dimen.margin_16).toInt() + val bottomInset = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom + view.updatePadding(bottom = bottomPadding + bottomInset) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceViewModel.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceViewModel.kt new file mode 100644 index 0000000..6cae8de --- /dev/null +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceViewModel.kt @@ -0,0 +1,76 @@ +package com.kieronquinn.app.classicpowermenu.ui.screens.settings.quickaccesswallet.autoswitch + +import android.graphics.drawable.Drawable +import androidx.annotation.StringRes +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.kieronquinn.app.classicpowermenu.R +import com.kieronquinn.app.classicpowermenu.components.navigation.ContainerNavigation +import com.kieronquinn.app.classicpowermenu.components.quickaccesswallet.autoswitch.AutoSwitchServicesRepository +import com.kieronquinn.app.classicpowermenu.components.quickaccesswallet.loyaltycards.LoyaltyCardsRepository +import com.kieronquinn.app.classicpowermenu.components.settings.Settings +import com.kieronquinn.app.classicpowermenu.model.quickaccesswallet.WalletLoyaltyCardViewInfo +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onStart +import kotlinx.coroutines.launch + +abstract class SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModel: ViewModel() { + + abstract val state: Flow + + abstract fun onBackPressed() + abstract fun onServiceClicked(service: SelectAutoSwitchService) + + data class SelectAutoSwitchService(val name: String, val componentName: String, val image: Drawable) { + var selected = false + } + + sealed class State { + object Loading: State() + data class Loaded(val services: ArrayList): State() + data class Error(val type: ErrorType): State() + } + + enum class ErrorType(@StringRes val contentRes: Int) { + NO_SERVICES(R.string.settings_quick_access_wallet_rearrange_error_no_cards) + } + +} + +class SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModelImpl(private val autoSwitchServicesRepository: AutoSwitchServicesRepository, private val settings: Settings, private val containerNavigation: ContainerNavigation): SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModel() { + + private val autoSwitchServices = flow { + val services = autoSwitchServicesRepository.getAutoSwitchServices() + emit(services) + } + + private val _state = autoSwitchServices.map { services -> + when { + services.isEmpty() -> { + State.Error(ErrorType.NO_SERVICES) + } + else -> { + State.Loaded(services) + } + } + } + + override val state = _state.onStart { emit(State.Loading) } + + + override fun onBackPressed() { + viewModelScope.launch { + containerNavigation.navigateBack() + } + } + + override fun onServiceClicked(service: SelectAutoSwitchService) { + viewModelScope.launch { + settings.quickAccessWalletSelectedAutoSwitchService = service.componentName + containerNavigation.navigateBack() + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_settings_quick_access_wallet_auto_switch_service.xml b/app/src/main/res/layout/fragment_settings_quick_access_wallet_auto_switch_service.xml new file mode 100644 index 0000000..fadd2a2 --- /dev/null +++ b/app/src/main/res/layout/fragment_settings_quick_access_wallet_auto_switch_service.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_wallet_select_service_card.xml b/app/src/main/res/layout/item_wallet_select_service_card.xml new file mode 100644 index 0000000..83cab09 --- /dev/null +++ b/app/src/main/res/layout/item_wallet_select_service_card.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + \ No newline at end of file From 0aeb72d67bb42b2fe44e48d5605608343bd75700 Mon Sep 17 00:00:00 2001 From: Philip Magyar Date: Thu, 22 Aug 2024 22:25:03 +0200 Subject: [PATCH 3/5] make payment service switch optional, ability to change service, try catch for putstring --- .idea/deploymentTargetSelector.xml | 10 + .idea/navEditor.xml | 44 ++- .idea/other.xml | 252 ++++++++++++++++++ app/build.gradle | 3 + app/src/main/AndroidManifest.xml | 6 + .../app/classicpowermenu/ClassicPowerMenu.kt | 7 +- .../AutoSwitchServicesRepository.kt | 113 ++------ .../components/settings/Settings.kt | 14 + .../powermenu/main/PowerMenuFragment.kt | 22 +- .../powermenu/main/PowerMenuViewModel.kt | 5 +- .../SettingsQuickAccessWalletFragment.kt | 25 +- .../SettingsQuickAccessWalletViewModel.kt | 14 +- ...ickAccessWalletAutoSwitchServiceAdapter.kt | 4 +- ...ckAccessWalletAutoSwitchServiceFragment.kt | 43 +-- ...kAccessWalletAutoSwitchServiceViewModel.kt | 19 +- ...ttingsQuickAccessWalletRearrangeAdapter.kt | 2 - ...tingsQuickAccessWalletRearrangeFragment.kt | 2 - ...uick_access_wallet_auto_switch_service.xml | 24 +- .../item_wallet_select_service_card.xml | 67 ++--- .../nav_graph_settings_container.xml | 8 + app/src/main/res/values/dimens.xml | 1 + app/src/main/res/values/strings.xml | 5 + 22 files changed, 498 insertions(+), 192 deletions(-) create mode 100644 .idea/deploymentTargetSelector.xml create mode 100644 .idea/other.xml diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..b268ef3 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/navEditor.xml b/.idea/navEditor.xml index 28887e5..8a0e2b0 100644 --- a/.idea/navEditor.xml +++ b/.idea/navEditor.xml @@ -224,6 +224,11 @@ @@ -326,6 +343,15 @@ + diff --git a/.idea/other.xml b/.idea/other.xml new file mode 100644 index 0000000..4604c44 --- /dev/null +++ b/.idea/other.xml @@ -0,0 +1,252 @@ + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index dabdcf7..7c281f7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -66,6 +66,9 @@ protobuf { } dependencies { + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'androidx.recyclerview:recyclerview:1.3.2' + //AndroidX def lifecycle_version = "2.7.0" implementation 'androidx.core:core-ktx:1.12.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d7a544d..56af4f3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,12 @@ + + + + + + { WalletActivityStarterImpl(get(), get()) } single { WalletCardBlurProviderImpl(get(), get()) } single { LoyaltyCardsRepositoryImpl(get(), get(), get()) } + single { AutoSwitchServicesRepositoryImpl(get(), get()) } } private val monetModule = module { @@ -157,6 +161,7 @@ class ClassicPowerMenu: LifecycleApplication() { viewModel { SettingsQuickAccessWalletViewModelImpl(get(), get(), get(), get()) } viewModel { SettingsDeviceControlsViewModelImpl(get(), get()) } viewModel { SettingsQuickAccessWalletRearrangeViewModelImpl(get(), get(), get()) } + viewModel { SettingsQuickAccessWalletAutoSwitchServiceViewModelImpl(get(), get(), get()) } viewModel { SettingsDeveloperOptionsViewModelImpl(get()) } viewModel { SettingsRootCheckViewModelImpl(get()) } viewModel { UpdateAvailableBottomSheetViewModelImpl(get()) } diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/components/quickaccesswallet/autoswitch/AutoSwitchServicesRepository.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/components/quickaccesswallet/autoswitch/AutoSwitchServicesRepository.kt index ca9b7c5..bf7a270 100644 --- a/app/src/main/java/com/kieronquinn/app/classicpowermenu/components/quickaccesswallet/autoswitch/AutoSwitchServicesRepository.kt +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/components/quickaccesswallet/autoswitch/AutoSwitchServicesRepository.kt @@ -1,107 +1,42 @@ -package com.kieronquinn.app.classicpowermenu.components.quickaccesswallet.loyaltycards +package com.kieronquinn.app.classicpowermenu.components.quickaccesswallet.autoswitch import android.content.Context -import android.database.sqlite.SQLiteDatabase -import android.graphics.BitmapFactory -import android.graphics.drawable.BitmapDrawable -import android.os.ParcelFileDescriptor -import android.util.Log -import androidx.core.content.res.ResourcesCompat -import com.android.systemui.plugin.globalactions.wallet.WalletCardViewInfo -import com.kieronquinn.app.classicpowermenu.IClassicPowerMenu -import com.kieronquinn.app.classicpowermenu.R -import com.kieronquinn.app.classicpowermenu.components.quickaccesswallet.GooglePayConstants +import android.content.Intent +import android.content.pm.PackageManager +import com.android.systemui.util.extensions.componentName import com.kieronquinn.app.classicpowermenu.components.settings.Settings -import com.kieronquinn.app.classicpowermenu.model.protobuf.loyaltycard.LoyaltyCardProtos -import com.kieronquinn.app.classicpowermenu.model.quickaccesswallet.LoyaltyCard -import com.kieronquinn.app.classicpowermenu.model.quickaccesswallet.WalletLoyaltyCardViewInfo -import com.kieronquinn.app.classicpowermenu.model.quickaccesswallet.extract -import com.kieronquinn.app.classicpowermenu.service.container.CPMServiceContainer -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import java.io.File -import java.util.* + +import com.kieronquinn.app.classicpowermenu.ui.screens.settings.quickaccesswallet.autoswitchservice.SettingsQuickAccessWalletAutoSwitchServiceViewModel.AutoSwitchServiceItem import kotlin.collections.ArrayList -import kotlin.collections.HashMap -interface LoyaltyCardsRepository { +interface AutoSwitchServicesRepository { - suspend fun getLoyaltyCards(onCardClicked: (LoyaltyCard) -> Boolean, ignoreSetting: Boolean = false): List? + fun getAutoSwitchServices(): ArrayList } -class LoyaltyCardsRepositoryImpl(private val service: CPMServiceContainer, private val context: Context, private val settings: Settings): LoyaltyCardsRepository { - - private val isGooglePayInstalled by lazy { - GooglePayConstants.isGooglePayInstalled(context.packageManager) - } - - private val googleSansMedium by lazy { - ResourcesCompat.getFont(context, R.font.google_sans_text_medium)!! - } +class AutoSwitchServicesRepositoryImpl(private val context: Context, private val settings: Settings): AutoSwitchServicesRepository { + override fun getAutoSwitchServices(): ArrayList { + val list = ArrayList() - override suspend fun getLoyaltyCards(onCardClicked: (LoyaltyCard) -> Boolean, ignoreSetting: Boolean): List? { - if((!settings.quickAccessWalletShowLoyaltyCards && !ignoreSetting) || !isGooglePayInstalled) return null - return service.runWithService { service -> - withContext(Dispatchers.IO) { - context.withTemporaryFile { - service.googlePayDatabaseForLoyalty?.loadRemoteFile(it) ?: return@withTemporaryFile null - val database = SQLiteDatabase.openOrCreateDatabase(it, null) - val valuableImageFileNames = getValuableImageList(database) - getValuables(database, valuableImageFileNames, service) - } - } - }?.map { WalletLoyaltyCardViewInfo(context, it, googleSansMedium, onCardClicked) } - } + val packageManager = context.packageManager + val intent = Intent("android.nfc.cardemulation.action.HOST_APDU_SERVICE").addCategory(Intent.CATEGORY_DEFAULT) + val resolveInfoList = packageManager.queryIntentServices(intent, PackageManager.MATCH_DEFAULT_ONLY) - private fun getValuableImageList(database: SQLiteDatabase): HashMap { - val valuableImageFileNames = HashMap() - val valuableImagesCursor = database.rawQuery("select valuable_id,file_name from valuable_images", null, null) - valuableImagesCursor.moveToFirst() - if(valuableImagesCursor.isAfterLast) return valuableImageFileNames - do { - if(valuableImagesCursor.isAfterLast) break - valuableImageFileNames[valuableImagesCursor.getString(0)] = valuableImagesCursor.getString(1) - }while (valuableImagesCursor.moveToNext()) - valuableImagesCursor.close() - return valuableImageFileNames - } + for (resolveInfo in resolveInfoList) { + val service = AutoSwitchServiceItem( + resolveInfo.serviceInfo.loadLabel(packageManager).toString(), + resolveInfo.serviceInfo.componentName.flattenToString(), + resolveInfo.serviceInfo.loadIcon(packageManager) + ) - private fun getValuables(database: SQLiteDatabase, valuableImageFileNames: HashMap, service: IClassicPowerMenu): ArrayList { - val loyaltyCards = ArrayList() - //Vertical ID 1 = LOYALTY_CARD (See CommonProto.ValuableType in Google Pay) - val cursor = database.rawQuery("select valuable_id,proto from valuables where vertical_id='1'", null, null) - cursor.moveToFirst() - if(cursor.isAfterLast) return loyaltyCards - do { - if(cursor.isAfterLast) break - val valuableId = cursor.getString(0) - val valuableIcon = valuableImageFileNames[valuableId]?.let { valuableImageFileName -> - val bitmap = context.withTemporaryFile { - service.getGooglePayLoyaltyImageForId(valuableImageFileName)?.loadRemoteFile(it) ?: return@withTemporaryFile null - BitmapFactory.decodeFile(it.absolutePath) - } - bitmap - } - val blob = cursor.getBlob(1) - val loyaltyCard = LoyaltyCardProtos.LoyaltyCard.parseFrom(blob) - loyaltyCards.add(loyaltyCard.extract(valuableIcon, context)) - } while (cursor.moveToNext()) - cursor.close() - return loyaltyCards - } + if (settings.quickAccessWalletSelectedAutoSwitchService == service.componentName) service.selected = true - private fun ParcelFileDescriptor.loadRemoteFile(into: File){ - ParcelFileDescriptor.AutoCloseInputStream(this).buffered().use { stream -> - stream.copyTo(into.outputStream()) + list.add(service) } - } - private fun Context.withTemporaryFile(block: (File) -> T): T { - val file = File(cacheDir, UUID.randomUUID().toString()) - val result = block.invoke(file) - file.delete() - return result + return list } + } \ No newline at end of file diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/components/settings/Settings.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/components/settings/Settings.kt index 9a9b952..2e91f4e 100644 --- a/app/src/main/java/com/kieronquinn/app/classicpowermenu/components/settings/Settings.kt +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/components/settings/Settings.kt @@ -31,6 +31,9 @@ abstract class Settings { abstract var quickAccessWalletShowPreview: Boolean abstract var quickAccessWalletAccessWhileLocked: Boolean abstract var quickAccessWalletHideCardNumberWhenLocked: Boolean + abstract var quickAccessWalletAutoSwitchService: Boolean + abstract val quickAccessWalletAutoSwitchServiceFlow: Flow + abstract var quickAccessWalletSelectedAutoSwitchService: String abstract var quickAccessWalletLoyaltyCardsOrder: List abstract var quickAccessWalletLoyaltyCardsHidden: List abstract val quickAccessWalletLoyaltyCardsHiddenFlow: Flow> @@ -93,6 +96,12 @@ class SettingsImpl(context: Context): Settings() { private const val KEY_QUICK_ACCESS_WALLET_HIDE_CARD_NUMBER_WHEN_LOCKED = "quick_access_wallet_hide_card_number_when_locked" private const val DEFAULT_QUICK_ACCESS_WALLET_HIDE_CARD_NUMBER_WHEN_LOCKED = false + private const val KEY_QUICK_ACCESS_WALLET_AUTO_SWITCH_SERVICE = "quick_access_wallet_auto_switch_service" + private const val DEFAULT_QUICK_ACCESS_WALLET_AUTO_SWITCH_SERVICE = false + + private const val KEY_QUICK_ACCESS_WALLET_SELECTED_AUTO_SWITCH_SERVICE = "quick_access_wallet_selected_auto_switch_service" + private const val DEFAULT_QUICK_ACCESS_WALLET_SELECTED_AUTO_SWITCH_SERVICE = "" + private const val KEY_QUICK_ACCESS_WALLET_LOYALTY_HIDDEN_CARDS = "quick_access_wallet_hidden_cards" private val DEFAULT_QUICK_ACCESS_LOYALTY_WALLET_HIDDEN_CARDS = emptyList() @@ -136,12 +145,17 @@ class SettingsImpl(context: Context): Settings() { override var quickAccessWalletShowPreview by shared(KEY_QUICK_ACCESS_WALLET_SHOW_PREVIEW, DEFAULT_QUICK_ACCESS_SHOW_PREVIEW) override var quickAccessWalletAccessWhileLocked by shared(KEY_QUICK_ACCESS_WALLET_ACCESS_WHILE_LOCKED, DEFAULT_QUICK_ACCESS_WALLET_ACCESS_WHILE_LOCKED) override var quickAccessWalletHideCardNumberWhenLocked by shared(KEY_QUICK_ACCESS_WALLET_HIDE_CARD_NUMBER_WHEN_LOCKED, DEFAULT_QUICK_ACCESS_WALLET_HIDE_CARD_NUMBER_WHEN_LOCKED) + override var quickAccessWalletAutoSwitchService by shared(KEY_QUICK_ACCESS_WALLET_AUTO_SWITCH_SERVICE, DEFAULT_QUICK_ACCESS_WALLET_AUTO_SWITCH_SERVICE) + override var quickAccessWalletSelectedAutoSwitchService by shared(KEY_QUICK_ACCESS_WALLET_SELECTED_AUTO_SWITCH_SERVICE, DEFAULT_QUICK_ACCESS_WALLET_SELECTED_AUTO_SWITCH_SERVICE) override val quickAccessWalletShowFlow by lazy { sharedPreferences.getPreferenceAsFlow(KEY_QUICK_ACCESS_WALLET_SHOW, ::quickAccessWalletShow) } override val quickAccessWalletShowLoyaltyCardsFlow by lazy { sharedPreferences.getPreferenceAsFlow(KEY_QUICK_ACCESS_WALLET_SHOW_LOYALTY_CARDS, ::quickAccessWalletShowLoyaltyCards) } + override val quickAccessWalletAutoSwitchServiceFlow by lazy { + sharedPreferences.getPreferenceAsFlow(KEY_QUICK_ACCESS_WALLET_AUTO_SWITCH_SERVICE, ::quickAccessWalletAutoSwitchService) + } override var quickAccessWalletLoyaltyCardsOrder by sharedList(KEY_QUICK_ACCESS_WALLET_LOYALTY_CARD_ORDER, DEFAULT_KEY_QUICK_ACCESS_WALLET_LOYALTY_CARD_ORDER, this::stringListTypeConverter, this::stringListTypeReverseConverter) override var quickAccessWalletLoyaltyCardsHidden by sharedList(KEY_QUICK_ACCESS_WALLET_LOYALTY_HIDDEN_CARDS, DEFAULT_QUICK_ACCESS_LOYALTY_WALLET_HIDDEN_CARDS, this::stringListTypeConverter, this::stringListTypeReverseConverter) diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/powermenu/main/PowerMenuFragment.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/powermenu/main/PowerMenuFragment.kt index 0b68e86..99f5e3f 100644 --- a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/powermenu/main/PowerMenuFragment.kt +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/powermenu/main/PowerMenuFragment.kt @@ -31,7 +31,14 @@ import com.kieronquinn.app.classicpowermenu.model.power.PowerMenuButton import com.kieronquinn.app.classicpowermenu.model.power.PowerMenuContentItem import com.kieronquinn.app.classicpowermenu.service.container.CPMServiceContainer import com.kieronquinn.app.classicpowermenu.ui.base.BoundFragment -import com.kieronquinn.app.classicpowermenu.utils.extensions.* +import com.kieronquinn.app.classicpowermenu.utils.extensions.animateToInvisible +import com.kieronquinn.app.classicpowermenu.utils.extensions.animateToVisible +import com.kieronquinn.app.classicpowermenu.utils.extensions.awaitPost +import com.kieronquinn.app.classicpowermenu.utils.extensions.changed +import com.kieronquinn.app.classicpowermenu.utils.extensions.isScrolled +import com.kieronquinn.app.classicpowermenu.utils.extensions.scrollPercentage +import com.kieronquinn.app.classicpowermenu.utils.extensions.sendDismissIntent +import com.kieronquinn.app.classicpowermenu.utils.extensions.setSecondaryAlpha import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.launch @@ -126,12 +133,19 @@ class PowerMenuFragment : override fun onStop() { super.onStop() - contentAdapter?.controlsUiController?.hide() + contentAdapter.controlsUiController?.hide() } private fun changeDefaultPaymentMethod() { - val googlePay = "com.google.android.gms/com.google.android.gms.tapandpay.hce.service.TpHceService" - Settings.Secure.putString(powerMenuApplication.contentResolver, "nfc_payment_default_component", googlePay) + if (viewModel.showQuickAccessWallet && + viewModel.quickAccessWalletAutoSwitchService && + viewModel.quickAccessWalletSelectedAutoSwitchService != "") { + try { + Settings.Secure.putString(powerMenuApplication.contentResolver, "nfc_payment_default_component", viewModel.quickAccessWalletSelectedAutoSwitchService) + } catch (e: Exception) { + Log.e("CPM", "Failed to apply default payment service", e) + } + } } private fun setupInsets(view: View) { diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/powermenu/main/PowerMenuViewModel.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/powermenu/main/PowerMenuViewModel.kt index 98799fc..845765b 100644 --- a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/powermenu/main/PowerMenuViewModel.kt +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/powermenu/main/PowerMenuViewModel.kt @@ -4,7 +4,6 @@ import android.app.KeyguardManager import android.content.Context import android.content.Intent import android.telecom.TelecomManager -import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.android.systemui.plugin.globalactions.wallet.WalletCardViewInfo @@ -50,6 +49,8 @@ abstract class PowerMenuViewModel: ViewModel() { abstract val showControls: Boolean abstract val monetEnabled: Boolean abstract val useSolidBackground: Boolean + abstract val quickAccessWalletAutoSwitchService: Boolean + abstract val quickAccessWalletSelectedAutoSwitchService: String } @@ -69,6 +70,8 @@ class PowerMenuViewModelImpl(context: Context, private val service: CPMServiceCo override val showQuickAccessWallet by settings::quickAccessWalletShow override val monetEnabled by settings::useMonet override val useSolidBackground by settings::useSolidBackground + override val quickAccessWalletAutoSwitchService by settings::quickAccessWalletAutoSwitchService + override val quickAccessWalletSelectedAutoSwitchService by settings::quickAccessWalletSelectedAutoSwitchService override suspend fun shouldShowLockdown(): Boolean { //No point showing lockdown without a lock diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/SettingsQuickAccessWalletFragment.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/SettingsQuickAccessWalletFragment.kt index e85a8b9..386659e 100644 --- a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/SettingsQuickAccessWalletFragment.kt +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/SettingsQuickAccessWalletFragment.kt @@ -61,7 +61,20 @@ class SettingsQuickAccessWalletFragment: SettingsSwitchedFragment(), BackAvailab getString(R.string.settings_quick_access_wallet_hide_card_number_when_locked), getText(R.string.settings_quick_access_wallet_hide_card_number_when_locked_desc), viewModel::hideCardNumber - ) + ), + SettingsItem.SwitchSetting( + R.drawable.ic_quick_access_wallet_rearrange, + getString(R.string.settings_quick_access_wallet_auto_switch_service), + getText(R.string.settings_quick_access_wallet_auto_switch_service_desc), + viewModel::autoSwitchService + ), + SettingsItem.Setting( + R.drawable.ic_quick_access_wallet_rearrange, + getString(R.string.settings_quick_access_wallet_auto_switch_service_select), + null, + enabled = { viewModel.autoSwitchService }, + tapAction = viewModel::onAutoSwitchServiceClicked + ), ) } @@ -119,6 +132,7 @@ class SettingsQuickAccessWalletFragment: SettingsSwitchedFragment(), BackAvailab override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setupLoyaltyCardsListener() + setupAutoSwitchServiceListener() } private fun setupLoyaltyCardsListener(){ @@ -129,5 +143,12 @@ class SettingsQuickAccessWalletFragment: SettingsSwitchedFragment(), BackAvailab } } } - + private fun setupAutoSwitchServiceListener(){ + val recyclerView = recyclerView.invoke() + lifecycleScope.launchWhenResumed { + viewModel.autoSwitchServiceChanged.collect { + recyclerView.adapter?.notifyDataSetChanged() + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/SettingsQuickAccessWalletViewModel.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/SettingsQuickAccessWalletViewModel.kt index cec23c1..6b607e3 100644 --- a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/SettingsQuickAccessWalletViewModel.kt +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/SettingsQuickAccessWalletViewModel.kt @@ -9,7 +9,6 @@ import com.kieronquinn.app.classicpowermenu.components.navigation.ContainerNavig import com.kieronquinn.app.classicpowermenu.components.quickaccesswallet.GooglePayConstants import com.kieronquinn.app.classicpowermenu.components.settings.Settings import com.kieronquinn.app.classicpowermenu.ui.screens.settings.container.SettingsContainerFragmentDirections -import com.kieronquinn.app.classicpowermenu.utils.extensions.isAppInstalled import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch @@ -22,13 +21,17 @@ abstract class SettingsQuickAccessWalletViewModel: ViewModel() { abstract var showPreview: Boolean abstract var accessWhileLocked: Boolean abstract var hideCardNumber: Boolean + abstract var autoSwitchService: Boolean + abstract val selectedAutoSwitchService: String abstract val showLoyaltyCardsChanged: Flow + abstract val autoSwitchServiceChanged: Flow abstract val isGooglePayInstalled: Boolean abstract fun onSwitchClicked() abstract fun onChangeGooglePaySettingsClicked() abstract fun onReorderLoyaltyCardsClicked() + abstract fun onAutoSwitchServiceClicked() } @@ -42,6 +45,9 @@ class SettingsQuickAccessWalletViewModelImpl(context: Context, private val setti override var showPreview by settings::quickAccessWalletShowPreview override var accessWhileLocked by settings::quickAccessWalletAccessWhileLocked override var hideCardNumber by settings::quickAccessWalletHideCardNumberWhenLocked + override var autoSwitchService by settings::quickAccessWalletAutoSwitchService + override var selectedAutoSwitchService by settings::quickAccessWalletSelectedAutoSwitchService + override val autoSwitchServiceChanged = settings.quickAccessWalletAutoSwitchServiceFlow.map{} override val showLoyaltyCardsChanged = settings.quickAccessWalletShowLoyaltyCardsFlow.map { } override val isGooglePayInstalled @@ -63,6 +69,12 @@ class SettingsQuickAccessWalletViewModelImpl(context: Context, private val setti } } + override fun onAutoSwitchServiceClicked() { + viewModelScope.launch { + containerNavigation.navigate(SettingsContainerFragmentDirections.actionSettingsContainerFragmentToSettingsQuickAccessWalletAutoSwitchServiceFragment()) + } + } + private fun getGooglePayIntent(): Intent? { return if(GooglePayConstants.isGPayInstalled(packageManager)){ packageManager.getLaunchIntentForPackage(GooglePayConstants.NBU_PAISA_PACKAGE_NAME) diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceAdapter.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceAdapter.kt index 09f43e3..318b472 100644 --- a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceAdapter.kt +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceAdapter.kt @@ -1,4 +1,4 @@ -package com.kieronquinn.app.classicpowermenu.ui.screens.settings.quickaccesswallet.autoswitch +package com.kieronquinn.app.classicpowermenu.ui.screens.settings.quickaccesswallet.autoswitchservice import android.content.Context import android.view.LayoutInflater @@ -7,7 +7,7 @@ import androidx.recyclerview.widget.RecyclerView import com.kieronquinn.app.classicpowermenu.databinding.ItemWalletSelectServiceCardBinding import com.kieronquinn.monetcompat.core.MonetCompat -class SettingsQuickAccessWalletChangeDefaultPaymentMethodAdapter(context: Context, var cards: List, val onServiceClicked: (SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModel.SelectAutoSwitchService) -> Unit): RecyclerView.Adapter() { +class SettingsQuickAccessWalletAutoSwitchServiceAdapter(context: Context, var cards: List, val onServiceClicked: (SettingsQuickAccessWalletAutoSwitchServiceViewModel.AutoSwitchServiceItem) -> Unit): RecyclerView.Adapter() { init { setHasStableIds(true) diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceFragment.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceFragment.kt index 9a0c674..6c2db4a 100644 --- a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceFragment.kt +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceFragment.kt @@ -1,4 +1,4 @@ -package com.kieronquinn.app.classicpowermenu.ui.screens.settings.quickaccesswallet.autoswitch +package com.kieronquinn.app.classicpowermenu.ui.screens.settings.quickaccesswallet.autoswitchservice import android.os.Bundle import android.view.View @@ -8,20 +8,20 @@ import androidx.core.view.updatePadding import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import com.kieronquinn.app.classicpowermenu.R -import com.kieronquinn.app.classicpowermenu.databinding.FragmentSettingsQuickAccessWalletChangeDefaultPaymentMethodBinding +import com.kieronquinn.app.classicpowermenu.databinding.FragmentSettingsQuickAccessWalletAutoSwitchServiceBinding import com.kieronquinn.app.classicpowermenu.ui.base.BoundFragment import com.kieronquinn.app.classicpowermenu.ui.base.StandaloneFragment import com.kieronquinn.app.classicpowermenu.utils.extensions.onApplyInsets import com.kieronquinn.monetcompat.extensions.views.applyMonet import org.koin.androidx.viewmodel.ext.android.viewModel -class SettingsQuickAccessWalletChangeDefaultPaymentMethodFragment: BoundFragment(FragmentSettingsQuickAccessWalletChangeDefaultPaymentMethodBinding::inflate), StandaloneFragment { +class SettingsQuickAccessWalletAutoSwitchServiceFragment: BoundFragment(FragmentSettingsQuickAccessWalletAutoSwitchServiceBinding::inflate), StandaloneFragment { private val adapter by lazy { - SettingsQuickAccessWalletChangeDefaultPaymentMethodAdapter(requireContext(), emptyList(), viewModel::onServiceClicked) + SettingsQuickAccessWalletAutoSwitchServiceAdapter(requireContext(), emptyList(), viewModel::onServiceClicked) } - private val viewModel by viewModel() + private val viewModel by viewModel() override val onBackPressed by lazy { return@lazy viewModel::onBackPressed @@ -42,21 +42,26 @@ class SettingsQuickAccessWalletChangeDefaultPaymentMethodFragment: BoundFragment } } - private fun handleState(state: SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModel.State){ + private fun handleState(state: SettingsQuickAccessWalletAutoSwitchServiceViewModel.State){ when(state){ - is SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModel.State.Loading -> { - binding.quickAccessWalletChangeDefaultPaymentMethodRecyclerview.isVisible = false + is SettingsQuickAccessWalletAutoSwitchServiceViewModel.State.Loading -> { + binding.quickAccessWalletAutoSwitchServiceRecyclerview.isVisible = false + binding.quickAccessWalletAutoSwitchServiceEmpty.isVisible = false + binding.quickAccessWalletAutoSwitchServiceLoading.isVisible = true } - is SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModel.State.Error -> { - //binding.quickAccessWalletRearrangeRecyclerview.isVisible = false - //binding.quickAccessWalletRearrangeEmpty.isVisible = true - //binding.quickAccessWalletRearrangeEmptyText.setText(state.type.contentRes) - //binding.quickAccessWalletRearrangeLoading.isVisible = false + is SettingsQuickAccessWalletAutoSwitchServiceViewModel.State.Error -> { + binding.quickAccessWalletAutoSwitchServiceRecyclerview.isVisible = false + binding.quickAccessWalletAutoSwitchServiceLoading.isVisible = false + + binding.quickAccessWalletAutoSwitchServiceEmptyText.setText(state.type.contentRes) + binding.quickAccessWalletAutoSwitchServiceEmpty.isVisible = true } - is SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModel.State.Loaded -> { - binding.quickAccessWalletChangeDefaultPaymentMethodRecyclerview.isVisible = true + is SettingsQuickAccessWalletAutoSwitchServiceViewModel.State.Loaded -> { binding.quickAccessWalletAutoSwitchServiceLoading.isVisible = false + binding.quickAccessWalletAutoSwitchServiceEmpty.isVisible = false + + binding.quickAccessWalletAutoSwitchServiceRecyclerview.isVisible = true adapter.cards = state.services } } @@ -66,16 +71,16 @@ class SettingsQuickAccessWalletChangeDefaultPaymentMethodFragment: BoundFragment private fun setupToolbar(){ with(binding.toolbar){ - setupWithScrollableView(binding.quickAccessWalletChangeDefaultPaymentMethodRecyclerview) + setupWithScrollableView(binding.quickAccessWalletAutoSwitchServiceRecyclerview) setNavigationOnClickListener { viewModel.onBackPressed() } } } - private fun setupRecyclerView() = with(binding.quickAccessWalletChangeDefaultPaymentMethodRecyclerview) { + private fun setupRecyclerView() = with(binding.quickAccessWalletAutoSwitchServiceRecyclerview) { layoutManager = LinearLayoutManager(context) - adapter = this@SettingsQuickAccessWalletChangeDefaultPaymentMethodFragment.adapter + adapter = this@SettingsQuickAccessWalletAutoSwitchServiceFragment.adapter } private fun setupMonet(){ @@ -88,7 +93,7 @@ class SettingsQuickAccessWalletChangeDefaultPaymentMethodFragment: BoundFragment val topInset = insets.getInsets(WindowInsetsCompat.Type.statusBars()).top view.updatePadding(top = topInset) } - binding.quickAccessWalletChangeDefaultPaymentMethodRecyclerview.onApplyInsets { view, insets -> + binding.quickAccessWalletAutoSwitchServiceRecyclerview.onApplyInsets { view, insets -> val bottomPadding = resources.getDimension(R.dimen.margin_16).toInt() val bottomInset = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom view.updatePadding(bottom = bottomPadding + bottomInset) diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceViewModel.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceViewModel.kt index 6cae8de..0283f3d 100644 --- a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceViewModel.kt +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceViewModel.kt @@ -1,4 +1,4 @@ -package com.kieronquinn.app.classicpowermenu.ui.screens.settings.quickaccesswallet.autoswitch +package com.kieronquinn.app.classicpowermenu.ui.screens.settings.quickaccesswallet.autoswitchservice import android.graphics.drawable.Drawable import androidx.annotation.StringRes @@ -7,40 +7,37 @@ import androidx.lifecycle.viewModelScope import com.kieronquinn.app.classicpowermenu.R import com.kieronquinn.app.classicpowermenu.components.navigation.ContainerNavigation import com.kieronquinn.app.classicpowermenu.components.quickaccesswallet.autoswitch.AutoSwitchServicesRepository -import com.kieronquinn.app.classicpowermenu.components.quickaccesswallet.loyaltycards.LoyaltyCardsRepository import com.kieronquinn.app.classicpowermenu.components.settings.Settings -import com.kieronquinn.app.classicpowermenu.model.quickaccesswallet.WalletLoyaltyCardViewInfo import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.launch -abstract class SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModel: ViewModel() { +abstract class SettingsQuickAccessWalletAutoSwitchServiceViewModel: ViewModel() { abstract val state: Flow abstract fun onBackPressed() - abstract fun onServiceClicked(service: SelectAutoSwitchService) + abstract fun onServiceClicked(service: AutoSwitchServiceItem) - data class SelectAutoSwitchService(val name: String, val componentName: String, val image: Drawable) { + data class AutoSwitchServiceItem(val name: String, val componentName: String, val image: Drawable) { var selected = false } sealed class State { object Loading: State() - data class Loaded(val services: ArrayList): State() + data class Loaded(val services: ArrayList): State() data class Error(val type: ErrorType): State() } enum class ErrorType(@StringRes val contentRes: Int) { - NO_SERVICES(R.string.settings_quick_access_wallet_rearrange_error_no_cards) + NO_SERVICES(R.string.settings_quick_access_wallet_auto_switch_service_error_no_cards) } } -class SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModelImpl(private val autoSwitchServicesRepository: AutoSwitchServicesRepository, private val settings: Settings, private val containerNavigation: ContainerNavigation): SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModel() { +class SettingsQuickAccessWalletAutoSwitchServiceViewModelImpl(private val autoSwitchServicesRepository: AutoSwitchServicesRepository, private val settings: Settings, private val containerNavigation: ContainerNavigation): SettingsQuickAccessWalletAutoSwitchServiceViewModel() { private val autoSwitchServices = flow { val services = autoSwitchServicesRepository.getAutoSwitchServices() @@ -67,7 +64,7 @@ class SettingsQuickAccessWalletChangeDefaultPaymentMethodViewModelImpl(private v } } - override fun onServiceClicked(service: SelectAutoSwitchService) { + override fun onServiceClicked(service: AutoSwitchServiceItem) { viewModelScope.launch { settings.quickAccessWalletSelectedAutoSwitchService = service.componentName containerNavigation.navigateBack() diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/rearrange/SettingsQuickAccessWalletRearrangeAdapter.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/rearrange/SettingsQuickAccessWalletRearrangeAdapter.kt index 8c614ad..ee79cda 100644 --- a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/rearrange/SettingsQuickAccessWalletRearrangeAdapter.kt +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/rearrange/SettingsQuickAccessWalletRearrangeAdapter.kt @@ -7,8 +7,6 @@ import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.kieronquinn.app.classicpowermenu.R import com.kieronquinn.app.classicpowermenu.databinding.ItemWalletRearrangeCardBinding -import com.kieronquinn.app.classicpowermenu.model.quickaccesswallet.LoyaltyCard -import com.kieronquinn.app.classicpowermenu.model.quickaccesswallet.WalletLoyaltyCardViewInfo import com.kieronquinn.monetcompat.core.MonetCompat class SettingsQuickAccessWalletRearrangeAdapter(context: Context, var cards: List, val onCardVisibilityToggleClicked: (SettingsQuickAccessWalletRearrangeViewModel.RearrangeLoyaltyCard) -> Unit, val onHandleLongPress: (ViewHolder) -> Unit): RecyclerView.Adapter() { diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/rearrange/SettingsQuickAccessWalletRearrangeFragment.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/rearrange/SettingsQuickAccessWalletRearrangeFragment.kt index f99dc2e..43f4cc1 100644 --- a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/rearrange/SettingsQuickAccessWalletRearrangeFragment.kt +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/rearrange/SettingsQuickAccessWalletRearrangeFragment.kt @@ -14,9 +14,7 @@ import com.kieronquinn.app.classicpowermenu.databinding.FragmentSettingsQuickAcc import com.kieronquinn.app.classicpowermenu.ui.base.BoundFragment import com.kieronquinn.app.classicpowermenu.ui.base.StandaloneFragment import com.kieronquinn.app.classicpowermenu.utils.extensions.onApplyInsets -import com.kieronquinn.monetcompat.core.MonetCompat import com.kieronquinn.monetcompat.extensions.views.applyMonet -import kotlinx.coroutines.flow.collect import org.koin.androidx.viewmodel.ext.android.viewModel import java.util.* diff --git a/app/src/main/res/layout/fragment_settings_quick_access_wallet_auto_switch_service.xml b/app/src/main/res/layout/fragment_settings_quick_access_wallet_auto_switch_service.xml index fadd2a2..271e9a3 100644 --- a/app/src/main/res/layout/fragment_settings_quick_access_wallet_auto_switch_service.xml +++ b/app/src/main/res/layout/fragment_settings_quick_access_wallet_auto_switch_service.xml @@ -16,7 +16,7 @@ app:titleTextAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title.ClassicPowerMenu" /> @@ -51,4 +51,26 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_wallet_select_service_card.xml b/app/src/main/res/layout/item_wallet_select_service_card.xml index 83cab09..bd0d96b 100644 --- a/app/src/main/res/layout/item_wallet_select_service_card.xml +++ b/app/src/main/res/layout/item_wallet_select_service_card.xml @@ -3,18 +3,21 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="@dimen/wallet_rearrange_item_height" + android:layout_height="wrap_content" + android:background="?android:attr/selectableItemBackground" + android:clickable="true" + android:focusable="true" android:clipToPadding="false" android:padding="@dimen/margin_16"> + tools:text="Service Name" /> - - - - + app:layout_constraintStart_toEndOf="@id/wallet_select_service_card_image" + app:layout_constraintTop_toBottomOf="@id/wallet_select_service_card_title" + tools:text="Service ComponentName" /> \ No newline at end of file diff --git a/app/src/main/res/navigation/nav_graph_settings_container.xml b/app/src/main/res/navigation/nav_graph_settings_container.xml index d25c914..71a06db 100644 --- a/app/src/main/res/navigation/nav_graph_settings_container.xml +++ b/app/src/main/res/navigation/nav_graph_settings_container.xml @@ -16,6 +16,9 @@ + + 172dp 200dp 300dp + 16dp \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5232781..1c9a3eb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -83,6 +83,11 @@ Change settings such as Payment Card order, default card and behaviour Show the Loyalty Card preview while locked. If disabled, you will be prompted to unlock first before the preview or Google Wallet opens Blur Payment Card Number when locked + Auto switch default payment method + When CPM is opened auto switch the default payment method to the selected service. Note: This is only needed if your wallet app is not the "Default Contactless Payment" + Select service for auto switch + Loading NFC emulation services… + No NFC emulation services found Show Loyalty Cards Load and show your Loyalty Cards from Google Wallet in the Quick Access Wallet Rearrange & Hide Loyalty Cards From a3c765b28a7248bd811054f78513dc7ce6cef395 Mon Sep 17 00:00:00 2001 From: Philip Magyar Date: Thu, 22 Aug 2024 22:40:14 +0200 Subject: [PATCH 4/5] name "card" to "service" --- ...ickAccessWalletAutoSwitchServiceAdapter.kt | 22 +++++++++---------- ...ckAccessWalletAutoSwitchServiceFragment.kt | 2 +- ...kAccessWalletAutoSwitchServiceViewModel.kt | 2 +- ...rvice_card.xml => item_wallet_service.xml} | 14 ++++++------ app/src/main/res/values/strings.xml | 2 +- 5 files changed, 21 insertions(+), 21 deletions(-) rename app/src/main/res/layout/{item_wallet_select_service_card.xml => item_wallet_service.xml} (81%) diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceAdapter.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceAdapter.kt index 318b472..6afe4ff 100644 --- a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceAdapter.kt +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceAdapter.kt @@ -4,10 +4,10 @@ import android.content.Context import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import com.kieronquinn.app.classicpowermenu.databinding.ItemWalletSelectServiceCardBinding +import com.kieronquinn.app.classicpowermenu.databinding.ItemWalletServiceBinding import com.kieronquinn.monetcompat.core.MonetCompat -class SettingsQuickAccessWalletAutoSwitchServiceAdapter(context: Context, var cards: List, val onServiceClicked: (SettingsQuickAccessWalletAutoSwitchServiceViewModel.AutoSwitchServiceItem) -> Unit): RecyclerView.Adapter() { +class SettingsQuickAccessWalletAutoSwitchServiceAdapter(context: Context, var services: List, val onServiceClicked: (SettingsQuickAccessWalletAutoSwitchServiceViewModel.AutoSwitchServiceItem) -> Unit): RecyclerView.Adapter() { init { setHasStableIds(true) @@ -22,22 +22,22 @@ class SettingsQuickAccessWalletAutoSwitchServiceAdapter(context: Context, var ca } override fun getItemId(position: Int): Long { - return cards[position].componentName.hashCode().toLong() + return services[position].componentName.hashCode().toLong() } - override fun getItemCount() = cards.size + override fun getItemCount() = services.size override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - return ViewHolder(ItemWalletSelectServiceCardBinding.inflate(layoutInflater, parent, false)) + return ViewHolder(ItemWalletServiceBinding.inflate(layoutInflater, parent, false)) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val item = cards[position] + val item = services[position] with(holder.binding){ - walletSelectServiceCardTitle.text = item.name - walletSelectServiceCardText.text = item.componentName - walletSelectServiceCardImage.clipToOutline = true - walletSelectServiceCardImage.setImageDrawable(item.image) + walletServiceTitle.text = item.name + walletServiceText.text = item.componentName + walletServiceImage.clipToOutline = true + walletServiceImage.setImageDrawable(item.image) } if (item.selected) holder.itemView.setBackgroundColor(monet.getSecondaryColor(holder.itemView.context)) @@ -47,6 +47,6 @@ class SettingsQuickAccessWalletAutoSwitchServiceAdapter(context: Context, var ca } } - data class ViewHolder(val binding: ItemWalletSelectServiceCardBinding): RecyclerView.ViewHolder(binding.root) + data class ViewHolder(val binding: ItemWalletServiceBinding): RecyclerView.ViewHolder(binding.root) } \ No newline at end of file diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceFragment.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceFragment.kt index 6c2db4a..87251d1 100644 --- a/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceFragment.kt +++ b/app/src/main/java/com/kieronquinn/app/classicpowermenu/ui/screens/settings/quickaccesswallet/autoswitchservice/SettingsQuickAccessWalletAutoSwitchServiceFragment.kt @@ -62,7 +62,7 @@ class SettingsQuickAccessWalletAutoSwitchServiceFragment: BoundFragment diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1c9a3eb..dcc6870 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -87,7 +87,7 @@ When CPM is opened auto switch the default payment method to the selected service. Note: This is only needed if your wallet app is not the "Default Contactless Payment" Select service for auto switch Loading NFC emulation services… - No NFC emulation services found + No NFC emulation services found Show Loyalty Cards Load and show your Loyalty Cards from Google Wallet in the Quick Access Wallet Rearrange & Hide Loyalty Cards From 82aa55a1183b104ba94a172ca6e80899fd5de7db Mon Sep 17 00:00:00 2001 From: Philip Magyar Date: Fri, 23 Aug 2024 11:01:14 +0200 Subject: [PATCH 5/5] remove placeholder --- .../placeholder/PlaceholderContent.kt | 57 ------------------- 1 file changed, 57 deletions(-) delete mode 100644 app/src/main/java/com/kieronquinn/app/classicpowermenu/placeholder/PlaceholderContent.kt diff --git a/app/src/main/java/com/kieronquinn/app/classicpowermenu/placeholder/PlaceholderContent.kt b/app/src/main/java/com/kieronquinn/app/classicpowermenu/placeholder/PlaceholderContent.kt deleted file mode 100644 index f4aa43f..0000000 --- a/app/src/main/java/com/kieronquinn/app/classicpowermenu/placeholder/PlaceholderContent.kt +++ /dev/null @@ -1,57 +0,0 @@ -package com.kieronquinn.app.classicpowermenu.placeholder - -import java.util.ArrayList -import java.util.HashMap - -/** - * Helper class for providing sample content for user interfaces created by - * Android template wizards. - * - * TODO: Replace all uses of this class before publishing your app. - */ -object PlaceholderContent { - - /** - * An array of sample (placeholder) items. - */ - val ITEMS: MutableList = ArrayList() - - /** - * A map of sample (placeholder) items, by ID. - */ - val ITEM_MAP: MutableMap = HashMap() - - private val COUNT = 25 - - init { - // Add some sample items. - for (i in 1..COUNT) { - addItem(createPlaceholderItem(i)) - } - } - - private fun addItem(item: PlaceholderItem) { - ITEMS.add(item) - ITEM_MAP.put(item.id, item) - } - - private fun createPlaceholderItem(position: Int): PlaceholderItem { - return PlaceholderItem(position.toString(), "Item " + position, makeDetails(position)) - } - - private fun makeDetails(position: Int): String { - val builder = StringBuilder() - builder.append("Details about Item: ").append(position) - for (i in 0..position - 1) { - builder.append("\nMore details information here.") - } - return builder.toString() - } - - /** - * A placeholder item representing a piece of content. - */ - data class PlaceholderItem(val id: String, val content: String, val details: String) { - override fun toString(): String = content - } -} \ No newline at end of file