From 36ec4a18d89628b724bdc3d7953d2aeb02f82362 Mon Sep 17 00:00:00 2001
From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Date: Fri, 12 Jun 2026 11:08:52 -0700
Subject: [PATCH 1/2] feat: add export/share button to the Logs screen
Fixes #468
---
.../greenart7c3/nostrsigner/ui/LogsScreen.kt | 66 ++++++++++++++++---
app/src/main/res/values/strings.xml | 1 +
2 files changed, 58 insertions(+), 9 deletions(-)
diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/LogsScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/LogsScreen.kt
index c3024a53..92e0c635 100644
--- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/LogsScreen.kt
+++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/LogsScreen.kt
@@ -1,11 +1,13 @@
package com.greenart7c3.nostrsigner.ui
+import android.content.Intent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
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.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
@@ -17,6 +19,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
@@ -30,7 +33,9 @@ import com.greenart7c3.nostrsigner.models.Account
import com.greenart7c3.nostrsigner.models.TimeUtils
import com.greenart7c3.nostrsigner.ui.components.AmberButton
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
@Composable
fun LogsScreen(
@@ -38,6 +43,7 @@ fun LogsScreen(
account: Account,
) {
val scope = rememberCoroutineScope()
+ val context = LocalContext.current
val pager =
Pager(
PagingConfig(
@@ -58,15 +64,57 @@ fun LogsScreen(
contentPadding = paddingValues,
) {
item {
- AmberButton(
- modifier = Modifier.padding(bottom = 8.dp),
- onClick = {
- scope.launch(Dispatchers.IO) {
- Amber.instance.getLogDatabase(account.npub).dao().clearLogs()
- }
- },
- text = stringResource(R.string.clear_logs),
- )
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(bottom = 8.dp),
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ ) {
+ AmberButton(
+ modifier = Modifier.weight(1f),
+ onClick = {
+ scope.launch(Dispatchers.IO) {
+ val logs =
+ Amber.instance
+ .getLogDatabase(account.npub)
+ .dao()
+ .getLogs()
+ .first()
+ val logsText =
+ logs.joinToString("\n") { log ->
+ val time =
+ TimeUtils.formatLongToCustomDateTimeWithSeconds(log.time)
+ "$time | ${log.url} | ${log.type} | ${log.message}"
+ }
+
+ withContext(Dispatchers.Main) {
+ val shareIntent =
+ Intent(Intent.ACTION_SEND).apply {
+ type = "text/plain"
+ putExtra(Intent.EXTRA_TEXT, logsText)
+ }
+
+ context.startActivity(
+ Intent.createChooser(
+ shareIntent,
+ context.getString(R.string.export_logs),
+ ),
+ )
+ }
+ }
+ },
+ text = stringResource(R.string.export_logs),
+ )
+ AmberButton(
+ modifier = Modifier.weight(1f),
+ onClick = {
+ scope.launch(Dispatchers.IO) {
+ Amber.instance.getLogDatabase(account.npub).dao().clearLogs()
+ }
+ },
+ text = stringResource(R.string.clear_logs),
+ )
+ }
}
items(lazyPagingItems.itemCount) { index ->
val log = lazyPagingItems[index]
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9c0f237f..8b142abd 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -240,6 +240,7 @@
Private outbox relay list
Save
Logs
+ Export logs
Clear logs
Default relays
requests
From 6bd003acea856892d5846ee0655a4ee30c1afacf Mon Sep 17 00:00:00 2001
From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Date: Fri, 12 Jun 2026 11:16:56 -0700
Subject: [PATCH 2/2] fix: address self-review findings
---
.../com/greenart7c3/nostrsigner/ui/LogsScreen.kt | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/LogsScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/LogsScreen.kt
index 92e0c635..18446043 100644
--- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/LogsScreen.kt
+++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/LogsScreen.kt
@@ -24,6 +24,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import androidx.core.content.FileProvider
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.compose.collectAsLazyPagingItems
@@ -32,6 +33,7 @@ import com.greenart7c3.nostrsigner.R
import com.greenart7c3.nostrsigner.models.Account
import com.greenart7c3.nostrsigner.models.TimeUtils
import com.greenart7c3.nostrsigner.ui.components.AmberButton
+import java.io.File
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
@@ -86,12 +88,21 @@ fun LogsScreen(
TimeUtils.formatLongToCustomDateTimeWithSeconds(log.time)
"$time | ${log.url} | ${log.type} | ${log.message}"
}
+ val logsFile = File(context.cacheDir, "amber-logs.txt")
+ logsFile.writeText(logsText)
+ val logsUri =
+ FileProvider.getUriForFile(
+ context,
+ "${context.packageName}.fileprovider",
+ logsFile,
+ )
withContext(Dispatchers.Main) {
val shareIntent =
Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
- putExtra(Intent.EXTRA_TEXT, logsText)
+ putExtra(Intent.EXTRA_STREAM, logsUri)
+ addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
context.startActivity(