From 659599ced191fdf1bf2643bc4edc728d8443f94f Mon Sep 17 00:00:00 2001 From: Brandon McAnsh Date: Thu, 18 Jul 2024 11:10:17 -0400 Subject: [PATCH 1/2] feat: share tweet to tip Signed-off-by: Brandon McAnsh --- app/src/main/AndroidManifest.xml | 6 +++ .../java/com/getcode/models/PaymentRequest.kt | 17 +++--- .../java/com/getcode/util/DeeplinkHandler.kt | 52 ++++++++++++++++++- 3 files changed, 66 insertions(+), 9 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2f5209785..a68d0d6be 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -138,6 +138,12 @@ android:scheme="codewallet" /> + + + + + + ("mode") ?: return null Timber.d("mode=$mode") - val secret = container.decode("clientSecret") ?: return null - val clientSecret = Base58.decode(secret) - if (clientSecret.size != 11) { - Timber.e("Invalid client secret") - return null - } + val secret = container.decode("clientSecret") + val clientSecret = secret?.let { Base58.decode(it) } val (successUrl, cancelUrl) = container.decode("confirmParams") ?: ConfirmParams(null, null) @@ -57,7 +54,7 @@ data class DeepLinkRequest( val baseRequest = DeepLinkRequest( mode = mode, - clientSecret = clientSecret.toList(), + clientSecret = clientSecret?.toList().orEmpty(), successUrl = successUrl?.url, cancelUrl = cancelUrl?.url, ) @@ -154,6 +151,10 @@ private inline fun JsonObject.decode(key: String): T? { } } +inline fun encode(data: T): String { + return runCatching { Json.encodeToString(data) }.getOrNull().orEmpty() +} + private inline fun JsonObject.decode(key: String, map: (T) -> R): R? { return decode(key)?.let { map(it) } } @@ -166,7 +167,7 @@ private data class LoginKeys( ) @Serializable -private data class PlatformKeys( +data class PlatformKeys( val name: String, val username: String, ) diff --git a/app/src/main/java/com/getcode/util/DeeplinkHandler.kt b/app/src/main/java/com/getcode/util/DeeplinkHandler.kt index 813209b9e..6ebbeda17 100644 --- a/app/src/main/java/com/getcode/util/DeeplinkHandler.kt +++ b/app/src/main/java/com/getcode/util/DeeplinkHandler.kt @@ -2,13 +2,24 @@ package com.getcode.util import android.content.Intent import android.net.Uri +import androidx.core.net.toUri import cafe.adriel.voyager.core.screen.Screen +import com.getcode.models.DeepLinkRequest +import com.getcode.models.PlatformKeys +import com.getcode.models.encode import com.getcode.navigation.screens.HomeScreen import com.getcode.navigation.screens.LoginScreen +import com.getcode.network.repository.encodeBase64 import com.getcode.network.repository.urlDecode import com.getcode.utils.TraceType +import com.getcode.utils.base64EncodedData import com.getcode.utils.trace +import com.getcode.vendor.Base58 import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.put import timber.log.Timber import javax.inject.Inject import javax.inject.Singleton @@ -42,7 +53,17 @@ class DeeplinkHandler @Inject constructor() { val intent = MutableStateFlow(debounceIntent) fun handle(intent: Intent? = debounceIntent): DeeplinkResult? { - val uri = intent?.data ?: return null + val uri = when { + intent?.data != null -> intent.data + intent?.getStringExtra(Intent.EXTRA_TEXT) != null -> { + val sharedLink = intent.getStringExtra(Intent.EXTRA_TEXT)?.toUri() ?: return null + sharedLink.resolveSharedEntity + } + + else -> null + } ?: return null + + println("resolved uri=$uri") return when (val type = uri.deeplinkType) { is Type.Login -> { DeeplinkResult( @@ -71,6 +92,35 @@ class DeeplinkHandler @Inject constructor() { } } + /** + * Handles converting inbound shared content with possible deeplinks + * e.g sharing a tweet to trigger a tipcard flow + */ + private val Uri.resolveSharedEntity: Uri + get() { + // https://x.com//status/ + when (this.host) { + "x.com", + "twitter.com" -> { + // convert shared tweets to owner's tip card + val username = pathSegments.firstOrNull() ?: return this + val payload = buildJsonObject { + put("mode", "tip") + put( + "platform", + buildJsonObject { + put("name", "Twitter") + put("username", username) + } + ) + } + val encodedPayload = encode(payload).toByteArray().encodeBase64() + return "codewallet://sdk.getcode.com/v1/elements/tip-request-page-mobile/#/p=$encodedPayload".toUri() + } + else -> return this + } + } + private val Uri.deeplinkType: Type get() = when (val segment = lastPathSegment) { "login" -> { From f386b196b85462094d3fcc8225aed17435a59799 Mon Sep 17 00:00:00 2001 From: Brandon McAnsh Date: Fri, 9 Aug 2024 12:19:38 -0400 Subject: [PATCH 2/2] chore: move share tweet to tip behind beta flag Signed-off-by: Brandon McAnsh --- .../com/getcode/analytics/AnalyticsManager.kt | 2 +- .../main/java/com/getcode/model/PrefBool.kt | 3 +- .../network/repository/BetaFlagsRepository.kt | 10 +++- app/build.gradle.kts | 2 +- app/src/main/AndroidManifest.xml | 10 +++- .../java/com/getcode/models/PaymentRequest.kt | 17 +++---- app/src/main/java/com/getcode/util/Context.kt | 7 --- .../java/com/getcode/util/DeeplinkHandler.kt | 32 ++++++++---- .../main/java/com/getcode/util/IntentUtils.kt | 2 + app/src/main/java/com/getcode/util/Pacman.kt | 30 +++++++++++ .../view/main/account/BetaFlagsScreen.kt | 15 ++++-- .../view/main/account/BetaFlagsViewModel.kt | 50 ++++++------------- app/src/main/res/values/strings-universal.xml | 2 + buildSrc/src/main/java/Dependencies.kt | 3 ++ 14 files changed, 111 insertions(+), 74 deletions(-) create mode 100644 app/src/main/java/com/getcode/util/Pacman.kt diff --git a/api/src/main/java/com/getcode/analytics/AnalyticsManager.kt b/api/src/main/java/com/getcode/analytics/AnalyticsManager.kt index 833c1bf6c..1fccc04f1 100644 --- a/api/src/main/java/com/getcode/analytics/AnalyticsManager.kt +++ b/api/src/main/java/com/getcode/analytics/AnalyticsManager.kt @@ -323,7 +323,7 @@ class AnalyticsManager @Inject constructor( //Bill Bill("Bill"), Request("Request Card"), - TipCard("TIp Card"), + TipCard("Tip Card"), //Transfer Transfer("Transfer"), diff --git a/api/src/main/java/com/getcode/model/PrefBool.kt b/api/src/main/java/com/getcode/model/PrefBool.kt index 0b0f44bff..590c172e8 100644 --- a/api/src/main/java/com/getcode/model/PrefBool.kt +++ b/api/src/main/java/com/getcode/model/PrefBool.kt @@ -43,14 +43,13 @@ sealed class PrefsBool(val value: String) { data object SHOW_CONNECTIVITY_STATUS: PrefsBool("debug_no_network"), BetaFlag data object GIVE_REQUESTS_ENABLED: PrefsBool("give_requests_enabled"), BetaFlag data object BUY_MODULE_ENABLED : PrefsBool("buy_kin_enabled"), BetaFlag - - data object CHAT_UNSUB_ENABLED: PrefsBool("chat_unsub_enabled"), BetaFlag data object TIPS_ENABLED : PrefsBool("tips_enabled"), BetaFlag data object TIPS_CHAT_ENABLED: PrefsBool("tips_chat_enabled"), BetaFlag data object TIPS_CHAT_CASH_ENABLED: PrefsBool("tips_chat_cash_enabled"), BetaFlag data object BALANCE_CURRENCY_SELECTION_ENABLED: PrefsBool("balance_currency_enabled"), BetaFlag data object KADO_WEBVIEW_ENABLED : PrefsBool("kado_inapp_enabled"), BetaFlag + data object SHARE_TWEET_TO_TIP : PrefsBool("share_tweet_to_tip"), BetaFlag } val APP_SETTINGS: List = listOf(PrefsBool.CAMERA_START_BY_DEFAULT, PrefsBool.REQUIRE_BIOMETRICS) \ No newline at end of file diff --git a/api/src/main/java/com/getcode/network/repository/BetaFlagsRepository.kt b/api/src/main/java/com/getcode/network/repository/BetaFlagsRepository.kt index d42ded921..5d798f63b 100644 --- a/api/src/main/java/com/getcode/network/repository/BetaFlagsRepository.kt +++ b/api/src/main/java/com/getcode/network/repository/BetaFlagsRepository.kt @@ -19,6 +19,7 @@ data class BetaOptions( val tipsChatCashEnabled: Boolean, val balanceCurrencySelectionEnabled: Boolean, val kadoWebViewEnabled: Boolean, + val shareTweetToTip: Boolean, ) { companion object { // Default states for various beta flags in app. @@ -36,6 +37,7 @@ data class BetaOptions( tipsChatCashEnabled = false, balanceCurrencySelectionEnabled = true, kadoWebViewEnabled = false, + shareTweetToTip = false ) } } @@ -70,7 +72,8 @@ class BetaFlagsRepository @Inject constructor( observeBetaFlag(PrefsBool.TIPS_CHAT_CASH_ENABLED, default = defaults.tipsChatCashEnabled), observeBetaFlag(PrefsBool.BALANCE_CURRENCY_SELECTION_ENABLED, defaults.balanceCurrencySelectionEnabled), observeBetaFlag(PrefsBool.DISPLAY_ERRORS, default = defaults.displayErrors), - observeBetaFlag(PrefsBool.KADO_WEBVIEW_ENABLED, default = defaults.kadoWebViewEnabled) + observeBetaFlag(PrefsBool.KADO_WEBVIEW_ENABLED, default = defaults.kadoWebViewEnabled), + observeBetaFlag(PrefsBool.SHARE_TWEET_TO_TIP, default = defaults.shareTweetToTip) ) { BetaOptions( showNetworkDropOff = it[0], @@ -86,6 +89,7 @@ class BetaFlagsRepository @Inject constructor( balanceCurrencySelectionEnabled = it[10], displayErrors = it[11], kadoWebViewEnabled = it[12], + shareTweetToTip = it[13] ) } } @@ -98,4 +102,8 @@ class BetaFlagsRepository @Inject constructor( b.takeIf { a } ?: default } } + + suspend fun isEnabled(flag: PrefsBool): Boolean { + return prefRepository.get(flag, false) + } } diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 572299105..6027ef141 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -223,5 +223,5 @@ dependencies { implementation(Libs.timber) implementation(Libs.bugsnag) - implementation("dev.chrisbanes.haze:haze:0.7.3") + implementation(Libs.haze) } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4e0e30cfa..093d4174e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -150,13 +150,19 @@ android:scheme="https" /> + + + - - + ("mode") ?: return null Timber.d("mode=$mode") - val secret = container.decode("clientSecret") - val clientSecret = secret?.let { Base58.decode(it) } + val secret = container.decode("clientSecret") ?: return null + val clientSecret = Base58.decode(secret) + if (clientSecret.size != 11) { + Timber.e("Invalid client secret") + return null + } val (successUrl, cancelUrl) = container.decode("confirmParams") ?: ConfirmParams(null, null) @@ -67,7 +70,7 @@ data class DeepLinkRequest( val baseRequest = DeepLinkRequest( mode = mode, - clientSecret = clientSecret?.toList().orEmpty(), + clientSecret = clientSecret.toList(), successUrl = successUrl?.url, cancelUrl = cancelUrl?.url, ) @@ -164,10 +167,6 @@ private inline fun JsonObject.decode(key: String): T? { } } -inline fun encode(data: T): String { - return runCatching { Json.encodeToString(data) }.getOrNull().orEmpty() -} - private inline fun JsonObject.decode(key: String, map: (T) -> R): R? { return decode(key)?.let { map(it) } } @@ -180,7 +179,7 @@ private data class LoginKeys( ) @Serializable -data class PlatformKeys( +private data class PlatformKeys( val name: String, val username: String, ) diff --git a/app/src/main/java/com/getcode/util/Context.kt b/app/src/main/java/com/getcode/util/Context.kt index 1060a721a..867d5a51f 100644 --- a/app/src/main/java/com/getcode/util/Context.kt +++ b/app/src/main/java/com/getcode/util/Context.kt @@ -1,15 +1,8 @@ package com.getcode.util import android.content.Context -import androidx.biometric.BiometricManager -import androidx.biometric.BiometricPrompt -import androidx.biometric.BiometricPrompt.AuthenticationError import androidx.core.content.ContextCompat -import androidx.fragment.app.FragmentActivity import com.getcode.R -import com.getcode.network.repository.TransactionRepository.ErrorSubmitIntent -import timber.log.Timber -import java.util.concurrent.Executors fun Context.launchAppSettings() { val intent = IntentUtils.appSettings() diff --git a/app/src/main/java/com/getcode/util/DeeplinkHandler.kt b/app/src/main/java/com/getcode/util/DeeplinkHandler.kt index 2b30fa6bc..cddc002c1 100644 --- a/app/src/main/java/com/getcode/util/DeeplinkHandler.kt +++ b/app/src/main/java/com/getcode/util/DeeplinkHandler.kt @@ -1,18 +1,24 @@ package com.getcode.util +import android.content.Context import android.content.Intent import android.net.Uri import androidx.core.net.toUri import cafe.adriel.voyager.core.screen.Screen +import com.getcode.model.BetaFlag +import com.getcode.model.PrefsBool import com.getcode.models.DeepLinkRequest import com.getcode.models.encode import com.getcode.navigation.screens.HomeScreen import com.getcode.navigation.screens.LoginScreen +import com.getcode.network.repository.BetaFlagsRepository import com.getcode.network.repository.encodeBase64 import com.getcode.network.repository.urlDecode +import com.getcode.ui.utils.getActivity import com.getcode.utils.TraceType import com.getcode.utils.base64EncodedData import com.getcode.utils.trace +import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.put @@ -39,7 +45,10 @@ data class DeeplinkResult( * in favour of the latest request in the navigation graph. */ @Singleton -class DeeplinkHandler @Inject constructor() { +class DeeplinkHandler @Inject constructor( + @ApplicationContext private val context: Context, + private val betaFlags: BetaFlagsRepository +) { var debounceIntent: Intent? = null set(value) { intent.value = value @@ -49,12 +58,13 @@ class DeeplinkHandler @Inject constructor() { val intent = MutableStateFlow(debounceIntent) - fun handle(intent: Intent? = debounceIntent): DeeplinkResult? { + suspend fun handle(intent: Intent? = debounceIntent): DeeplinkResult? { + println(intent) val uri = when { intent?.data != null -> intent.data intent?.getStringExtra(Intent.EXTRA_TEXT) != null -> { val sharedLink = intent.getStringExtra(Intent.EXTRA_TEXT)?.toUri() ?: return null - sharedLink.resolveSharedEntity + sharedLink.resolveSharedEntity() } else -> null @@ -108,19 +118,19 @@ class DeeplinkHandler @Inject constructor() { * Handles converting inbound shared content with possible deeplinks * e.g sharing a tweet to trigger a tipcard flow */ - private val Uri.resolveSharedEntity: Uri - get() { - // https://x.com//status/ - return when { - this.host == "x.com" || this.host == "twitter.com" -> { + private suspend fun Uri.resolveSharedEntity(): Uri { + when { + this.host == "x.com" || this.host == "twitter.com" -> { + // https://x.com//status/ + if (betaFlags.isEnabled(PrefsBool.SHARE_TWEET_TO_TIP)) { // convert shared tweets to owner's tip card val username = pathSegments.firstOrNull() ?: return this - Uri.parse(Linkify.tipCard(username, "x")) + return Uri.parse(Linkify.tipCard(username, "x")) } - - else -> this } } + return this + } private val Uri.deeplinkType: Type get() { diff --git a/app/src/main/java/com/getcode/util/IntentUtils.kt b/app/src/main/java/com/getcode/util/IntentUtils.kt index 8a61cbd30..ada046265 100644 --- a/app/src/main/java/com/getcode/util/IntentUtils.kt +++ b/app/src/main/java/com/getcode/util/IntentUtils.kt @@ -1,11 +1,13 @@ package com.getcode.util +import android.content.Context import android.content.Intent import android.net.Uri import android.provider.Settings import com.getcode.BuildConfig import com.getcode.utils.makeE164 + object IntentUtils { fun appSettings() = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { diff --git a/app/src/main/java/com/getcode/util/Pacman.kt b/app/src/main/java/com/getcode/util/Pacman.kt new file mode 100644 index 000000000..db2500529 --- /dev/null +++ b/app/src/main/java/com/getcode/util/Pacman.kt @@ -0,0 +1,30 @@ +package com.getcode.util + +import android.content.ComponentName +import android.content.Context +import android.content.pm.PackageManager +import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject + + +class Pacman @Inject constructor( + @ApplicationContext private val context: Context +) { + private val packageManager = context.packageManager + + fun enableTweetShare(enable: Boolean) { + val component = ComponentName(context.packageName, "com.getcode.view.TweetShareHandler") + if (enable) { + packageManager.setComponentEnabledSetting( + component, + PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP + ) + } else { + packageManager.setComponentEnabledSetting( + component, + PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP + ) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/getcode/view/main/account/BetaFlagsScreen.kt b/app/src/main/java/com/getcode/view/main/account/BetaFlagsScreen.kt index 7cd07999b..30201acf8 100644 --- a/app/src/main/java/com/getcode/view/main/account/BetaFlagsScreen.kt +++ b/app/src/main/java/com/getcode/view/main/account/BetaFlagsScreen.kt @@ -14,6 +14,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import com.getcode.R import com.getcode.model.PrefsBool +import com.getcode.network.repository.BetaOptions import com.getcode.theme.CodeTheme import com.getcode.ui.components.ButtonState import com.getcode.ui.components.CodeButton @@ -44,7 +45,7 @@ fun BetaFlagsScreen( PrefsBool.VIBRATE_ON_SCAN, R.string.beta_vibrate_on_scan, stringResource(R.string.beta_vibrate_on_scan_description), - state.isVibrateOnScan + state.tickOnScan ), BetaFeature( PrefsBool.SHOW_CONNECTIVITY_STATUS, @@ -62,7 +63,7 @@ fun BetaFlagsScreen( PrefsBool.BALANCE_CURRENCY_SELECTION_ENABLED, R.string.beta_balance_currency, stringResource(R.string.beta_balance_currency_description), - state.currencySelectionBalanceEnabled + state.balanceCurrencySelectionEnabled ), BetaFeature( PrefsBool.GIVE_REQUESTS_ENABLED, @@ -74,7 +75,7 @@ fun BetaFlagsScreen( PrefsBool.BUY_MODULE_ENABLED, R.string.beta_buy_kin, stringResource(id = R.string.beta_buy_kin_description), - state.buyKinEnabled + state.buyModuleEnabled ), BetaFeature( PrefsBool.CHAT_UNSUB_ENABLED, @@ -106,6 +107,12 @@ fun BetaFlagsScreen( stringResource(id = R.string.beta_kado_webview_description), state.kadoWebViewEnabled, ), + BetaFeature( + PrefsBool.SHARE_TWEET_TO_TIP, + R.string.beta_share_tweet_tip, + stringResource(id = R.string.beta_share_tweet_tip_description), + state.shareTweetToTip, + ), BetaFeature( PrefsBool.DISPLAY_ERRORS, R.string.beta_display_errors, @@ -143,7 +150,7 @@ fun BetaFlagsScreen( } } -private fun BetaFlagsViewModel.State.canMutate(flag: PrefsBool): Boolean { +private fun BetaOptions.canMutate(flag: PrefsBool): Boolean { return when (flag) { PrefsBool.BUY_MODULE_ENABLED -> false PrefsBool.BALANCE_CURRENCY_SELECTION_ENABLED -> false diff --git a/app/src/main/java/com/getcode/view/main/account/BetaFlagsViewModel.kt b/app/src/main/java/com/getcode/view/main/account/BetaFlagsViewModel.kt index d212ecaab..a518f71a5 100644 --- a/app/src/main/java/com/getcode/view/main/account/BetaFlagsViewModel.kt +++ b/app/src/main/java/com/getcode/view/main/account/BetaFlagsViewModel.kt @@ -5,6 +5,7 @@ import com.getcode.model.PrefsBool import com.getcode.network.repository.BetaFlagsRepository import com.getcode.network.repository.BetaOptions import com.getcode.network.repository.PrefRepository +import com.getcode.util.Pacman import com.getcode.utils.ErrorUtils import com.getcode.view.BaseViewModel2 import dagger.hilt.android.lifecycle.HiltViewModel @@ -18,26 +19,11 @@ import javax.inject.Inject class BetaFlagsViewModel @Inject constructor( betaFlags: BetaFlagsRepository, prefRepository: PrefRepository, -) : BaseViewModel2( - initialState = State(), + pacman: Pacman, +) : BaseViewModel2( + initialState = BetaOptions.Defaults, updateStateForEvent = updateStateForEvent ) { - data class State( - val showNetworkDropOff: Boolean = false, - val canViewBuckets: Boolean = false, - val isVibrateOnScan: Boolean = false, - val currencySelectionBalanceEnabled: Boolean = false, - val displayErrors: Boolean = false, - val giveRequestsEnabled: Boolean = false, - val buyKinEnabled: Boolean = false, - val establishCodeRelationship: Boolean = false, - val chatUnsubEnabled: Boolean = false, - val tipsEnabled: Boolean = false, - val tipsChatEnabled: Boolean = false, - val tipsChatCashEnabled: Boolean = false, - val kadoWebViewEnabled: Boolean = false, - ) - sealed interface Event { data class UpdateSettings(val settings: BetaOptions) : Event data class Toggle(val setting: PrefsBool, val state: Boolean): Event @@ -58,29 +44,21 @@ class BetaFlagsViewModel @Inject constructor( it.setting, it.state ) + + when (it.setting) { + PrefsBool.SHARE_TWEET_TO_TIP -> { + pacman.enableTweetShare(it.state) + } + else -> Unit + } }.launchIn(viewModelScope) } companion object { - val updateStateForEvent: (Event) -> ((State) -> State) = { event -> + val updateStateForEvent: (Event) -> ((BetaOptions) -> BetaOptions) = { event -> when (event) { - is Event.UpdateSettings -> { state -> - with(event.settings) { - state.copy( - showNetworkDropOff = showNetworkDropOff, - canViewBuckets = canViewBuckets, - isVibrateOnScan = tickOnScan, - currencySelectionBalanceEnabled = balanceCurrencySelectionEnabled, - displayErrors = displayErrors, - giveRequestsEnabled = giveRequestsEnabled, - buyKinEnabled = buyModuleEnabled, - chatUnsubEnabled = chatUnsubEnabled, - tipsEnabled = tipsEnabled, - tipsChatEnabled = tipsChatEnabled, - tipsChatCashEnabled = tipsChatCashEnabled, - kadoWebViewEnabled = kadoWebViewEnabled, - ) - } + is Event.UpdateSettings -> { _ -> + event.settings } is Event.Toggle -> { state -> state } diff --git a/app/src/main/res/values/strings-universal.xml b/app/src/main/res/values/strings-universal.xml index a04e8d6a5..55d4736d5 100644 --- a/app/src/main/res/values/strings-universal.xml +++ b/app/src/main/res/values/strings-universal.xml @@ -24,6 +24,7 @@ Tip Chats Cash Currency Selection in Balance Buy Kin Internally + Share Tweets to Tip Show Errors If enabled, you\'ll gain the ability to tap the balance on the Balance screen to inspect individual bucket balances. If enabled, a \"No Connection\" badge will show on the scan screen when no internet is detected. @@ -37,6 +38,7 @@ If enabled, you\'ll gain the ability to chat with tippers. If enabled, you\'ll gain the ability to send Kin in Tip Chats. If enabled, the Buy Kin flow will open in an internal WebView. + If enabled, you\'ll gain the ability to share tweets directly from Twitter to Code to tip the author. %1$s %2$s Reset Tooltips diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index 15feed7ce..6820b088a 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -260,4 +260,7 @@ object Libs { const val sodium_bindings = "com.ionspin.kotlin:multiplatform-crypto-libsodium-bindings-android:${Versions.sodium_bindings}" const val fingerprint_pro = "com.fingerprint.android:pro:2.4.0" + + const val haze = "dev.chrisbanes.haze:haze:0.7.3" + const val process_phoenix = "com.jakewharton:process-phoenix:3.0.0" }