Skip to content

Commit f923c35

Browse files
author
Visuwesh
committed
Add yank-media handlers and XDS function
* ement-room.el (ement-room-send-file): Add new :then argument for these new features. (ement-room-dnd-xds-upload-file): Add XDS function. (ement-room-send-image-in-clipboard, ement-room-send-copied-files): Add yank-media handler functions. (ement-room-mode): Register them all. Closes alphapapa#47.
1 parent 8e6e9cd commit f923c35

File tree

1 file changed

+57
-4
lines changed

1 file changed

+57
-4
lines changed

ement-room.el

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,10 +1263,12 @@ otherwise use current room."
12631263
:then (lambda (_data)
12641264
(message "Topic set (%s): %s" display-name topic)))))
12651265

1266-
(cl-defun ement-room-send-file (file body room session &key (msgtype "m.file"))
1266+
(cl-defun ement-room-send-file (file body room session &key (msgtype "m.file") (then #'ignore))
12671267
"Send FILE to ROOM on SESSION, using message BODY and MSGTYPE.
12681268
Interactively, with prefix, prompt for room and session,
1269-
otherwise use current room."
1269+
otherwise use current room.
1270+
When THEN is non-nil, it should be a function of no arguments and
1271+
will be called once the image is uploaded."
12701272
;; TODO: Support URLs to remote files.
12711273
(interactive
12721274
(ement-with-room-and-session
@@ -1279,7 +1281,7 @@ otherwise use current room."
12791281
(list file body ement-room ement-session)))))
12801282
;; NOTE: The typing notification won't be quite right, because it'll be canceled while waiting
12811283
;; for the file to upload. It would be awkward to handle that, so this will do for now.
1282-
(when (yes-or-no-p (format "Upload file %S to room %S? "
1284+
(when (yes-or-no-p (format "Upload file %s to room %s? "
12831285
file (ement-room-display-name room)))
12841286
(pcase-let* ((filename (file-name-nondirectory file))
12851287
(extension (or (file-name-extension file) ""))
@@ -1289,6 +1291,8 @@ otherwise use current room."
12891291
(ement-upload session :data data :filename filename :content-type mime-type
12901292
:then (lambda (data)
12911293
(message "Uploaded file %S. Sending message..." file)
1294+
(when then
1295+
(funcall then))
12921296
(pcase-let* (((map ('content_uri content-uri)) data)
12931297
((cl-struct ement-room (id room-id)) room)
12941298
(endpoint (format "rooms/%s/send/%s/%s" (url-hexify-string room-id)
@@ -1328,6 +1332,50 @@ otherwise use current room."
13281332
"m.image"
13291333
"m.file"))))
13301334

1335+
(defun ement-room-dnd-xds-upload-file (need-name filename)
1336+
"Upload the file dropped via XDS protocol.
1337+
When NEED-NAME is t, FILENAME is the base name of the file to be
1338+
saved by the source of the file being droped.
1339+
When NEED-NAME is nil, the drop is complete."
1340+
(if need-name
1341+
(expand-file-name filename temporary-file-directory)
1342+
(ement-room-send-file filename (file-name-nondirectory filename)
1343+
ement-room ement-session
1344+
:msgtype (if (string-prefix-p "image/" (mailcap-file-name-to-mime-type filename))
1345+
"m.image"
1346+
"m.file")
1347+
:then (lambda () (delete-file filename)))))
1348+
1349+
(defun ement-room-send-image-in-clipboard (mimetype data)
1350+
"Upload image file in clipboard whose contents is DATA.
1351+
The mimetype of the image is given by MIMETYPE."
1352+
(let* ((ext (symbol-name (mailcap-mime-type-to-extension mimetype)))
1353+
(coding-system-for-write 'no-conversion)
1354+
(filename (make-temp-file "emacs" nil (concat "." ext) data)))
1355+
(ement-room-send-file filename
1356+
(concat "clipboard." ext)
1357+
ement-room ement-session
1358+
:msgtype "m.image"
1359+
:then (lambda () (delete-file filename)))))
1360+
1361+
(defun ement-room-send-copied-files (_mimetype data)
1362+
"Upload files in clipboard to the current room.
1363+
DATA follows the following format:
1364+
1365+
cut OR copy
1366+
file://...
1367+
..."
1368+
(let* ((files (cdr (split-string data "[\0\n\r]" t "^file://"))))
1369+
(dolist (f files)
1370+
;; NOTE: We are assuming the filename is always UTF-8!
1371+
(setq f (decode-coding-string (url-unhex-string f) 'utf-8))
1372+
(when (file-readable-p f)
1373+
(ement-room-send-file f (file-name-nondirectory f) ement-room ement-session
1374+
:msgtype
1375+
(if (string-prefix-p "image/" (mailcap-file-name-to-mime-type f))
1376+
"m.image"
1377+
"m.file"))))))
1378+
13311379
(cl-defun ement-room-join (id-or-alias session &key then)
13321380
"Join room by ID-OR-ALIAS on SESSION.
13331381
THEN may be a function to call after joining the room (and when
@@ -2093,7 +2141,12 @@ and erases the buffer."
20932141
'(ement-room--complete-members-at-point ement-room--complete-rooms-at-point))
20942142
(setq-local dnd-protocol-alist (append '(("^file:///" . ement-room-dnd-upload-file)
20952143
("^file:" . ement-room-dnd-upload-file))
2096-
dnd-protocol-alist)))
2144+
dnd-protocol-alist))
2145+
(when (boundp 'x-dnd-direct-save-function)
2146+
(setq-local x-dnd-direct-save-function #'ement-room-dnd-xds-upload-file))
2147+
(when (fboundp 'yank-media-handler)
2148+
(yank-media-handler "image/.*" #'ement-room-send-image-in-clipboard)
2149+
(yank-media-handler "x/special-\\(?:gnome\|KDE\|mate\\)-files" #'ement-room-send-copied-files)))
20972150
(add-hook 'ement-room-mode-hook 'visual-line-mode)
20982151

20992152
(defun ement-room-read-string (prompt &optional initial-input history default-value inherit-input-method)

0 commit comments

Comments
 (0)