about summary refs log tree commit diff
path: root/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog.el
diff options
context:
space:
mode:
Diffstat (limited to 'configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog.el')
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog.el343
1 files changed, 343 insertions, 0 deletions
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog.el
new file mode 100644
index 000000000000..e62f2a46ec13
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog.el
@@ -0,0 +1,343 @@
+;;; slack-dialog.el ---                              -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-selectable)
+
+(defclass slack-dialog ()
+  ((title :initarg :title :type string)
+   (callback-id :initarg :callback_id :type string)
+   (elements :initarg :elements :type list)
+   (state :initarg :state :type (or null string) :initform nil)
+   (submit-label :initarg :submit_label :type string :initform "Submit")
+   (notify-on-cancel :initarg :notify_on_cancel :type boolean :initform nil)
+   (error-message :initarg :error-message :type (or null string) :initform nil)
+   ))
+
+(defclass slack-dialog-element ()
+  ((name :initarg :name :type string)
+   (label :initarg :label :type string)
+   (type :initarg :type :type string)
+   (optional :initarg :optional :type boolean :initform nil)
+   (placeholder :initarg :placeholder :type (or null string) :initform nil)
+   (value :initarg :value :type (or null string) :initform nil)
+   (errors :initarg :errors :type list :initform '())))
+
+(defclass slack-dialog-element-error ()
+  ((name :initarg :name :type string)
+   (error-message :initarg :error-message :type string)))
+
+(defclass slack-dialog-text-element (slack-dialog-element)
+  ((max-length :initarg :max_length :type number :initform 150)
+   (min-length :initarg :min_length :type number :initform 0)
+   (hint :initarg :hint :type (or null string) :initform nil)
+   ;; one of email, number, tel or url
+   (subtype :initarg :subtype :type (or null string) :initform nil)))
+
+(defclass slack-dialog-textarea-element (slack-dialog-text-element)
+  ((max-length :initarg :max_length :type number :initform 3000)))
+
+(defclass slack-dialog-select-element (slack-dialog-element slack-selectable)
+  ((min-query-length :initarg :min_query_length :type (or null number) :initform nil)))
+
+(defclass slack-dialog-select-option (slack-selectable-option)
+  ((label :initarg :label :type string)))
+
+(defclass slack-dialog-select-option-group (slack-selectable-option-group)
+  ((label :initarg :label :type string)))
+
+(defmethod slack-dialog-element-value ((this slack-dialog-element))
+  (or (oref this value) ""))
+
+(defmethod slack-dialog-element-value ((this slack-dialog-select-element))
+  (with-slots (data-source selected-options) this
+    (or (cond
+         ((string= data-source "external")
+          (and selected-options
+               (car selected-options)
+               (oref (car selected-options) value)))
+         (t (oref this value)))
+        "")))
+
+(defmethod slack-equalp ((this slack-dialog-element) other)
+  (string= (oref this name)
+           (oref other name)))
+
+(defmethod slack-dialog-selected-option ((this slack-dialog-select-element))
+  (with-slots (data-source value options selected-options) this
+    (if (string= data-source "static")
+        (cl-find-if #'(lambda (op) (string= (oref op value)
+                                            value))
+                    options)
+      (and selected-options (car selected-options)))))
+
+(defmethod slack-selectable-text ((this slack-dialog-select-option))
+  (oref this label))
+
+(defmethod slack-selectable-text ((this slack-dialog-select-option-group))
+  (oref this label))
+
+(defmethod slack-selectable-prompt ((this slack-dialog-select-element))
+  (format "%s :"
+          (oref this label)))
+
+(defun slack-dialog-text-element-create (payload)
+  (apply #'make-instance 'slack-dialog-text-element
+         (slack-collect-slots 'slack-dialog-text-element payload)))
+
+(defun slack-dialog-textarea-element-create (payload)
+  (apply #'make-instance 'slack-dialog-textarea-element
+         (slack-collect-slots 'slack-dialog-textarea-element payload)))
+
+(defun slack-dialog-select-element-create (payload)
+  (let ((options
+         (mapcar #'(lambda (e)
+                     (apply #'make-instance 'slack-dialog-select-option
+                            (slack-collect-slots 'slack-dialog-select-option
+                                                 e)))
+                 (plist-get payload :options)))
+        (option-groups
+         (mapcar #'(lambda (e)
+                     (apply #'make-instance
+                            'slack-dialog-select-option-group
+                            (slack-collect-slots 'slack-dialog-select-option-group
+                                                 e)))
+                 (plist-get payload :option_groups))))
+    (setq payload (plist-put payload :options options))
+    (setq payload (plist-put payload :option_groups option-groups))
+    (apply #'make-instance 'slack-dialog-select-element
+           (slack-collect-slots 'slack-dialog-select-element
+                                payload))))
+
+(defun slack-dialog-element-create (payload)
+  (let ((type (plist-get payload :type)))
+    (cond
+     ((string= type "select")
+      (slack-dialog-select-element-create payload))
+     ((string= type "text")
+      (slack-dialog-text-element-create payload))
+     ((string= type "textarea")
+      (slack-dialog-textarea-element-create payload))
+     (t (error "Unknown dialog element type: %s" type)))))
+
+(defun slack-dialog-create (payload)
+  (let ((elements (mapcar #'slack-dialog-element-create
+                          (plist-get payload :elements))))
+    (setq payload (plist-put payload :elements elements))
+    (apply #'make-instance 'slack-dialog
+           (slack-collect-slots 'slack-dialog payload))))
+
+(defmethod slack-dialog-element-validate ((this slack-dialog-element) value)
+  (with-slots (optional label) this
+    (when (and (not optional)
+               (or (null value)
+                   (< (length value) 1)))
+      (error "%s must not be empty" label))))
+
+(defmethod slack-dialog-element-validate ((_this slack-dialog-select-element) _value)
+  (call-next-method))
+
+(defmethod slack-dialog-element-validate ((this slack-dialog-text-element) value)
+  (call-next-method)
+  (with-slots (min-length max-length label) this
+    (when (< max-length (length value))
+      (error "%s must be less than %s" label max-length))
+    (when (< (length value) min-length)
+      (error "%s must be greater than %s" label min-length))))
+
+(defmethod slack-dialog-execute ((this slack-dialog-text-element) _dialog-id team)
+  (with-slots (hint value placeholder label optional) this
+    (let* ((prompt (format "%s%s%s : "
+                           label
+                           (if hint (format " (%s)" hint) "")
+                           (if optional " (optional)" "")))
+           (value (read-from-minibuffer prompt value)))
+      (slack-dialog-element-validate this value)
+      value)))
+
+(defmethod slack-dialog-execute ((this slack-dialog-textarea-element) _dialog-id team)
+  (call-next-method))
+
+(defmethod slack-dialog-select-element-get-suggestions ((this slack-dialog-select-element)
+                                                        dialog-id team after-success)
+  (let* ((url "https://slack.com/api/dialog.selectSuggestion")
+         (min-query-length (oref this min-query-length))
+         (prompt (format "Type hints to see options (minimum: %s) : " min-query-length))
+         (params (list (cons "dialog_id" dialog-id)
+                       (cons "name" (oref this name))
+                       (cons "value" (read-from-minibuffer prompt)))))
+    (cl-labels
+        ((on-success (&key data &allow-other-keys)
+                     (slack-request-handle-error
+                      (data "slack-dialog-select-fetch-suggestion")
+                      (funcall after-success data))))
+      (slack-request
+       (slack-request-create
+        url
+        team
+        :type "POST"
+        :params params
+        :sync t
+        :success #'on-success)))))
+
+(defmethod slack-dialog-execute ((this slack-dialog-select-element) dialog-id team)
+  (slack-if-let* ((selected (slack-dialog--execute this dialog-id team)))
+      (cdr selected)))
+
+(defmethod slack-dialog--execute ((this slack-dialog-select-element) dialog-id team)
+  (with-slots (data-source) this
+    (cond
+     ((string= data-source "external")
+      (let ((result-option nil))
+        (cl-labels
+            ((log-error (err)
+                        (slack-log (format "Error: %s" err) team :level 'error))
+             (select (options)
+                     (slack-if-let*
+                         ((selected (completing-read "Choose an Option..."
+                                                     (mapcar #'(lambda (option)
+                                                                 (plist-get option :label))
+                                                             options)
+                                                     nil t)))
+                         (cl-find-if #'(lambda (option) (string= selected
+                                                                 (plist-get option :label)))
+                                     options)))
+             (after-success (data)
+                            (slack-request-handle-error
+                             (data "slack-dialog-execute"
+                                   #'log-error)
+                             (let ((option-groups (plist-get data :option_groups))
+                                   (options (plist-get data :options)))
+                               (when option-groups
+                                 (slack-if-let* ((selected-option-group (select option-groups)))
+                                     (setq options (plist-get selected-option-group :options))))
+                               (when options
+                                 (slack-if-let* ((selected (select options)))
+                                     (setq result-option selected)))))))
+          (slack-dialog-select-element-get-suggestions this
+                                                       dialog-id
+                                                       team
+                                                       #'after-success)
+          (if result-option
+              (cons (plist-get result-option :label)
+                    (plist-get result-option :value))))))
+     ((string= data-source "conversations")
+      (slack-if-let* ((rooms (append (oref team channels)
+                                     (oref team groups)
+                                     (oref team ims)))
+                      (room (slack-room-select rooms team)))
+          (cons (slack-room-name room team)
+                (oref room id))))
+     ((string= data-source "channels")
+      (slack-if-let* ((channels (oref team channels))
+                      (channel (slack-room-select channels team)))
+          (cons (slack-room-name channel team)
+                (oref channel id))))
+     ((string= data-source "users")
+      (slack-if-let* ((id (plist-get (slack--user-select team) :id)))
+          (cons (slack-user-name id team)
+                id)))
+     ((string= "static" data-source)
+      (slack-if-let* ((selected (slack-selectable-select-from-static-data-source this)))
+          (cons (oref selected label)
+                (oref selected value))))
+     (t (error "Unknown element's data-source: %s" data-source))
+     )))
+
+(defmethod slack-dialog--submit ((_this slack-dialog)
+                                 dialog-id team submission
+                                 &optional after-success)
+  (let ((url "https://slack.com/api/dialog.submit")
+        (params (list (cons "submission" (json-encode-alist submission))
+                      (cons "dialog_id" dialog-id))))
+    (cl-labels
+        ((on-success (&key data &allow-other-keys)
+                     (when (functionp after-success)
+                       (funcall after-success data))))
+      (slack-request
+       (slack-request-create
+        url
+        team
+        :type "POST"
+        :params params
+        :success #'on-success)))))
+
+(defmethod slack-dialog-submit ((this slack-dialog) dialog-id team)
+  (with-slots (elements) this
+    (let ((submission (mapcar #'(lambda (element)
+                                  (let ((value (slack-dialog-execute element dialog-id team)))
+                                    (cons (oref element name) value)))
+                              elements)))
+      (slack-dialog--submit this dialog-id team submission))))
+
+(defun slack-dialog-get (id team)
+  (let ((url "https://slack.com/api/dialog.get")
+        (params (list (cons "dialog_id" id))))
+    (cl-labels
+        ((on-success (&key data &allow-other-keys)
+                     (slack-request-handle-error
+                      (data "slack-dialog-get")
+                      (slack-if-let*
+                          ((payload (plist-get data :dialog))
+                           (dialog (slack-dialog-create payload)))
+                          ;; (slack-dialog-submit dialog id team)
+                          (slack-buffer-display
+                           (slack-create-dialog-buffer id
+                                                       dialog
+                                                       team))
+                        ))))
+      (slack-request
+       (slack-request-create
+        url
+        team
+        :type "POST"
+        :params params
+        :success #'on-success)))))
+
+(defmethod slack-dialog-notify-cancel ((this slack-dialog) dialog-id team)
+  (slack-if-let* ((url "https://slack.com/api/dialog.notifyCancel")
+                  (params (list (cons "dialog_id" dialog-id)))
+                  (notify-cancelp (oref this notify-on-cancel)))
+      (cl-labels
+          ((on-success (&key data &allow-other-keys)
+                       (slack-request-handle-error
+                        (data "slack-dialog-notify-cancel"))))
+        (slack-request
+         (slack-request-create
+          url
+          team
+          :type "POST"
+          :params params
+          :success #'on-success)))))
+
+(defmethod slack-dialog-clear-errors ((this slack-dialog))
+  (oset this error-message nil)
+  (dolist (element (oref this elements))
+    (oset element errors nil)))
+
+(provide 'slack-dialog)
+;;; slack-dialog.el ends here