mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-10-04 18:24:34 +02:00
Full Wallet Connect onboarding with Alby.
This commit is contained in:
@@ -43,6 +43,13 @@
|
||||
<data android:scheme="nostr" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:label="Amethyst">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="nostrwalletconnect" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.app.lib_name"
|
||||
android:value="" />
|
||||
|
@@ -21,6 +21,8 @@ import com.vitorpamplona.amethyst.LocalPreferences
|
||||
import com.vitorpamplona.amethyst.ServiceManager
|
||||
import com.vitorpamplona.amethyst.service.nip19.Nip19
|
||||
import com.vitorpamplona.amethyst.service.relays.Client
|
||||
import com.vitorpamplona.amethyst.ui.navigation.Route
|
||||
import com.vitorpamplona.amethyst.ui.note.Nip47
|
||||
import com.vitorpamplona.amethyst.ui.screen.AccountScreen
|
||||
import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel
|
||||
import com.vitorpamplona.amethyst.ui.theme.AmethystTheme
|
||||
@@ -28,6 +30,8 @@ import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
class MainActivity : FragmentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -40,6 +44,14 @@ class MainActivity : FragmentActivity() {
|
||||
Nip19.Type.EVENT -> "Event/${nip19.hex}"
|
||||
Nip19.Type.ADDRESS -> "Note/${nip19.hex}"
|
||||
else -> null
|
||||
} ?: try {
|
||||
intent?.data?.toString()?.let {
|
||||
Nip47.parse(it)
|
||||
val encodedUri = URLEncoder.encode(it, StandardCharsets.UTF_8.toString())
|
||||
Route.Home.base + "?nip47=" + encodedUri
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
Coil.setImageLoader {
|
||||
|
@@ -1,8 +1,12 @@
|
||||
package com.vitorpamplona.amethyst.ui.navigation
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
@@ -39,6 +43,7 @@ fun AppNavigation(
|
||||
nextPage: String? = null
|
||||
) {
|
||||
val homePagerState = rememberPagerState()
|
||||
var actionableNextPage by remember { mutableStateOf<String?>(nextPage) }
|
||||
|
||||
// Avoids creating ViewModels for performance reasons (up to 1 second delays)
|
||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||
@@ -76,8 +81,9 @@ fun AppNavigation(
|
||||
}
|
||||
|
||||
Route.Home.let { route ->
|
||||
composable(route.route, route.arguments, content = {
|
||||
composable(route.route, route.arguments, content = { it ->
|
||||
val scrollToTop = it.arguments?.getBoolean("scrollToTop") ?: false
|
||||
val nip47 = it.arguments?.getString("nip47")
|
||||
|
||||
HomeScreen(
|
||||
homeFeedViewModel = homeFeedViewModel,
|
||||
@@ -85,13 +91,17 @@ fun AppNavigation(
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController,
|
||||
pagerState = homePagerState,
|
||||
scrollToTop = scrollToTop
|
||||
scrollToTop = scrollToTop,
|
||||
nip47 = nip47
|
||||
)
|
||||
|
||||
// Avoids running scroll to top when back button is pressed
|
||||
if (scrollToTop) {
|
||||
it.arguments?.remove("scrollToTop")
|
||||
}
|
||||
if (nip47 != null) {
|
||||
it.arguments?.remove("nip47")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -178,7 +188,10 @@ fun AppNavigation(
|
||||
}
|
||||
}
|
||||
|
||||
if (nextPage != null) {
|
||||
navController.navigate(nextPage)
|
||||
actionableNextPage?.let {
|
||||
LaunchedEffect(it) {
|
||||
navController.navigate(it)
|
||||
}
|
||||
actionableNextPage = null
|
||||
}
|
||||
}
|
||||
|
@@ -24,9 +24,12 @@ sealed class Route(
|
||||
get() = route.substringBefore("?")
|
||||
|
||||
object Home : Route(
|
||||
route = "Home?scrollToTop={scrollToTop}",
|
||||
route = "Home?scrollToTop={scrollToTop}&nip47={nip47}",
|
||||
icon = R.drawable.ic_home,
|
||||
arguments = listOf(navArgument("scrollToTop") { type = NavType.BoolType; defaultValue = false }),
|
||||
arguments = listOf(
|
||||
navArgument("scrollToTop") { type = NavType.BoolType; defaultValue = false },
|
||||
navArgument("nip47") { type = NavType.StringType; nullable = true; defaultValue = null }
|
||||
),
|
||||
hasNewItems = { accountViewModel, cache -> homeHasNewItems(accountViewModel, cache) }
|
||||
)
|
||||
|
||||
|
@@ -49,6 +49,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
@@ -165,17 +166,40 @@ class UpdateZapAmountViewModel : ViewModel() {
|
||||
walletConnectSecret.text != (account?.zapPaymentRequest?.secret ?: "")
|
||||
)
|
||||
}
|
||||
|
||||
fun updateNIP47(uri: String) {
|
||||
val contact = Nip47.parse(uri)
|
||||
if (contact != null) {
|
||||
walletConnectPubkey =
|
||||
TextFieldValue(contact.pubKeyHex)
|
||||
walletConnectRelay =
|
||||
TextFieldValue(contact.relayUri ?: "")
|
||||
walletConnectSecret =
|
||||
TextFieldValue(contact.secret ?: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
fun UpdateZapAmountDialog(onClose: () -> Unit, account: Account) {
|
||||
fun UpdateZapAmountDialog(onClose: () -> Unit, account: Account, nip47uri: String? = null) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val postViewModel: UpdateZapAmountViewModel = viewModel()
|
||||
val uri = LocalUriHandler.current
|
||||
|
||||
LaunchedEffect(account) {
|
||||
postViewModel.load(account)
|
||||
if (nip47uri != null) {
|
||||
try {
|
||||
postViewModel.updateNIP47(nip47uri)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
scope.launch {
|
||||
Toast.makeText(context, e.message, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dialog(
|
||||
@@ -299,6 +323,18 @@ fun UpdateZapAmountDialog(onClose: () -> Unit, account: Account) {
|
||||
stringResource(id = R.string.wallet_connect_service),
|
||||
Modifier.weight(1f)
|
||||
)
|
||||
|
||||
IconButton(onClick = {
|
||||
runCatching { uri.openUri("https://nwc.getalby.com/apps/new?c=Amethyst") }
|
||||
}) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.alby),
|
||||
null,
|
||||
modifier = Modifier.size(24.dp),
|
||||
tint = Color.Unspecified
|
||||
)
|
||||
}
|
||||
|
||||
IconButton(onClick = {
|
||||
qrScanning = true
|
||||
}) {
|
||||
@@ -330,15 +366,7 @@ fun UpdateZapAmountDialog(onClose: () -> Unit, account: Account) {
|
||||
qrScanning = false
|
||||
if (!it.isNullOrEmpty()) {
|
||||
try {
|
||||
val contact = Nip47.parse(it)
|
||||
if (contact != null) {
|
||||
postViewModel.walletConnectPubkey =
|
||||
TextFieldValue(contact.pubKeyHex)
|
||||
postViewModel.walletConnectRelay =
|
||||
TextFieldValue(contact.relayUri ?: "")
|
||||
postViewModel.walletConnectSecret =
|
||||
TextFieldValue(contact.secret ?: "")
|
||||
}
|
||||
postViewModel.updateNIP47(it)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
scope.launch {
|
||||
Toast.makeText(context, e.message, Toast.LENGTH_SHORT)
|
||||
|
@@ -11,7 +11,11 @@ import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.compose.ui.res.stringResource
|
||||
@@ -28,6 +32,7 @@ import com.vitorpamplona.amethyst.service.NostrHomeDataSource
|
||||
import com.vitorpamplona.amethyst.ui.dal.HomeConversationsFeedFilter
|
||||
import com.vitorpamplona.amethyst.ui.dal.HomeNewThreadFeedFilter
|
||||
import com.vitorpamplona.amethyst.ui.navigation.Route
|
||||
import com.vitorpamplona.amethyst.ui.note.UpdateZapAmountDialog
|
||||
import com.vitorpamplona.amethyst.ui.screen.FeedView
|
||||
import com.vitorpamplona.amethyst.ui.screen.NostrHomeFeedViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.NostrHomeRepliesFeedViewModel
|
||||
@@ -42,10 +47,12 @@ fun HomeScreen(
|
||||
accountViewModel: AccountViewModel,
|
||||
navController: NavController,
|
||||
pagerState: PagerState,
|
||||
scrollToTop: Boolean = false
|
||||
scrollToTop: Boolean = false,
|
||||
nip47: String? = null
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val account = accountViewModel.accountLiveData.value?.account ?: return
|
||||
var wantsToAddNip47 by remember { mutableStateOf<String?>(nip47) }
|
||||
|
||||
LaunchedEffect(accountViewModel) {
|
||||
HomeNewThreadFeedFilter.account = account
|
||||
@@ -55,6 +62,10 @@ fun HomeScreen(
|
||||
repliesFeedViewModel.invalidateData()
|
||||
}
|
||||
|
||||
if (wantsToAddNip47 != null) {
|
||||
UpdateZapAmountDialog({ wantsToAddNip47 = null }, account = account, wantsToAddNip47)
|
||||
}
|
||||
|
||||
val lifeCycleOwner = LocalLifecycleOwner.current
|
||||
DisposableEffect(accountViewModel) {
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
|
@@ -1,39 +1,58 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="250dp"
|
||||
android:height="250dp"
|
||||
android:viewportWidth="250"
|
||||
android:viewportHeight="250">
|
||||
android:width="489dp"
|
||||
android:height="489dp"
|
||||
android:viewportWidth="489"
|
||||
android:viewportHeight="489">
|
||||
<path
|
||||
android:pathData="M48.12,70.63m18.75,0a18.75,18.75 0,1 0,-37.5 0a18.75,18.75 0,1 0,37.5 0"
|
||||
android:fillColor="#000000"/>
|
||||
android:pathData="M89.58,181.77C96.83,182.51 103.84,181.66 110.26,179.49L110.42,179.63L110.66,179.87C83.35,210.92 64.09,251.1 56.14,295.56C50.5,327.03 67.39,357.29 95.35,370.61C140.92,392.29 191.9,404.42 245.64,404.42C299.39,404.42 349.32,392.54 394.53,371.27C422.59,358.07 439.6,327.82 434.06,296.31C426.2,251.6 406.52,211.48 379.48,179.96C345.33,140.15 379.58,179.8 379.58,179.8C379.58,179.8 391.32,182.34 397.62,181.9C421.93,180.22 441.52,160.37 442.89,136.03C444.51,106.88 420.52,82.9 391.36,84.54C367.36,85.89 347.63,105.01 345.58,128.97C344.95,136.44 346.01,143.62 348.41,150.15L348.02,150.54L347.79,150.77C318.32,129.03 283.17,116.22 245.05,116.22C206.93,116.22 171.54,129.12 141.99,151.01L141.77,150.78L141.4,150.42L140.69,149.71C143.01,143.22 144.01,136.11 143.33,128.71C141.16,104.88 121.47,85.9 97.57,84.55C68.36,82.92 44.37,106.91 46.01,136.09C47.34,159.78 65.97,179.34 89.56,181.78L89.58,181.77Z"
|
||||
android:strokeWidth="19.962"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M45,67.82L80,102.82"
|
||||
android:strokeWidth="9.37484"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M201.25,70.63m-18.75,0a18.75,18.75 0,1 1,37.5 0a18.75,18.75 0,1 1,-37.5 0"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M204.68,67.82L169.68,102.82"
|
||||
android:strokeWidth="9.37484"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M53.45,182.51C43.34,177.7 37.46,166.9 39.43,155.88C47.89,108.59 83.12,73.13 125.31,73.13C167.6,73.13 202.91,108.77 211.25,156.23C213.19,167.26 207.26,178.06 197.12,182.83C175.43,193.04 151.19,198.75 125.62,198.75C99.79,198.75 75.32,192.92 53.45,182.51Z"
|
||||
android:pathData="M104.48,351.42C84.72,342.01 73.22,320.89 77.07,299.33C85.11,254.32 105.57,214.8 133.95,186.08C138.28,181.69 142.81,177.57 147.49,173.7C175.19,150.87 208.78,137.51 244.99,137.51C281.2,137.51 314.55,150.78 342.19,173.45C346.89,177.3 351.41,181.43 355.76,185.81C384.43,214.69 405.06,254.58 413.04,300.02C416.84,321.6 405.24,342.72 385.41,352.05C342.98,372.01 295.59,383.17 245.6,383.17C195.6,383.17 147.22,371.79 104.45,351.42H104.48Z"
|
||||
android:fillColor="#FFDF6F"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M211.25,156.23L206.64,157.04L211.25,156.23ZM53.45,182.51L51.43,186.74L53.45,182.51ZM44.04,156.71C52.21,111.01 85.99,77.82 125.31,77.82V68.44C80.26,68.44 43.56,106.17 34.82,155.06L44.04,156.71ZM125.31,77.82C164.73,77.82 198.57,111.18 206.64,157.04L215.87,155.41C207.24,106.36 170.47,68.44 125.31,68.44V77.82ZM195.13,178.59C174.04,188.51 150.49,194.06 125.62,194.06V203.44C151.9,203.44 176.81,197.57 199.12,187.07L195.13,178.59ZM125.62,194.06C100.5,194.06 76.71,188.4 55.46,178.28L51.43,186.74C73.92,197.45 99.08,203.44 125.62,203.44V194.06ZM206.64,157.04C208.19,165.89 203.45,174.67 195.13,178.59L199.12,187.07C211.07,181.45 218.2,168.64 215.87,155.41L206.64,157.04ZM34.82,155.06C32.45,168.26 39.52,181.07 51.43,186.74L55.46,178.28C47.16,174.33 42.46,165.54 44.04,156.71L34.82,155.06Z"
|
||||
android:pathData="M95.07,121.28L82.11,134.24L112.95,165.08C118.32,161.99 122.85,157.57 126.06,152.26L95.07,121.28Z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M71.48,170.76C63.34,167.44 58.52,158.79 61.34,150.47C70.03,124.82 95.38,106.25 125.31,106.25C155.24,106.25 180.59,124.82 189.29,150.47C192.1,158.79 187.28,167.44 179.14,170.76C162.53,177.52 144.36,181.25 125.31,181.25C106.26,181.25 88.09,177.52 71.48,170.76Z"
|
||||
android:pathData="M394.79,96.61C374.95,96.28 357.68,113.06 357.49,132.9C357.41,140.15 359.45,146.93 363.03,152.66L394.39,121.29L407.36,134.26L376.3,165.3C382.44,168.73 389.68,170.45 397.35,169.8C415.01,168.3 429.27,153.98 430.7,136.32C432.42,114.9 415.73,96.96 394.79,96.61ZM363.03,152.66L348.73,166.94C353.43,170.82 357.94,174.97 362.27,179.33L376.3,165.3C370.87,162.28 366.3,157.91 363.03,152.66ZM422.09,298.44C413.84,251.46 392.38,209.71 362.27,179.33L355.79,185.81C351.44,181.43 346.92,177.31 342.22,173.47L348.73,166.94C319.53,142.71 283.85,128.37 245.01,128.37C206.16,128.37 170.25,142.8 140.99,167.2L147.51,173.71C142.81,177.57 138.3,181.71 133.97,186.1L127.49,179.62C97.66,209.82 76.37,251.19 68.04,297.74C63.44,323.55 77.25,348.61 100.54,359.7C144.51,380.63 193.71,392.35 245.63,392.35C297.54,392.35 345.72,380.87 389.35,360.35C412.72,349.34 426.65,324.29 422.09,298.44ZM381.54,343.75C340.31,363.17 294.24,374.01 245.63,374.01C197.01,374.01 149.99,362.94 108.42,343.15C92.2,335.42 83,318.23 86.09,300.97C93.86,257.51 113.49,219.81 140.45,192.57L154.03,180.24C180.14,158.99 211.55,146.69 245.01,146.69C278.46,146.69 309.63,158.88 335.69,179.98L349.31,192.29C376.54,219.69 396.33,257.73 404.04,301.61C407.08,318.92 397.82,336.11 381.54,343.75ZM126.08,152.28C122.87,157.58 118.34,161.99 112.96,165.09L127.49,179.62C131.82,175.23 136.31,171.09 140.99,167.2L126.08,152.28ZM126.08,152.28C129.56,146.54 131.51,139.77 131.38,132.56C130.98,112.5 114.04,96.21 93.97,96.61C73.05,97.03 56.44,114.95 58.17,136.32C59.61,154.07 74.01,168.43 91.76,169.82C99.51,170.42 106.8,168.61 112.96,165.09L82.13,134.26L95.09,121.29L126.08,152.28Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M131.25,146.25a15.62,12.5 0,1 0,31.25 0a15.62,12.5 0,1 0,-31.25 0z"
|
||||
android:pathData="M407.36,134.26L376.3,165.3C370.87,162.28 366.3,157.91 363.03,152.66L394.39,121.29L407.36,134.26Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M362.27,179.33L355.79,185.81C351.44,181.43 346.92,177.32 342.22,173.47L348.73,166.94C353.43,170.82 357.94,174.97 362.27,179.33Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M147.51,173.71C142.81,177.57 138.3,181.71 133.97,186.1L127.49,179.62C131.82,175.23 136.31,171.09 140.99,167.2L147.51,173.71Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M126.08,152.28C122.87,157.58 118.34,161.99 112.96,165.09L82.13,134.26L95.09,121.29L126.08,152.28Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M407.36,134.24L376.3,165.29C370.87,162.26 366.3,157.9 363.03,152.64L394.39,121.28L407.36,134.24Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M348.73,166.93L342.2,173.45C346.9,177.3 351.43,181.43 355.77,185.81L362.26,179.33C357.92,174.95 353.41,170.82 348.73,166.94V166.93Z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M140.98,167.18C136.3,171.07 131.8,175.23 127.47,179.6L133.95,186.08C138.28,181.69 142.81,177.57 147.49,173.7L140.98,167.18Z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M140.37,329.06C124.47,322.58 115.04,305.67 120.55,289.4C137.54,239.24 187.12,202.92 245.64,202.92C304.16,202.92 353.74,239.23 370.75,289.4C376.27,305.67 366.83,322.6 350.93,329.06C318.44,342.3 282.9,349.58 245.66,349.58C208.42,349.58 172.87,342.3 140.39,329.06H140.37Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M287.82,305.59C304.7,305.59 318.38,294.65 318.38,281.15C318.38,267.65 304.7,256.7 287.82,256.7C270.94,256.7 257.26,267.65 257.26,281.15C257.26,294.65 270.94,305.59 287.82,305.59Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M86.52,146.26a15.62,12.5 0,1 0,31.25 0a15.62,12.5 0,1 0,-31.25 0z"
|
||||
android:pathData="M200.35,305.61C217.22,305.61 230.91,294.66 230.91,281.16C230.91,267.66 217.22,256.72 200.35,256.72C183.47,256.72 169.78,267.66 169.78,281.16C169.78,294.66 183.47,305.61 200.35,305.61Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
||||
|
Reference in New Issue
Block a user