mirror of
https://github.com/penpot/penpot.git
synced 2025-06-05 13:51:40 +02:00
96 lines
3.1 KiB
Clojure
96 lines
3.1 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
;;
|
|
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
|
;; defined by the Mozilla Public License, v. 2.0.
|
|
;;
|
|
;; Copyright (c) 2020 UXBOX Labs SL
|
|
|
|
(ns app.main.ui.workspace.presence
|
|
(:require
|
|
[rumext.alpha :as mf]
|
|
[beicon.core :as rx]
|
|
[app.main.refs :as refs]
|
|
[app.main.store :as st]
|
|
[app.util.time :as dt]
|
|
[app.util.timers :as tm]
|
|
[app.util.router :as rt]))
|
|
|
|
(def pointer-icon-path
|
|
(str "M5.292 4.027L1.524.26l-.05-.01L0 0l.258 1.524 3.769 3.768zm-.45 "
|
|
"0l-.313.314L1.139.95l.314-.314zm-.5.5l-.315.316-3.39-3.39.315-.315 "
|
|
"3.39 3.39zM1.192.526l-.668.667L.431.646.64.43l.552.094z"))
|
|
|
|
(mf/defc session-cursor
|
|
[{:keys [session] :as props}]
|
|
(let [point (:point session)
|
|
color (:color session "#000000")
|
|
transform (str "translate(" (:x point) "," (:y point) ") scale(4)")]
|
|
[:g.multiuser-cursor {:transform transform}
|
|
[:path {:fill color
|
|
:d pointer-icon-path
|
|
:font-family "sans-serif"}]
|
|
[:g {:transform "translate(0 -291.708)"}
|
|
[:rect {:width "21.415"
|
|
:height "5.292"
|
|
:x "6.849"
|
|
:y "291.755"
|
|
:fill color
|
|
:fill-opacity ".893"
|
|
:paint-order "stroke fill markers"
|
|
:rx ".794"
|
|
:ry ".794"}]
|
|
[:text {:x "9.811"
|
|
:y "295.216"
|
|
:fill "#fff"
|
|
:stroke-width ".265"
|
|
:font-family "Open Sans"
|
|
:font-size"2.91"
|
|
:font-weight "400"
|
|
:letter-spacing"0"
|
|
:style {:line-height "1.25"}
|
|
:word-spacing "0"}
|
|
(:fullname session)]]]))
|
|
|
|
(mf/defc active-cursors
|
|
{::mf/wrap [mf/memo]}
|
|
[{:keys [page-id] :as props}]
|
|
(let [counter (mf/use-state 0)
|
|
sessions (mf/deref refs/workspace-presence)
|
|
sessions (->> (vals sessions)
|
|
(filter #(= page-id (:page-id %)))
|
|
(filter #(>= 3000 (- (inst-ms (dt/now)) (inst-ms (:updated-at %))))))]
|
|
(mf/use-effect
|
|
nil
|
|
(fn []
|
|
(let [sem (tm/schedule 1000 #(swap! counter inc))]
|
|
(fn [] (rx/dispose! sem)))))
|
|
|
|
(for [session sessions]
|
|
(when (:point session)
|
|
[:& session-cursor {:session session :key (:id session)}]))))
|
|
|
|
(mf/defc session-widget
|
|
[{:keys [session self?] :as props}]
|
|
(let [photo (:photo-uri session "/images/avatar.jpg")]
|
|
[:li.tooltip.tooltip-bottom
|
|
{:alt (:fullname session)
|
|
:on-click (when self?
|
|
#(st/emit! (rt/navigate :settings/profile)))}
|
|
[:img {:style {:border-color (:color session)}
|
|
:src photo}]]))
|
|
|
|
(mf/defc active-sessions
|
|
{::mf/wrap [mf/memo]}
|
|
[]
|
|
(let [profile (mf/deref refs/profile)
|
|
sessions (mf/deref refs/workspace-presence)]
|
|
[:ul.active-users
|
|
(for [session (vals sessions)]
|
|
[:& session-widget
|
|
{:session session
|
|
:self? (= (:id session) (:id profile))
|
|
:key (:id session)}])]))
|
|
|
|
|