feat: add attach media button
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
"@tauri-apps/api": "2.0.0-beta.15",
|
"@tauri-apps/api": "2.0.0-beta.15",
|
||||||
"@tauri-apps/plugin-clipboard-manager": "2.1.0-beta.5",
|
"@tauri-apps/plugin-clipboard-manager": "2.1.0-beta.5",
|
||||||
"@tauri-apps/plugin-dialog": "2.0.0-beta.7",
|
"@tauri-apps/plugin-dialog": "2.0.0-beta.7",
|
||||||
|
"@tauri-apps/plugin-fs": "2.0.0-beta.7",
|
||||||
"@tauri-apps/plugin-os": "2.0.0-beta.7",
|
"@tauri-apps/plugin-os": "2.0.0-beta.7",
|
||||||
"@tauri-apps/plugin-process": "2.0.0-beta.7",
|
"@tauri-apps/plugin-process": "2.0.0-beta.7",
|
||||||
"@tauri-apps/plugin-shell": "2.0.0-beta.8",
|
"@tauri-apps/plugin-shell": "2.0.0-beta.8",
|
||||||
|
|||||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@@ -38,6 +38,9 @@ importers:
|
|||||||
'@tauri-apps/plugin-dialog':
|
'@tauri-apps/plugin-dialog':
|
||||||
specifier: 2.0.0-beta.7
|
specifier: 2.0.0-beta.7
|
||||||
version: 2.0.0-beta.7
|
version: 2.0.0-beta.7
|
||||||
|
'@tauri-apps/plugin-fs':
|
||||||
|
specifier: 2.0.0-beta.7
|
||||||
|
version: 2.0.0-beta.7
|
||||||
'@tauri-apps/plugin-os':
|
'@tauri-apps/plugin-os':
|
||||||
specifier: 2.0.0-beta.7
|
specifier: 2.0.0-beta.7
|
||||||
version: 2.0.0-beta.7
|
version: 2.0.0-beta.7
|
||||||
@@ -914,6 +917,9 @@ packages:
|
|||||||
'@tauri-apps/plugin-dialog@2.0.0-beta.7':
|
'@tauri-apps/plugin-dialog@2.0.0-beta.7':
|
||||||
resolution: {integrity: sha512-myywwpsKbquDDzl5zaOmmLLv5O8EJ/GgHDAoVSPwO97R4iWzkDvj3HFF91tNh7i25Tu/bP6jYPAdZA1NCRxxtg==}
|
resolution: {integrity: sha512-myywwpsKbquDDzl5zaOmmLLv5O8EJ/GgHDAoVSPwO97R4iWzkDvj3HFF91tNh7i25Tu/bP6jYPAdZA1NCRxxtg==}
|
||||||
|
|
||||||
|
'@tauri-apps/plugin-fs@2.0.0-beta.7':
|
||||||
|
resolution: {integrity: sha512-hsZyhzvy+xtRfbrKI2rmU1ZfmgbSs7Zu/6a12MFlJKVzqXmUwJvggcjYdm1cEFdLbnOOsszENXbwMnkzmxtirA==}
|
||||||
|
|
||||||
'@tauri-apps/plugin-os@2.0.0-beta.7':
|
'@tauri-apps/plugin-os@2.0.0-beta.7':
|
||||||
resolution: {integrity: sha512-CHo09ecxUU0NFkAqctXeQzdaXw02EXulqcaZnbjrBfRJ2ulmGq7zaUCsHihfcqWcdnmNwmP9Wh/gyznMc1JF9Q==}
|
resolution: {integrity: sha512-CHo09ecxUU0NFkAqctXeQzdaXw02EXulqcaZnbjrBfRJ2ulmGq7zaUCsHihfcqWcdnmNwmP9Wh/gyznMc1JF9Q==}
|
||||||
|
|
||||||
@@ -2427,6 +2433,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@tauri-apps/api': 2.0.0-beta.15
|
'@tauri-apps/api': 2.0.0-beta.15
|
||||||
|
|
||||||
|
'@tauri-apps/plugin-fs@2.0.0-beta.7':
|
||||||
|
dependencies:
|
||||||
|
'@tauri-apps/api': 2.0.0-beta.15
|
||||||
|
|
||||||
'@tauri-apps/plugin-os@2.0.0-beta.7':
|
'@tauri-apps/plugin-os@2.0.0-beta.7':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tauri-apps/api': 2.0.0-beta.15
|
'@tauri-apps/api': 2.0.0-beta.15
|
||||||
|
|||||||
1
src-tauri/Cargo.lock
generated
1
src-tauri/Cargo.lock
generated
@@ -949,6 +949,7 @@ dependencies = [
|
|||||||
"tauri-plugin-decorum",
|
"tauri-plugin-decorum",
|
||||||
"tauri-plugin-devtools",
|
"tauri-plugin-devtools",
|
||||||
"tauri-plugin-dialog",
|
"tauri-plugin-dialog",
|
||||||
|
"tauri-plugin-fs",
|
||||||
"tauri-plugin-os",
|
"tauri-plugin-os",
|
||||||
"tauri-plugin-prevent-default",
|
"tauri-plugin-prevent-default",
|
||||||
"tauri-plugin-process",
|
"tauri-plugin-process",
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ tauri-plugin-dialog = "2.0.0-beta"
|
|||||||
tauri-plugin-shell = "2.0.0-beta"
|
tauri-plugin-shell = "2.0.0-beta"
|
||||||
tauri-plugin-updater = "2.0.0-beta"
|
tauri-plugin-updater = "2.0.0-beta"
|
||||||
tauri-plugin-process = "2.0.0-beta"
|
tauri-plugin-process = "2.0.0-beta"
|
||||||
|
tauri-plugin-fs = "2.0.0-beta"
|
||||||
tauri-plugin-decorum = "0.1.5"
|
tauri-plugin-decorum = "0.1.5"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
"updater:allow-check",
|
"updater:allow-check",
|
||||||
"updater:allow-download-and-install",
|
"updater:allow-download-and-install",
|
||||||
"clipboard-manager:allow-write-text",
|
"clipboard-manager:allow-write-text",
|
||||||
"clipboard-manager:allow-read-text"
|
"clipboard-manager:allow-read-text",
|
||||||
|
"fs:allow-read-file"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ fn main() {
|
|||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.enable_macos_default_menu(false)
|
.enable_macos_default_menu(false)
|
||||||
|
.plugin(tauri_plugin_fs::init())
|
||||||
.plugin(tauri_plugin_prevent_default::init())
|
.plugin(tauri_plugin_prevent_default::init())
|
||||||
.plugin(tauri_plugin_process::init())
|
.plugin(tauri_plugin_process::init())
|
||||||
.plugin(tauri_plugin_updater::Builder::new().build())
|
.plugin(tauri_plugin_updater::Builder::new().build())
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { ask, message } from "@tauri-apps/plugin-dialog";
|
import { ask, message, open } from "@tauri-apps/plugin-dialog";
|
||||||
|
import { readFile } from "@tauri-apps/plugin-fs";
|
||||||
import { relaunch } from "@tauri-apps/plugin-process";
|
import { relaunch } from "@tauri-apps/plugin-process";
|
||||||
import { check } from "@tauri-apps/plugin-updater";
|
import { check } from "@tauri-apps/plugin-updater";
|
||||||
import { type ClassValue, clsx } from "clsx";
|
import { type ClassValue, clsx } from "clsx";
|
||||||
@@ -138,3 +139,55 @@ export async function checkForAppUpdates(silent: boolean) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function upload() {
|
||||||
|
const allowExts = [
|
||||||
|
"png",
|
||||||
|
"jpeg",
|
||||||
|
"jpg",
|
||||||
|
"gif",
|
||||||
|
"mp4",
|
||||||
|
"mp3",
|
||||||
|
"webm",
|
||||||
|
"mkv",
|
||||||
|
"avi",
|
||||||
|
"mov",
|
||||||
|
];
|
||||||
|
|
||||||
|
const selected = await open({
|
||||||
|
multiple: false,
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
name: "Media",
|
||||||
|
extensions: allowExts,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
// User cancelled action
|
||||||
|
if (!selected) return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const selectedPath = selected.path;
|
||||||
|
const file = await readFile(selectedPath);
|
||||||
|
const blob = new Blob([file]);
|
||||||
|
|
||||||
|
const data = new FormData();
|
||||||
|
data.append("fileToUpload", blob);
|
||||||
|
data.append("submit", "Upload Image");
|
||||||
|
|
||||||
|
const res = await fetch("https://nostr.build/api/v2/upload/files", {
|
||||||
|
method: "POST",
|
||||||
|
body: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.ok) return null;
|
||||||
|
|
||||||
|
const json = await res.json();
|
||||||
|
const content = json.data[0];
|
||||||
|
|
||||||
|
return content.url as string;
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { commands } from "@/commands";
|
import { commands } from "@/commands";
|
||||||
import { cn, getReceivers, groupEventByDate, time } from "@/commons";
|
import { cn, getReceivers, groupEventByDate, time, upload } from "@/commons";
|
||||||
import { Spinner } from "@/components/spinner";
|
import { Spinner } from "@/components/spinner";
|
||||||
import { User } from "@/components/user";
|
import { User } from "@/components/user";
|
||||||
import { CoopIcon } from "@/icons/coop";
|
import { CoopIcon } from "@/icons/coop";
|
||||||
@@ -11,6 +11,8 @@ import { listen } from "@tauri-apps/api/event";
|
|||||||
import { message } from "@tauri-apps/plugin-dialog";
|
import { message } from "@tauri-apps/plugin-dialog";
|
||||||
import type { NostrEvent } from "nostr-tools";
|
import type { NostrEvent } from "nostr-tools";
|
||||||
import {
|
import {
|
||||||
|
type Dispatch,
|
||||||
|
type SetStateAction,
|
||||||
useCallback,
|
useCallback,
|
||||||
useLayoutEffect,
|
useLayoutEffect,
|
||||||
useRef,
|
useRef,
|
||||||
@@ -317,12 +319,7 @@ function Form() {
|
|||||||
) : (
|
) : (
|
||||||
<div className="flex-1 flex items-center gap-2">
|
<div className="flex-1 flex items-center gap-2">
|
||||||
<div className="inline-flex gap-1">
|
<div className="inline-flex gap-1">
|
||||||
<div
|
<AttachMedia callback={setNewMessage} />
|
||||||
title="Attach media"
|
|
||||||
className="size-9 inline-flex items-center justify-center hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-full"
|
|
||||||
>
|
|
||||||
<Paperclip className="size-5" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<input
|
<input
|
||||||
placeholder="Message..."
|
placeholder="Message..."
|
||||||
@@ -347,3 +344,36 @@ function Form() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function AttachMedia({
|
||||||
|
callback,
|
||||||
|
}: { callback: Dispatch<SetStateAction<string>> }) {
|
||||||
|
const [isPending, startTransition] = useTransition();
|
||||||
|
|
||||||
|
const attach = async () => {
|
||||||
|
startTransition(async () => {
|
||||||
|
const file = await upload();
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
callback((prev) => `${prev} ${file}`);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
title="Attach media"
|
||||||
|
onClick={() => attach()}
|
||||||
|
className="size-9 inline-flex items-center justify-center hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-full"
|
||||||
|
>
|
||||||
|
{isPending ? (
|
||||||
|
<Spinner className="size-4" />
|
||||||
|
) : (
|
||||||
|
<Paperclip className="size-5" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user