summaryrefslogtreecommitdiff
path: root/src/wasp-model.el
blob: c38da58b99dc9b4bdd68b6748fb6cb21b7df43c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
;;; wasp-model --- Model controls -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:

(require 'dash)
(require 's)
(require 'f)
(require 'ht)
(require 'cl-lib)
(require 'wasp-utils)
(require 'wasp-bus)
(require 'wasp-twitch)
(require 'wasp-user)

(defun w/model-get-default-backgrounds (k)
  "Retrieve the background playlist and pass it to K."
  (w/db-get "modelbackgrounds"
    (lambda (res)
      (funcall k (if (s-present? res) (w/read-sexp res) nil)))))

(defun w/model-add-default-background (url)
  "Add URL to the background playlist."
  (w/model-get-default-backgrounds
    (lambda (cur)
      (w/db-set "modelbackgrounds" (format "%S" (cons url cur))))))

(defun w/model-frame-test ()
  "Submit a test frame for the new model."
  (let ((data
          (seq-mapcat #'byte-to-string (apply #'seq-concatenate 'list (seq-into (caddr (u/load-image-png "/home/llll/mrgreenbig.png")) 'list)) 'string)
          ;; (seq-mapcat #'byte-to-string (--mapcat (list 0 255 0) (-iota (* 64 64))) 'string)
          ))
    (w/pub '(avatar frame) (list (base64-encode-string data t)))))

(defun w/color-value-to-html-code (cval)
  "Convert color value CVAL to an HTML color code."
  (and
   cval
   (format
    "#%02x%02x%02x"
    (truncate (* 255 (/ (car cval) 65535.0)))
    (truncate (* 255 (/ (cadr cval) 65535.0)))
    (truncate (* 255 (/ (caddr cval) 65535.0)))
    )))

(defun w/color-to-html-code (cname)
  "Convert color name CNAME to an HTML color code."
  (w/color-value-to-html-code (color-values cname)))

(defvar w/model-palette-counter nil "Time to display model changes.")

(defun w/model-record-change ()
  "Record a change to the model in the counter."
  (setf w/model-palette-counter 300))

(defun w/model-reset ()
  "Reset the model palette."
  (interactive)
  (w/pub '(avatar reset))
  (w/model-get-default-backgrounds
    (lambda (bgs)
      (when bgs
        (w/model-region-video "hair" (w/pick-random bgs))))))

(defun w/model-toggle (toggle)
  "Toggle TOGGLE on model."
  (w/model-record-change)
  (w/pub '(avatar toggle) (list toggle)))

(defun w/model-toggle-set (toggle)
  "Set TOGGLE on model."
  (w/model-record-change)
  (w/pub '(avatar toggle set) (list toggle)))

(defun w/model-toggle-unset (toggle)
  "Unset TOGGLE on model."
  (w/model-record-change)
  (w/pub '(avatar toggle unset) (list toggle)))

(defun w/model-background-text (msg)
  "Change the background text of the model to MSG."
  (let* ((cleanmsg (s-trim (w/clean-string msg)))
         (encoded (w/encode-string cleanmsg)))
    (unless (s-blank? cleanmsg)
      (w/model-record-change)
      (w/pub '(avatar text) (list encoded)))))

(w/defstruct
 w/color-source
 type ;; 'color or 'twitch-emote or '7tv-emote or 'video-url
 value)

(defun w/string-to-color-source (s k)
  "Convert S to a color source and pass it to K."
  (w/twitch-get-emote
   s
   (lambda (emote)
     (let ((7tv-emote (w/twitch-get-7tv-emote s))
           (color (color-values s))
           (url
            (-contains?
             '("www.youtube.com" "youtube.com" "youtu.be" "www.twitch.tv" "twitch.tv" "clips.twitch.tv")
             (url-host (url-generic-parse-url s)))))
       (funcall
        k
        (cond
         (url (w/make-color-source :type 'video-url :value s))
         (emote (w/make-color-source :type 'twitch-emote :value emote))
         (7tv-emote (w/make-color-source :type '7tv-emote :value 7tv-emote))
         (color (w/make-color-source :type 'color :value color))
         (t nil)))))))

(defun w/model-region-word (type msg)
  "Change the model region TYPE to MSG."
  (let* ((cleanmsg (s-trim (w/clean-string msg)))
         (encodedmsg (w/encode-string cleanmsg)))
    (unless (s-blank? cleanmsg)
      (w/model-record-change)
      (w/pub '(avatar palette word) (list type encodedmsg)))))

(defun w/model-region-color (type color)
  "Change the model region TYPE to COLOR."
  (let* ((encodedcol (w/encode-string (w/color-value-to-html-code color))))
    (w/model-record-change)
    (w/pub '(avatar palette color) (list type encodedcol))))

(defun w/model-region-image (type path)
  "Change the model region TYPE to an image at PATH."
  (interactive)
  (let* ((cleanpath (s-trim (w/clean-string path)))
         (encodedpath (w/encode-string cleanpath)))
    (unless (s-blank? cleanpath)
      (w/model-record-change)
      (w/pub '(avatar palette image) (list type encodedpath)))))

(defun w/model-region-video (type url)
  "Change the model region TYPE to a video at URL."
  (interactive)
  (let* ((cleanurl (s-trim (w/clean-string url)))
         (encodedurl (w/encode-string cleanurl)))
    (unless (s-blank? cleanurl)
      (w/model-record-change)
      (w/pub '(avatar palette video) (list type encodedurl)))))

(defun w/model-region-user-avatar (type user)
  "Change the model region TYPE to USER's avatar."
  (w/twitch-get-user-avatar
   user
   (lambda ()
     (when (f-exists? (w/twitch-user-avatar-path user))
       (w/model-region-image type (w/twitch-user-avatar-path user))))))

(defun w/model-region-color-source (type cs)
  "Change the model region TYPE to CS."
  (cl-case (w/color-source-type cs)
    (color
     (w/model-region-color
      type
      (w/color-source-value cs)))
    (twitch-emote
     (w/model-region-image
      type
      (w/twitch-emote-path (w/color-source-value cs))))
    (7tv-emote
     (w/model-region-image
      type
      (w/twitch-7tv-emote-path (w/color-source-value cs))))
    (video-url
     (w/model-region-video
      type
      (w/color-source-value cs)))
    (t nil)))

(defun w/handle-redeem-region-swap (type)
  "Return a redeem callback for region swap of TYPE.
If the color is unspecified, use DEFCOLOR."
  (lambda (user inp)
    (let ((splinp (s-split-up-to " " (s-trim inp) 1))
          (auth (w/user-authorized)))
      (w/string-to-color-source
       (car splinp)
       (lambda (cs)
         (let ((text (if cs (cadr splinp) (s-join " " splinp))))
           (w/write-chat-event (format "%s changes my %s to %s" user type inp))
           (when cs
             (if (or auth
                     (not (eq 'video-url (w/color-source-type cs))))
                 (w/model-region-color-source type cs)
               (w/write-chat-event (format "%s is not authorized to play video, boost harder" user))))
           (when text
             (w/model-region-word type text))))))))

(defvar w/model-timer nil)
(defun w/run-model-timer ()
  "Run the model timer."
  (when w/model-timer
    (cancel-timer w/model-timer))

  (when w/model-palette-counter
    (cl-decf w/model-palette-counter)
    (when (<= w/model-palette-counter 0)
      (setf w/model-palette-counter nil)
      (w/model-reset)
      ))

  (setq
   w/model-timer
   (run-with-timer 1 nil #'w/run-model-timer)))

(provide 'wasp-model)
;;; wasp-model.el ends here