(ns heyarne.all-my-friends.views (:require [reagent.core :as r] [cljs-http.client :as http] [cljs.core.async :refer [blob [img-data cb] (let [canvas (js/document.createElement "canvas") ctx (.getContext canvas "2d")] (set! (.-width canvas) (.-width img-data)) (set! (.-height canvas) (.-height img-data)) (.putImageData ctx img-data 0 0) (.toBlob canvas cb "image/png"))) (defn preview [{{:keys [video predictions]} :snapshot}] (let [canvas (js/document.createElement "canvas") ctx (.getContext canvas "2d")] ;; this is most probably not the most beautiful component i have ever written (set! (.-predictions js/window) predictions) (set! (.-width canvas) (.-width video)) (set! (.-height canvas) (.-height video)) (.putImageData ctx video 0 0) (vis/draw-wireframe ctx predictions) [:img {:src (.toDataURL canvas)}])) (defn snapshot [{:keys [current-snapshot]}] (let [compliment (rand-nth ["Hübschi!" "Sweet." "Nice!" ":)" "Uh lala~"])] [:div#snapshot-preview.container [:p compliment] [preview {:snapshot current-snapshot}] [:button {:on-click #(image-data->blob (:video current-snapshot) (fn [blob] (dispatch [:upload/post {:snapshot blob :predictions (js/JSON.stringify (:predictions current-snapshot))}])))} "Abschicken"] [:button {:on-click #(dispatch [:running/discard-snapshot])} "Lieber noch eins"]])) (defn notifications [{:keys [messages]}] [:ul.notifications (for [[id {:keys [type message]}] messages] ^{:key id} [:li.message {:class (name type) :on-click #(dispatch [:message/hide id])} message])]) (defn running [{:keys [on-faces-detected halt?]}] (let [result (atom {:video nil :predictions nil})] (fn [{:keys [on-faces-detected halt?]}] [:div.container [:p "Tippe auf den Button um ein Bild zu machen."] [webcam-facemesh {:on-faces-detected (fn [ctx video predictions] (swap! result assoc :video video :predictions predictions) (on-faces-detected ctx predictions)) :halt? halt?}] [:button {:on-click #(dispatch [:running/snapshot (update @result :video video-snapshot)])} "Cheese"]]))) (defn app [] (let [state @state status (:status state) messages (:messages state) current-snapshot (get-in state [:snapshots :current]) uploading? (some? (get-in state [:http/requests "/upload"]))] (prn messages) [:<> [welcome-message {:hidden? (not= :welcome-message status)}] [notifications {:messages messages}] (when uploading? [:p "Bild wird hochgeladen"]) (when current-snapshot [snapshot {:current-snapshot current-snapshot}]) (case status :permission-rejected [:div "Sad :("] :running [running {:on-faces-detected vis/draw-sketch :halt? (some? current-snapshot)}] ;; default nil)]))