Make downloadText work on native

This commit is contained in:
Jon Staab 2026-07-08 14:53:49 -07:00
parent 47be12ff57
commit ba7a690d6f
2 changed files with 43 additions and 9 deletions

View file

@ -39,7 +39,7 @@
.replace(/NEWLINE/g, "\n\n")
.trim()
const downloadKey = () => {
const downloadKey = async () => {
const sharedCopy = `
Most online services keep track of users by giving them a username and password. This gives the
service total control over their users, allowing them to ban them at any time, or sell their activity.
@ -52,6 +52,8 @@
account.
`
let instructions: string
if (usePassword) {
if (password.length < 12) {
return pushToast({
@ -61,7 +63,7 @@
}
const ncryptsec = encrypt(hexToBytes(secret), password)
const instructions = `
instructions = `
This file contains a backup of your Nostr secret key, downloaded from ${PLATFORM_NAME} and encrypted using
a password you chose when you signed up.
@ -74,11 +76,9 @@
To use it to log in to other Nostr apps, find a Nostr Signer app (https://nostrapps.com/#signers is a good
place to look), and import your key.
`
downloadText("Nostr Secret Key.txt", cleanupCopy(instructions))
} else {
const nsec = nsecEncode(hexToBytes(secret))
const instructions = `
instructions = `
This file contains a backup of your Nostr secret key, downloaded from ${PLATFORM_NAME}.
${sharedCopy}
@ -90,11 +90,23 @@
To use it to log in to other Nostr apps, find a Nostr Signer app (https://nostrapps.com/#signers is a good
place to look), and import your key.
`
downloadText("Nostr Secret Key.txt", cleanupCopy(instructions))
}
didDownload = true
try {
await downloadText("Nostr Secret Key.txt", cleanupCopy(instructions))
didDownload = true
} catch (e) {
// Dismissing the native share sheet rejects with "Share canceled" — leave
// the flow gated so the user can try again rather than showing an error.
if (
!String((e as any)?.message || e)
.toLowerCase()
.includes("cancel")
) {
pushToast({theme: "error", message: "We couldn't save your key. Please try again."})
}
}
}
const onPasswordChange = () => {

View file

@ -1,4 +1,5 @@
import {sleep, randomId} from "@welshman/lib"
import {Capacitor} from "@capacitor/core"
export {preventDefault, stopPropagation} from "svelte/legacy"
// Anchors an @svelte-plugins/datepicker popup with fixed positioning so it
@ -127,7 +128,28 @@ export const createScroller = ({
export const isMobile = "ontouchstart" in document.documentElement
export const downloadText = (filename: string, text: string) => {
export const downloadText = async (filename: string, text: string) => {
// The <a download> blob trick is a no-op in native WebViews (Android in
// particular never triggers a download), so on device we write the file and
// hand it to the native share sheet, letting the user save it to Files,
// Drive, a password manager, etc. Cache is the directory our FileProvider
// (android/app/src/main/res/xml/file_paths.xml) is configured to serve.
if (Capacitor.isNativePlatform()) {
const {Filesystem, Directory, Encoding} = await import("@capacitor/filesystem")
const {Share} = await import("@capacitor/share")
const {uri} = await Filesystem.writeFile({
path: filename,
data: text,
directory: Directory.Cache,
encoding: Encoding.UTF8,
})
await Share.share({title: filename, files: [uri]})
return
}
const blob = new Blob([text], {type: "text/plain"})
const url = URL.createObjectURL(blob)
const a = document.createElement("a")