diff --git a/src/components/icons.tsx b/src/components/icons.tsx
index 699ffc646..2dfeedef8 100644
--- a/src/components/icons.tsx
+++ b/src/components/icons.tsx
@@ -215,3 +215,15 @@ export const UnlockIcon = createIcon({
d: "M7 10h13a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V11a1 1 0 0 1 1-1h1V9a7 7 0 0 1 13.262-3.131l-1.789.894A5 5 0 0 0 7 9v1zm-2 2v8h14v-8H5zm5 3h4v2h-4v-2z",
defaultProps,
});
+
+export const ImageIcon = createIcon({
+ displayName: "ImageIcon",
+ d: "M4.828 21l-.02.02-.021-.02H2.992A.993.993 0 0 1 2 20.007V3.993A1 1 0 0 1 2.992 3h18.016c.548 0 .992.445.992.993v16.014a1 1 0 0 1-.992.993H4.828zM20 15V5H4v14L14 9l6 6zm0 2.828l-6-6L6.828 19H20v-1.172zM8 11a2 2 0 1 1 0-4 2 2 0 0 1 0 4z",
+ defaultProps,
+});
+
+export const CameraIcon = createIcon({
+ displayName: "CameraIcon",
+ d: "M9.828 5l-2 2H4v12h16V7h-3.828l-2-2H9.828zM9 3h6l2 2h4a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h4l2-2zm3 15a5.5 5.5 0 1 1 0-11 5.5 5.5 0 0 1 0 11zm0-2a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7z",
+ defaultProps,
+});
diff --git a/src/components/note/index.tsx b/src/components/note/index.tsx
index 2059061ad..c9dcf228f 100644
--- a/src/components/note/index.tsx
+++ b/src/components/note/index.tsx
@@ -67,7 +67,11 @@ export const Note = React.memo(({ event, maxHeight }: NoteProps) => {
-
+
{
+ const isMobile = useIsMobile();
+ const toast = useToast();
const { requestSignature } = useSigningContext();
const writeRelays = useWriteRelayUrls();
const [waiting, setWaiting] = useState(false);
@@ -46,6 +51,33 @@ export const PostModal = ({ isOpen, onClose, initialDraft }: PostModalProps) =>
const [results, resultsActions] = useList();
const { isOpen: showPreview, onToggle: togglePreview } = useDisclosure();
const [draft, setDraft] = useState(() => Object.assign(emptyDraft(), initialDraft));
+ const imageUploadRef = useRef(null);
+ const imageCaptureRef = useRef(null);
+ const [uploading, setUploading] = useState(false);
+
+ const uploadImage = async (imageFile: File) => {
+ try {
+ if (!imageFile.type.includes("image")) throw new Error("Only images are supported");
+ setUploading(true);
+ const payload = new FormData();
+ payload.append("fileToUpload", imageFile);
+ const response = await fetch("https://nostr.build/upload.php", { body: payload, method: "POST" }).then((res) =>
+ res.text()
+ );
+ const imageUrl = response.match(/https:\/\/nostr\.build\/i\/[\w.]+/)?.[0];
+ if (imageUrl) {
+ setDraft((d) => ({ ...d, content: (d.content += imageUrl) }));
+ }
+ } catch (e) {
+ if (e instanceof Error) {
+ toast({
+ status: "error",
+ description: e.message,
+ });
+ }
+ }
+ setUploading(false);
+ };
const handleContentChange: React.ChangeEventHandler = (event) => {
setDraft((d) => ({ ...d, content: event.target.value }));
@@ -87,9 +119,56 @@ export const PostModal = ({ isOpen, onClose, initialDraft }: PostModalProps) =>
{showPreview ? (
) : (
-
+