Add: Sending image messages

This commit is contained in:
Adam Porter 2021-07-29 18:52:14 -05:00
parent f70b6661b1
commit c009da4c80
3 changed files with 56 additions and 1 deletions

View file

@ -6,7 +6,7 @@
# [[https://melpa.org/#/package-name][file:https://melpa.org/packages/package-name-badge.svg]] [[https://stable.melpa.org/#/package-name][file:https://stable.melpa.org/packages/package-name-badge.svg]]
Ement.el is a new Matrix client for Emacs. It's basic at the moment, but it can be used to send and read messages (including sending replies and seeing images), join and leave rooms, etc.
Ement.el is a new Matrix client for Emacs. It's basic at the moment, but it can be used to send and read messages (including replies and images), join and leave rooms, etc.
* Screenshots
@ -92,6 +92,7 @@ If you want to install it manually, it's simple enough, but you should know what
- ~ement-join-room~ to join a room.
- ~ement-leave-room~ to leave a room.
- ~ement-room-edit-message~ to edit a message at point.
- ~ement-room-send-image~ to send an image message.
In a room buffer:

View file

@ -36,6 +36,7 @@
(require 'color)
(require 'ewoc)
(require 'mailcap)
(require 'shr)
(require 'subr-x)
(require 'mwheel)
@ -371,6 +372,46 @@ Matrix-related commands in it will fail."
;;;; Commands
(declare-function ement-upload "ement" t t)
(defun ement-room-send-image (file body room session)
"Send image FILE to ROOM on SESSION, using message BODY."
;; TODO: Support URLs to remote files.
(interactive (let* ((file (read-file-name (format "Send image file (%s): " (ement-room-display-name ement-room))
nil nil 'confirm))
(body (read-string (format "Message body (%s): " (ement-room-display-name ement-room))
file)))
(list file body ement-room ement-session)))
(when (yes-or-no-p (format "Upload file %S to room %S? "
file (ement-room-display-name room)))
(pcase-let* ((extension (file-name-extension file))
(mime-type (mailcap-extension-to-mime extension))
(data (with-temp-buffer
;; NOTE: Using (set-buffer-multibyte nil) doesn't
;; seem to be necessary, but I don't know why not.
(insert-file-contents file)
(buffer-string)))
(size (length data)))
;; MAYBE: Send typing notification (maybe make an ement-room-with-typing macro).
(ement-upload session :data data :content-type mime-type
:then (lambda (data)
(message "Uploaded file %S. Sending message..." file)
(pcase-let* (((map ('content_uri content-uri)) data)
((cl-struct ement-session server token) session)
((cl-struct ement-room (id room-id)) room)
(endpoint (format "rooms/%s/send/%s/%s" (url-hexify-string room-id)
"m.room.message" (cl-incf (ement-session-transaction-id session))))
;; TODO: Image height/width (maybe not easy to get in Emacs).
(data (ement-alist "msgtype" "m.image"
"url" content-uri
"body" body
"info" (ement-alist "mimetype" mime-type
"size" size))))
(ement-api server token endpoint
(lambda (&rest args)
(message "SEND MESSAGE CALLBACK: %S" args))
:data (json-encode data)
:method 'put)))))))
(defun ement-room-scroll-up-mark-read ()
"Scroll buffer up, marking read and burying when at end."
(interactive)

View file

@ -228,6 +228,19 @@ call `pop-to-buffer'."
(ement-room--buffer session room (ement--room-buffer-name room)))
(goto-char (point-max)))
(cl-defun ement-upload (session &key data filename then else
(content-type "application/octet-stream"))
"Upload DATA with FILENAME to content repository on SESSION.
THEN and ELSE are passed to `ement-api', which see."
(declare (indent defun))
(pcase-let* (((cl-struct ement-session server token) session)
(endpoint (if filename
(format "upload?filename=%s" (url-hexify-string filename))
"upload")))
(ement-api server token endpoint then :else else
:method 'post :endpoint-category "media"
:content-type content-type :data data :data-type 'binary)))
;;;; Functions
(defun ement--sync-messages-p (session)