~emersion/public-inbox

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
3 2

[PATCH gamja] Add support for uploading files with FILEHOST

Details
Message ID
<20240213004529.25896-1-amk@amk.ie>
DKIM signature
pass
Download raw message
Patch: +67 -3
---
 components/app.js           | 41 +++++++++++++++++++++++++++++++++++++
 components/buffer-header.js | 25 +++++++++++++++++++---
 lib/irc.js                  |  4 ++++
 3 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/components/app.js b/components/app.js
index a27c915..db3d713 100644
--- a/components/app.js
+++ b/components/app.js
@@ -226,6 +226,7 @@ export default class App extends Component {
		this.handleVerifyClick = this.handleVerifyClick.bind(this);
		this.handleVerifySubmit = this.handleVerifySubmit.bind(this);
		this.handleOpenSettingsClick = this.handleOpenSettingsClick.bind(this);
		this.handleUploadClick = this.handleUploadClick.bind(this);
		this.handleSettingsChange = this.handleSettingsChange.bind(this);
		this.handleSettingsDisconnect = this.handleSettingsDisconnect.bind(this);
		this.handleSwitchSubmit = this.handleSwitchSubmit.bind(this);
@@ -1904,6 +1905,43 @@ export default class App extends Component {
		this.openDialog("settings", { showProtocolHandler });
	}

	async handleUploadClick(event) {
		const file = event.target.files && event.target.files[0];
		if (!file) {
			return;
		}
		event.target.value = null;
		let serverID = State.getActiveServerID(this.state);
		let client = this.clients.get(serverID);
		const url = client.isupport.filehost();
		if (!url) {
			return;
		}
		let authHeaderVal;
		if (this.config.server.auth === "oauth2") {
			authHeaderVal = "Bearer " + this.state.connectParams.saslOauthBearer.token;
		} else {
			authHeaderVal =  "Basic " + btoa(this.state.connectParams.saslPlain.username
											 + ":" +
											 this.state.connectParams.saslPlain.password);
		}
		let response = await fetch(url, {
			method: "POST",
			body: file,
			headers: {
				"Authorization": authHeaderVal,
				"Content-Disposition": "attachment; filename=" + file.name
			}
		});
		let location = response.headers.get("location");
		if (location) {
			let fileUrl = new URL(url)
			fileUrl.pathname = location
			this.composer.current.setState({text: fileUrl.toString()});
			this.composer.current.focus()
		}
	}

	handleSettingsChange(settings) {
		store.settings.put(settings);
		this.setState({ settings });
@@ -1990,6 +2028,8 @@ export default class App extends Component {
				activeUser = activeServer.users.get(activeBuffer.name);
			}

			let client = this.clients.get(activeBuffer.server);

			bufferHeader = html`
				<section id="buffer-header">
					<${BufferHeader}
@@ -2004,6 +2044,7 @@ export default class App extends Component {
						onAddNetwork=${this.handleAddNetworkClick}
						onManageNetwork=${() => this.handleManageNetworkClick(activeBuffer.server)}
						onOpenSettings=${this.handleOpenSettingsClick}
						onUpload=${client.isupport.filehost() ? this.handleUploadClick : null}
					/>
				</section>
			`;
diff --git a/components/buffer-header.js b/components/buffer-header.js
index 5b2b56a..01ced0f 100644
--- a/components/buffer-header.js
+++ b/components/buffer-header.js
@@ -1,4 +1,4 @@
import { html, Component } from "../lib/index.js";
import { html, Component, createRef } from "../lib/index.js";
import linkify from "../lib/linkify.js";
import { strip as stripANSI } from "../lib/ansi.js";
import { BufferType, ServerStatus, getServerName } from "../state.js";
@@ -26,6 +26,8 @@ export default function BufferHeader(props) {
		fullyConnected = fullyConnected && props.bouncerNetwork.state === "connected";
	}

	let uploadRef = createRef();

	let description = null, actions = [];
	switch (props.buffer.type) {
	case BufferType.SERVER:
@@ -124,6 +126,14 @@ export default function BufferHeader(props) {
			description = linkify(stripANSI(props.buffer.topic), props.onChannelClick);
		}
		if (props.buffer.joined) {
			if (props.onUpload) {
				actions.push(html`
					<input type="file" accept="*" style="display: none;" ref=${uploadRef} onChange=${props.onUpload}></input>
					<button onClick=${() => {uploadRef.current.click();}}>
						Upload
					</button>
				`);
			}
			actions.push(html`
				<button
					key="part"
@@ -203,13 +213,22 @@ export default function BufferHeader(props) {
			description = html`<${NickStatus} status=${status}/> ${realname} ${details}`;
		}

		actions = html`
		if (props.onUpload) {
			actions.push(html`
					<input type="file" accept="*" style="display: none;" ref=${uploadRef} onChange=${props.onUpload}></input>
					<button onClick=${() => {uploadRef.current.click();}}>
						Upload
					</button>
				`);
		}

		actions.push(html`
			<button
				key="close"
				class="danger"
				onClick=${props.onClose}
			>Close</button>
		`;
		`);
		break;
	}

diff --git a/lib/irc.js b/lib/irc.js
index 86fa65a..3fa81e0 100644
--- a/lib/irc.js
+++ b/lib/irc.js
@@ -500,6 +500,10 @@ export class Isupport {
		}
		return parseInt(this.raw.get("LINELEN"), 10);
	}

	filehost() {
		return this.raw.get("SOJU.IM/FILEHOST");
	}
}

export function getMaxPrivmsgLen(isupport, nick, target) {
-- 
2.43.1

[gamja/patches/.build.yml] build success

builds.sr.ht <builds@sr.ht>
Details
Message ID
<CZ3JBCWW2KL2.3MJFMQIJZC27D@fra02>
In-Reply-To
<20240213004529.25896-1-amk@amk.ie> (view parent)
DKIM signature
missing
Download raw message
gamja/patches/.build.yml: SUCCESS in 24s

[Add support for uploading files with FILEHOST][0] from [Alex McGrath][1]

[0]: https://lists.sr.ht/~emersion/public-inbox/patches/49426
[1]: amk@amk.ie

✓ #1148591 SUCCESS gamja/patches/.build.yml https://builds.sr.ht/~emersion/job/1148591
Details
Message ID
<28Xr4v5KVwQWfaKNhKEX6lRa5BarPFH6U3nHqrU7Eo_VRX4H_3AjVx20dehcpou2dZfhLA504U3EpaO_1Ie_ONAucyuHFxzj0VfgySDvE2E=@emersion.fr>
In-Reply-To
<20240213004529.25896-1-amk@amk.ie> (view parent)
DKIM signature
pass
Download raw message
Thanks for the patch! I haven't looked closely at the code, but as a more
general comment: I think I'd like to support this feature, but I'm not
sure what's the best way to expose it without being intrusive. I'd say
that a prominent button in the top bar is a bit too intrusive. I don't
have great alternative ideas currently.

I also wonder how to give feedback to the user that an upload is in
progress. Maybe we can keep this for later.

Additionally, would be nicer to not completely throw away any previous
text in the input field -- maybe append the URL with a space separator
if it's not empty.
Details
Message ID
<ChgGBDcUiQArQIc9FaMWbQEFoL-FwAY1Iwm1flCEU-UvfwFTEshNHWhlvxuIN2sI0ArTlDuKST98320d4bHxHBKP0lNrVOrT4t2mA8QLmBY=@emersion.fr>
In-Reply-To
<20240213004529.25896-1-amk@amk.ie> (view parent)
DKIM signature
pass
Download raw message
I've merged part of this patch in 87e88ccccaf3, but only handling paste
events with files for now. (Drag-and-drop would be easy to add.)
Reply to thread Export thread (mbox)