created history screen

This commit is contained in:
greenart7c3
2023-10-16 17:34:13 -03:00
parent 776e68f0cd
commit a902c63adf
6 changed files with 118 additions and 8 deletions
@@ -4,7 +4,10 @@ import android.annotation.SuppressLint
import android.content.Context
import android.content.SharedPreferences
import androidx.compose.runtime.Immutable
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.greenart7c3.nostrsigner.models.Account
import com.greenart7c3.nostrsigner.models.History
import com.greenart7c3.nostrsigner.service.KeyPair
import com.vitorpamplona.quartz.encoders.hexToByteArray
import com.vitorpamplona.quartz.encoders.toHexKey
@@ -25,6 +28,7 @@ private object PrefKeys {
const val NOSTR_PRIVKEY = "nostr_privkey"
const val NOSTR_PUBKEY = "nostr_pubkey"
const val REMEMBER_APPS = "remember_apps"
const val HISTORY = "history"
const val ACCOUNT_NAME = "account_name"
}
@@ -185,6 +189,8 @@ object LocalPreferences {
val jsonObject = JSONObject(account.savedApps.toMap())
putString(PrefKeys.REMEMBER_APPS, jsonObject.toString())
putString(PrefKeys.ACCOUNT_NAME, account.name)
val historyObject = Gson().toJson(account.history)
putString(PrefKeys.HISTORY, historyObject)
}.apply()
}
@@ -204,6 +210,14 @@ object LocalPreferences {
}
}
fun loadHistory(npub: String?): MutableList<History> {
encryptedPreferences(npub).apply {
val historyJson = getString(PrefKeys.HISTORY, "[]") ?: "[]"
val listType = object : TypeToken<List<History>>() {}.type
return Gson().fromJson<List<History>>(historyJson, listType).toMutableList()
}
}
fun loadFromEncryptedStorage(npub: String?): Account? {
encryptedPreferences(npub).apply {
val pubKey = getString(PrefKeys.NOSTR_PUBKEY, null) ?: return null
@@ -222,10 +236,15 @@ object LocalPreferences {
}
val name = getString(PrefKeys.ACCOUNT_NAME, "") ?: ""
val historyJson = getString(PrefKeys.HISTORY, "[]") ?: "[]"
val listType = object : TypeToken<List<History>>() {}.type
val history = Gson().fromJson<List<History>>(historyJson, listType).toMutableList()
return Account(
keyPair = KeyPair(privKey = privKey?.hexToByteArray(), pubKey = pubKey.hexToByteArray()),
name = name,
savedApps = outputMap
savedApps = outputMap,
history = history
)
}
}
@@ -5,7 +5,9 @@ import android.content.ContentValues
import android.database.Cursor
import android.database.MatrixCursor
import android.net.Uri
import com.greenart7c3.nostrsigner.models.History
import com.greenart7c3.nostrsigner.models.SignerType
import com.greenart7c3.nostrsigner.models.TimeUtils
import com.greenart7c3.nostrsigner.service.AmberUtils
import com.greenart7c3.nostrsigner.service.model.AmberEvent
import com.vitorpamplona.quartz.encoders.toNpub
@@ -61,6 +63,10 @@ class SignerProvider : ContentProvider() {
AmberEvent.fromJson(json),
account.keyPair.privKey
)
account.history.add(History(packageName, "SIGN_EVENT", TimeUtils.now()))
LocalPreferences.saveToEncryptedStorage(account)
val cursor = MatrixCursor(arrayOf("signature", "event"))
cursor.addRow(arrayOf(signedEvent.sig, signedEvent.toJson()))
return cursor
@@ -99,6 +105,10 @@ class SignerProvider : ContentProvider() {
} catch (e: Exception) {
"Could not decrypt the message"
}
account.history.add(History(packageName, stringType, TimeUtils.now()))
LocalPreferences.saveToEncryptedStorage(account)
if (type == SignerType.NIP04_ENCRYPT && result == "Could not decrypt the message") {
return null
} else {
@@ -115,6 +125,9 @@ class SignerProvider : ContentProvider() {
val isRemembered = account.savedApps[key] ?: false
if (!isRemembered) return null
account.history.add(History(packageName, "GET_PUBLIC_KEY", TimeUtils.now()))
LocalPreferences.saveToEncryptedStorage(account)
val cursor = MatrixCursor(arrayOf("signature"))
cursor.addRow(arrayOf<Any>(account.keyPair.pubKey.toNpub()))
return cursor
@@ -5,11 +5,18 @@ import androidx.compose.runtime.Stable
import androidx.lifecycle.LiveData
import com.greenart7c3.nostrsigner.service.KeyPair
class History(
val appName: String,
val type: String,
val time: Long
)
@Stable
class Account(
val keyPair: KeyPair,
var name: String,
var savedApps: MutableMap<String, Boolean>
var savedApps: MutableMap<String, Boolean>,
var history: MutableList<History> = mutableListOf()
) {
val saveable: AccountLiveData = AccountLiveData(this)
}
@@ -82,7 +82,8 @@ fun HomeScreen(
sig,
"",
sig,
it.callBackUrl
it.callBackUrl,
it.type
)
}
return@LoginWithPubKey
@@ -157,7 +158,8 @@ fun HomeScreen(
result,
it.id,
result,
it.callBackUrl
it.callBackUrl,
it.type
)
}
}
@@ -247,7 +249,8 @@ fun HomeScreen(
resultEvent.toJson(),
it.id,
resultEvent.toJson(),
it.callBackUrl
it.callBackUrl,
it.type
)
}
} else {
@@ -267,7 +270,8 @@ fun HomeScreen(
signedEvent.toJson(),
it.id,
signedEvent.sig,
it.callBackUrl
it.callBackUrl,
it.type
)
}
}
@@ -4,17 +4,22 @@ import android.app.Activity.RESULT_OK
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.text.format.DateUtils
import android.widget.Toast
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ExpandMore
import androidx.compose.material3.Card
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
@@ -35,6 +40,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ClipboardManager
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.text.toLowerCase
import androidx.compose.ui.unit.dp
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
@@ -45,7 +52,10 @@ import androidx.navigation.navArgument
import com.greenart7c3.nostrsigner.LocalPreferences
import com.greenart7c3.nostrsigner.R
import com.greenart7c3.nostrsigner.models.Account
import com.greenart7c3.nostrsigner.models.History
import com.greenart7c3.nostrsigner.models.IntentData
import com.greenart7c3.nostrsigner.models.SignerType
import com.greenart7c3.nostrsigner.models.TimeUtils
import com.greenart7c3.nostrsigner.service.getAppCompatActivity
import com.greenart7c3.nostrsigner.service.toShortenHex
import com.greenart7c3.nostrsigner.ui.actions.AccountsBottomSheet
@@ -66,13 +76,15 @@ fun sendResult(
event: String,
id: String,
value: String,
callBackUrl: String?
callBackUrl: String?,
type: SignerType
) {
val activity = context.getAppCompatActivity()
if (packageName != null) {
if (rememberChoice) {
account.savedApps[key] = rememberChoice
}
account.history.add(History(packageName, type.toString(), TimeUtils.now()))
LocalPreferences.saveToEncryptedStorage(account)
val intent = Intent()
intent.putExtra("signature", value)
@@ -114,7 +126,7 @@ fun MainScreen(
) {
val navController = rememberNavController()
val navBackStackEntry by navController.currentBackStackEntryAsState()
val items = listOf(Route.Home, Route.Permissions, Route.Settings)
val items = listOf(Route.Home, Route.Permissions, Route.History, Route.Settings)
var shouldShowBottomSheet by remember { mutableStateOf(false) }
val sheetState = rememberModalBottomSheetState(
@@ -237,6 +249,37 @@ fun MainScreen(
}
)
composable(
Route.History.route,
content = {
val history = LocalPreferences.loadHistory(account.keyPair.pubKey.toNpub())
LazyColumn(
Modifier
.fillMaxSize()
.padding(padding)
.padding(16.dp)
) {
items(history.size) {
Card(
Modifier
.fillMaxWidth()
.padding(4.dp)
) {
Column(
Modifier
.fillMaxWidth()
.padding(8.dp)
) {
Text(history[it].appName)
Text(history[it].type.toLowerCase(Locale.current))
Text(timeAgoShort(history[it].time, "now"))
}
}
}
}
}
)
composable(
Route.Permission.route,
arguments = listOf(navArgument("packageName") { type = NavType.StringType }),
@@ -255,3 +298,19 @@ fun MainScreen(
}
}
}
fun timeAgoShort(mills: Long?, stringForNow: String): String {
if (mills == null) return " "
var humanReadable = DateUtils.getRelativeTimeSpanString(
mills * 1000,
System.currentTimeMillis(),
DateUtils.MINUTE_IN_MILLIS,
DateUtils.FORMAT_ABBREV_ALL
).toString()
if (humanReadable.startsWith("In") || humanReadable.startsWith("0")) {
humanReadable = stringForNow
}
return humanReadable
}
@@ -1,9 +1,11 @@
package com.greenart7c3.nostrsigner.ui.navigation
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.History
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.ViewList
import androidx.compose.material.icons.outlined.History
import androidx.compose.material.icons.outlined.Home
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material.icons.outlined.ViewList
@@ -39,4 +41,10 @@ sealed class Route(
icon = Icons.Outlined.ViewList,
selectedIcon = Icons.Default.ViewList
)
data object History : Route(
route = "History",
icon = Icons.Outlined.History,
selectedIcon = Icons.Default.History
)
}