From 37ddc95d8395b24ed774b1b439042a641387431a Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Fri, 24 Jan 2025 07:27:13 -0300 Subject: [PATCH] Add profile picture in the incoming request screen when using a large device --- app/build.gradle | 2 + .../ui/components/EncryptDecryptData.kt | 4 + .../nostrsigner/ui/components/EventData.kt | 4 + .../ui/components/LoginWithPubKey.kt | 77 +++++++++++++++++++ .../nostrsigner/ui/components/SignMessage.kt | 4 + .../ui/components/SingleEventHomeScreen.kt | 3 + gradle/libs.versions.toml | 5 ++ 7 files changed, 99 insertions(+) diff --git a/app/build.gradle b/app/build.gradle index 35135d48..5e9d582f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -205,6 +205,8 @@ dependencies { implementation libs.appcompat implementation libs.work.runtime.ktx + implementation libs.material3.window + implementation libs.adaptive.android testImplementation libs.junit testImplementation libs.mockk diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/EncryptDecryptData.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/EncryptDecryptData.kt index 87149f4a..7102817e 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/EncryptDecryptData.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/EncryptDecryptData.kt @@ -33,11 +33,13 @@ import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.greenart7c3.nostrsigner.R +import com.greenart7c3.nostrsigner.models.Account import com.greenart7c3.nostrsigner.models.SignerType import kotlinx.coroutines.launch @Composable fun EncryptDecryptData( + account: Account, paddingValues: PaddingValues, content: String, encryptedData: String, @@ -63,6 +65,8 @@ fun EncryptDecryptData( .verticalScroll(rememberScrollState()) .padding(paddingValues), ) { + ProfilePicture(account) + val message = when (type) { SignerType.NIP44_ENCRYPT -> stringResource(R.string.encrypt_nip44) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/EventData.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/EventData.kt index 627391fa..456b00e7 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/EventData.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/EventData.kt @@ -29,6 +29,7 @@ import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.greenart7c3.nostrsigner.R +import com.greenart7c3.nostrsigner.models.Account import com.greenart7c3.nostrsigner.models.Permission import com.greenart7c3.nostrsigner.models.SignerType import com.greenart7c3.nostrsigner.service.model.AmberEvent @@ -36,6 +37,7 @@ import com.vitorpamplona.quartz.events.Event @Composable fun EventData( + account: Account, paddingValues: PaddingValues, shouldAcceptOrReject: Boolean?, remember: MutableState, @@ -59,6 +61,8 @@ fun EventData( .verticalScroll(rememberScrollState()) .padding(paddingValues), ) { + ProfilePicture(account) + val permission = Permission("sign_event", event.kind) val text = stringResource(R.string.wants_you_to_sign_a, permission.toLocalizedString(context)) packageName?.let { diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/LoginWithPubKey.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/LoginWithPubKey.kt index 45bf4cc8..eacf1fb1 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/LoginWithPubKey.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/LoginWithPubKey.kt @@ -10,15 +10,18 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.selection.selectable +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Check +import androidx.compose.material.icons.outlined.Person import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults @@ -27,7 +30,9 @@ import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.RadioButton import androidx.compose.material3.Text +import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf @@ -37,6 +42,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource @@ -44,9 +50,76 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.window.core.layout.WindowWidthSizeClass +import coil3.compose.AsyncImage +import com.greenart7c3.nostrsigner.BuildConfig +import com.greenart7c3.nostrsigner.NostrSigner import com.greenart7c3.nostrsigner.R import com.greenart7c3.nostrsigner.models.Account import com.greenart7c3.nostrsigner.models.Permission +import com.greenart7c3.nostrsigner.service.toShortenHex +import com.greenart7c3.nostrsigner.ui.fromHex +import com.greenart7c3.nostrsigner.ui.navigation.Route +import com.vitorpamplona.quartz.encoders.toHexKey +import com.vitorpamplona.quartz.encoders.toNpub +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +@Composable +fun ProfilePicture(account: Account) { + val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass + if (windowSizeClass.windowWidthSizeClass != WindowWidthSizeClass.COMPACT) { + var profileUrl by remember { mutableStateOf(null) } + LaunchedEffect(Unit) { + launch(Dispatchers.IO) { + NostrSigner.getInstance().fetchProfileData( + account = account, + onPictureFound = { + profileUrl = it + }, + ) + } + } + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + @Suppress("KotlinConstantConditions") + if (!profileUrl.isNullOrBlank() && BuildConfig.FLAVOR != "offline") { + AsyncImage( + profileUrl, + Route.Accounts.route, + Modifier + .clip( + RoundedCornerShape(50), + ) + .height(120.dp) + .width(120.dp), + ) + } else { + Icon( + Icons.Outlined.Person, + Route.Accounts.route, + modifier = Modifier + .border( + 2.dp, + Color.fromHex(account.signer.keyPair.pubKey.toHexKey().slice(0..5)), + CircleShape, + ) + .height(120.dp) + .width(120.dp), + ) + } + Text( + account.name.ifBlank { account.signer.keyPair.pubKey.toNpub().toShortenHex() }, + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + textAlign = TextAlign.Center, + ) + } + } +} @Composable fun LoginWithPubKey( @@ -76,6 +149,8 @@ fun LoginWithPubKey( .verticalScroll(rememberScrollState()) .padding(paddingValues), ) { + ProfilePicture(account) + packageName?.let { Text( modifier = Modifier @@ -146,6 +221,8 @@ fun LoginWithPubKey( .verticalScroll(rememberScrollState()) .padding(paddingValues), ) { + ProfilePicture(account) + packageName?.let { Text( modifier = Modifier diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/SignMessage.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/SignMessage.kt index 1fb92fc5..5fc1dfa7 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/SignMessage.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/SignMessage.kt @@ -33,11 +33,13 @@ import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.greenart7c3.nostrsigner.R +import com.greenart7c3.nostrsigner.models.Account import com.greenart7c3.nostrsigner.models.SignerType import kotlinx.coroutines.launch @Composable fun SignMessage( + account: Account, paddingValues: PaddingValues, content: String, shouldRunOnAccept: Boolean?, @@ -62,6 +64,8 @@ fun SignMessage( .verticalScroll(rememberScrollState()) .padding(paddingValues), ) { + ProfilePicture(account) + val message = stringResource(R.string.sign_message) packageName?.let { diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/SingleEventHomeScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/SingleEventHomeScreen.kt index 748d6f11..113b17c2 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/SingleEventHomeScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/SingleEventHomeScreen.kt @@ -188,6 +188,7 @@ fun SingleEventHomeScreen( packageName } SignMessage( + account, paddingValues, intentData.data, permission?.acceptable, @@ -330,6 +331,7 @@ fun SingleEventHomeScreen( packageName } EncryptDecryptData( + account, paddingValues, intentData.data, intentData.encryptedData ?: "", @@ -482,6 +484,7 @@ fun SingleEventHomeScreen( packageName } EventData( + account, paddingValues, permission?.acceptable, remember, diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 39680278..25eb1ee3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -28,6 +28,9 @@ ksp = "2.1.0-1.0.29" coil = "3.0.4" storage = "2.0.0" jna = "5.16.0" +material3AdaptiveAndroid = "1.0.0-alpha06" +material3AdaptiveNavigationSuiteAndroid = "1.3.1" +adaptiveAndroid = "1.0.0" [libraries] jna = { module = "net.java.dev.jna:jna", version.ref = "jna" } @@ -70,6 +73,8 @@ coil-gif = { group = "io.coil-kt.coil3", name = "coil-gif", version.ref = "coil" coil-svg = { group = "io.coil-kt.coil3", name = "coil-svg", version.ref = "coil" } coil-okhttp = { group = "io.coil-kt.coil3", name = "coil-network-okhttp", version.ref = "coil" } storage = { module = "com.anggrayudi:storage", version.ref = "storage" } +material3-window = { group = "androidx.compose.material3", name = "material3-window-size-class", version.ref = "material3" } +adaptive-android = { group = "androidx.compose.material3.adaptive", name = "adaptive-android", version.ref = "adaptiveAndroid" } [plugins] jetbrainsKotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }