Fix image uploads on ios

This commit is contained in:
Jon Staab
2026-02-02 14:06:36 -08:00
parent 7fc508603f
commit 75ec7688b1
2 changed files with 67 additions and 3 deletions
+50 -1
View File
@@ -1,6 +1,7 @@
<script lang="ts">
import type {Instance} from "tippy.js"
import {writable} from "svelte/store"
import {once} from "@welshman/lib"
import type {EventContent} from "@welshman/util"
import {isMobile, preventDefault} from "@lib/html"
import GallerySend from "@assets/icons/gallery-send.svg?dataurl"
@@ -44,7 +45,55 @@
}
}
const uploadFiles = () => editor.then(ed => ed.chain().selectFiles().run())
const uploadFiles = () =>
// TODO: go back to the following command after PR is released
// https://github.com/cesardeazevedo/nostr-editor/pull/37
// editor.then(ed => ed.chain().selectFiles().run())
editor.then(ed => {
const input = document.createElement("input")
input.type = "file"
input.multiple = true
input.accept = "image/jpeg,image/png,image/gif,video/mp4,video/mpeg,video/webm"
input.style.display = "none"
const cleanup = () => {
input.removeEventListener("change", handleFiles)
input.removeEventListener("input", handleFiles)
input.removeEventListener("cancel", cleanup)
if (input.parentNode) {
input.parentNode.removeChild(input)
}
}
const handleFiles = once((event: Event) => {
const files = (event.target as HTMLInputElement).files
if (files) {
Array.from(files).forEach(file => {
if (file) {
ed.commands.addFile(file, ed.view.state.selection.from + 1)
}
})
}
cleanup()
})
// Add both change and input listeners for iOS compatibility
input.addEventListener("change", handleFiles)
input.addEventListener("input", handleFiles)
input.addEventListener("cancel", cleanup)
// Attach to DOM for iOS compatibility
document.body.appendChild(input)
// Small delay for iOS WebView
setTimeout(() => {
input.click()
}, 100)
})
const showPopover = () => popover?.show()
+17 -2
View File
@@ -43,7 +43,6 @@ import {
toNostrURI,
RelayMode,
getTagValues,
uploadBlob,
canUploadBlob,
encryptFile,
makeBlossomAuthEvent,
@@ -51,6 +50,7 @@ import {
editProfile,
createProfile,
uniqTags,
makeHttpAuthHeader,
} from "@welshman/util"
import {Pool, AuthStatus, SocketStatus} from "@welshman/net"
import {Router} from "@welshman/router"
@@ -509,6 +509,8 @@ export const uploadFile = async (file: File, options: UploadFileOptions = {}) =>
try {
const {name, type} = file
console.log("======== 1", name, type, options.encrypt)
if (!type.match("image/(webp|gif|svg)")) {
file = await compressFile(file, options)
}
@@ -530,13 +532,25 @@ export const uploadFile = async (file: File, options: UploadFileOptions = {}) =>
}
const ext = "." + type.split("/")[1]
console.log("======== 2", ext)
const server = await getBlossomServer(options)
console.log("======== 3", server)
const hashes = [await sha256(await file.arrayBuffer())]
const $signer = signer.get() || Nip01Signer.ephemeral()
const authTemplate = makeBlossomAuthEvent({action: "upload", server, hashes})
const authEvent = await $signer.sign(authTemplate)
const res = await uploadBlob(server, file, {authEvent})
console.log("======== 4", authEvent.id)
// const res = await uploadBlob(server, file, {authEvent})
const res = await fetch(`${new URL(server).origin}/upload`, {
method: "PUT",
headers: {Authorization: makeHttpAuthHeader(authEvent)},
body: file instanceof Blob ? file : new Blob([file]),
})
console.log("======== 5", res.status)
const text = await res.text()
console.log("======== 6", text)
let {uploaded, url, ...task} = parseJson(text) || {}
@@ -555,6 +569,7 @@ export const uploadFile = async (file: File, options: UploadFileOptions = {}) =>
return {result}
} catch (e: any) {
console.log("========= error", String(e))
console.error("Error caught when uploading file:", e)
return {error: e.toString()}