Fix reaction images and implement Selectors > Reactions component (#16114)
Fixes reaction images and implements the component Selectors > Reactions that, for some reason, wasn't implemented as a separate quo2 component as per Figma https://www.figma.com/file/qLLuMLfpGxK9OfpIavwsmK/Iconset?type=design&node-id=942-218&t=cqTr12Q3zVHaLoap-0 Fixes https://github.com/status-im/status-mobile/issues/16045 Note: Reaction images in the Design System are not icons, so that's why you are seeing a bunch of icons removed from icons2. The directory resources/images/reactions already existed, and so I used images from that directory instead.
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.9 KiB |
|
@ -1,6 +1,7 @@
|
|||
(ns quo2.components.reactions.reaction
|
||||
(:require [quo2.components.icon :as icons]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.reactions.resource :as resource]
|
||||
[quo2.components.reactions.style :as style]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as theme]
|
||||
|
@ -28,9 +29,10 @@
|
|||
:on-long-press on-long-press
|
||||
:accessibility-label accessibility-label
|
||||
:style (style/reaction neutral?)}
|
||||
[icons/icon emoji
|
||||
{:no-color true
|
||||
:size 16}]
|
||||
[rn/image
|
||||
{:style {:width 16 :height 16}
|
||||
:accessibility-label :emoji
|
||||
:source (resource/get-reaction emoji)}]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :semi-bold
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
(ns quo2.components.reactions.resource
|
||||
(:require [clojure.java.io :as io]
|
||||
[clojure.string :as string]))
|
||||
|
||||
(def ^:private reactions-dir "./resources/images/reactions/")
|
||||
|
||||
(defn- resolve-reaction
|
||||
[reaction]
|
||||
(let [path (str reactions-dir (name reaction) ".png")
|
||||
file (io/file path)]
|
||||
(when (.exists file)
|
||||
`(js/require ~(str "." path)))))
|
||||
|
||||
(defn- find-all-image-base-names
|
||||
[]
|
||||
(let [dir (io/file reactions-dir)]
|
||||
(->> dir
|
||||
file-seq
|
||||
(filter #(string/ends-with? % "png"))
|
||||
(map #(.getName %))
|
||||
(map #(string/replace % #"\.png$" ""))
|
||||
(map #(first (string/split % #"@")))
|
||||
distinct)))
|
||||
|
||||
(defmacro resolve-all-reactions
|
||||
[]
|
||||
(reduce (fn [acc reaction]
|
||||
(assoc acc reaction (resolve-reaction reaction)))
|
||||
{}
|
||||
(find-all-image-base-names)))
|
|
@ -0,0 +1,12 @@
|
|||
(ns quo2.components.reactions.resource
|
||||
(:require-macros [quo2.components.reactions.resource :refer [resolve-all-reactions]]))
|
||||
|
||||
(def ^:private reactions
|
||||
(resolve-all-reactions))
|
||||
|
||||
(defn get-reaction
|
||||
[reaction]
|
||||
(assert (keyword? reaction) "Reaction should be a keyword")
|
||||
(assert (= "reaction" (namespace reaction))
|
||||
"Reaction keyword should be namespaced with :reaction")
|
||||
(get reactions (name reaction)))
|
|
@ -0,0 +1,23 @@
|
|||
(ns quo2.components.selectors.reactions.component-spec
|
||||
(:require [quo2.components.selectors.reactions.view :as view]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Selectors > Reactions"
|
||||
(h/test "renders component"
|
||||
(h/render [view/view :reaction/sad])
|
||||
(h/is-truthy (h/get-by-label-text :reaction)))
|
||||
|
||||
(h/describe "on-press event"
|
||||
(h/test "starts with released state"
|
||||
(let [on-press (h/mock-fn)]
|
||||
(h/render [view/view :reaction/love {:on-press on-press}])
|
||||
(h/fire-event :press (h/get-by-label-text :reaction))
|
||||
(h/was-called on-press)))
|
||||
|
||||
(h/test "starts with pressed state"
|
||||
(let [on-press (h/mock-fn)]
|
||||
(h/render [view/view :reaction/love
|
||||
{:on-press on-press
|
||||
:start-pressed? true}])
|
||||
(h/fire-event :press (h/get-by-label-text :reaction))
|
||||
(h/was-called on-press)))))
|
|
@ -0,0 +1,11 @@
|
|||
(ns quo2.components.selectors.reactions.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn container
|
||||
[pressed?]
|
||||
{:padding 10
|
||||
:border-radius 12
|
||||
:border-width 1
|
||||
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80)
|
||||
:background-color (when pressed?
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80-opa-40))})
|
|
@ -0,0 +1,25 @@
|
|||
(ns quo2.components.selectors.reactions.view
|
||||
(:require [quo2.components.reactions.resource :as reactions.resource]
|
||||
[quo2.components.selectors.reactions.style :as style]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn view
|
||||
[_ {:keys [start-pressed?]}]
|
||||
(let [pressed? (reagent/atom start-pressed?)]
|
||||
(fn [emoji
|
||||
{:keys [container-style on-press
|
||||
accessibility-label]
|
||||
:or {accessibility-label :reaction}}]
|
||||
[rn/touchable-without-feedback
|
||||
{:accessibility-label accessibility-label
|
||||
:on-press (fn [e]
|
||||
(swap! pressed? not)
|
||||
(when on-press
|
||||
(on-press e)))}
|
||||
[rn/view
|
||||
{:style (merge (style/container @pressed?)
|
||||
container-style)}
|
||||
[rn/image
|
||||
{:source (reactions.resource/get-reaction emoji)
|
||||
:style {:width 20 :height 20}}]]])))
|
|
@ -64,6 +64,7 @@
|
|||
quo2.components.profile.profile-card.view
|
||||
quo2.components.profile.select-profile.view
|
||||
quo2.components.reactions.reaction
|
||||
quo2.components.selectors.reactions.view
|
||||
quo2.components.record-audio.record-audio.view
|
||||
quo2.components.record-audio.soundtrack.view
|
||||
quo2.components.selectors.disclaimer.view
|
||||
|
@ -110,6 +111,9 @@
|
|||
(def skeleton quo2.components.loaders.skeleton/skeleton)
|
||||
(def author quo2.components.messages.author.view/author)
|
||||
|
||||
;;;; SELECTORS
|
||||
(def reactions quo2.components.selectors.reactions.view/view)
|
||||
|
||||
;;;; AVATAR
|
||||
(def account-avatar quo2.components.avatars.account-avatar/account-avatar)
|
||||
(def channel-avatar quo2.components.avatars.channel-avatar/channel-avatar)
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
[quo2.components.drawers.drawer-buttons.component-spec]
|
||||
[quo2.components.drawers.permission-context.component-spec]
|
||||
[quo2.components.inputs.input.component-spec]
|
||||
[quo2.components.keycard.component-spec]
|
||||
[quo2.components.inputs.profile-input.component-spec]
|
||||
[quo2.components.inputs.recovery-phrase.component-spec]
|
||||
[quo2.components.inputs.title-input.component-spec]
|
||||
[quo2.components.keycard.component-spec]
|
||||
[quo2.components.links.link-preview.component-spec]
|
||||
[quo2.components.links.url-preview-list.component-spec]
|
||||
[quo2.components.links.url-preview.component-spec]
|
||||
[quo2.components.links.link-preview.component-spec]
|
||||
[quo2.components.markdown.--tests--.text-component-spec]
|
||||
[quo2.components.notifications.notification.component-spec]
|
||||
[quo2.components.onboarding.small-option-card.component-spec]
|
||||
|
@ -30,6 +30,7 @@
|
|||
[quo2.components.record-audio.soundtrack.--tests--.soundtrack-component-spec]
|
||||
[quo2.components.selectors.disclaimer.component-spec]
|
||||
[quo2.components.selectors.filter.component-spec]
|
||||
[quo2.components.selectors.reactions.component-spec]
|
||||
[quo2.components.selectors.selectors.component-spec]
|
||||
[quo2.components.share.share-qr-code.component-spec]
|
||||
[quo2.components.tags.--tests--.status-tags-component-spec]))
|
||||
|
|
|
@ -71,12 +71,12 @@
|
|||
(def request-to-join-pending-state 1)
|
||||
|
||||
(def reactions
|
||||
{emoji-reaction-love :i/love
|
||||
emoji-reaction-thumbs-up :i/thumbs-up
|
||||
emoji-reaction-thumbs-down :i/thumbs-down
|
||||
emoji-reaction-laugh :i/laugh
|
||||
emoji-reaction-sad :i/sad
|
||||
emoji-reaction-angry :i/angry})
|
||||
{emoji-reaction-love :reaction/love
|
||||
emoji-reaction-thumbs-up :reaction/thumbs-up
|
||||
emoji-reaction-thumbs-down :reaction/thumbs-down
|
||||
emoji-reaction-laugh :reaction/laugh
|
||||
emoji-reaction-sad :reaction/sad
|
||||
emoji-reaction-angry :reaction/angry})
|
||||
|
||||
(def ^:const invitation-state-unknown 0)
|
||||
(def ^:const invitation-state-requested 1)
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
[react-native.core :as rn]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im2.contexts.chat.composer.reply.view :as reply]
|
||||
[status-im2.common.not-implemented :as not-implemented]
|
||||
[status-im2.constants :as constants]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
|
@ -175,29 +174,23 @@
|
|||
:padding-horizontal 30
|
||||
:padding-top 5
|
||||
:padding-bottom 15}}
|
||||
(doall
|
||||
(for [[id icon] constants/reactions]
|
||||
(let [emoji-reaction-id (get own-reactions id)]
|
||||
^{:key id}
|
||||
[not-implemented/not-implemented
|
||||
[quo/button
|
||||
(merge
|
||||
{:size 40
|
||||
:type (if emoji-reaction-id :grey :ghost)
|
||||
:icon true
|
||||
:icon-no-color true
|
||||
:accessibility-label (str "emoji-picker-" id)
|
||||
:on-press (fn []
|
||||
(if emoji-reaction-id
|
||||
(rf/dispatch [:models.reactions/send-emoji-reaction-retraction
|
||||
{:message-id message-id
|
||||
:emoji-id id
|
||||
:emoji-reaction-id emoji-reaction-id}])
|
||||
(rf/dispatch [:models.reactions/send-emoji-reaction
|
||||
{:message-id message-id
|
||||
:emoji-id id}]))
|
||||
(rf/dispatch [:hide-bottom-sheet]))})
|
||||
icon]])))]))
|
||||
(for [[id reaction-name] constants/reactions
|
||||
:let [emoji-reaction-id (get own-reactions id)]]
|
||||
^{:key id}
|
||||
[quo/reactions reaction-name
|
||||
{:start-pressed? (boolean emoji-reaction-id)
|
||||
:accessibility-label (str "reaction-" (name reaction-name))
|
||||
:on-press
|
||||
(fn []
|
||||
(if emoji-reaction-id
|
||||
(rf/dispatch [:models.reactions/send-emoji-reaction-retraction
|
||||
{:message-id message-id
|
||||
:emoji-id id
|
||||
:emoji-reaction-id emoji-reaction-id}])
|
||||
(rf/dispatch [:models.reactions/send-emoji-reaction
|
||||
{:message-id message-id
|
||||
:emoji-id id}]))
|
||||
(rf/dispatch [:hide-bottom-sheet]))}])]))
|
||||
|
||||
(defn reactions-and-actions
|
||||
[message-data
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
[status-im2.contexts.quo-preview.avatars.group-avatar :as group-avatar]
|
||||
[status-im2.contexts.quo-preview.avatars.icon-avatar :as icon-avatar]
|
||||
[status-im2.contexts.quo-preview.avatars.user-avatar :as user-avatar]
|
||||
[status-im2.contexts.quo-preview.selectors.reactions :as selector-reactions]
|
||||
[status-im2.contexts.quo-preview.avatars.wallet-user-avatar :as wallet-user-avatar]
|
||||
[status-im2.contexts.quo-preview.banners.banner :as banner]
|
||||
[status-im2.contexts.quo-preview.buttons.button :as button]
|
||||
|
@ -296,7 +297,10 @@
|
|||
:component filter/preview}
|
||||
{:name :selectors
|
||||
:options {:topBar {:visible true}}
|
||||
:component selectors/preview-selectors}]
|
||||
:component selectors/preview-selectors}
|
||||
{:name :select-reactions
|
||||
:options {:topBar {:visible true}}
|
||||
:component selector-reactions/preview}]
|
||||
:settings [{:name :privacy-option
|
||||
:options {:topBar {:visible true}}
|
||||
:component privacy-option/preview-options}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
(ns status-im2.contexts.quo-preview.reactions.react
|
||||
(:require [quo2.components.reactions.reaction :as quo2.reaction]
|
||||
(:require [clojure.string :as string]
|
||||
[quo2.components.reactions.reaction :as quo2.reaction]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
|
||||
(def descriptor
|
||||
|
@ -12,29 +14,24 @@
|
|||
{:label "Emoji"
|
||||
:key :emoji
|
||||
:type :select
|
||||
:options [{:key :main-icons/love16
|
||||
:value "Love"}
|
||||
{:key :main-icons/thumbs-up16
|
||||
:value "Thumbs Up"}
|
||||
{:key :main-icons/thumbs-down16
|
||||
:value "Thumbs Down"}
|
||||
{:key :main-icons/laugh16
|
||||
:value "Laugh"}
|
||||
{:key :main-icons/sad16
|
||||
:value "Sad"}]}
|
||||
:options (for [reaction (vals constants/reactions)]
|
||||
{:key reaction
|
||||
:value (string/capitalize (name reaction))})}
|
||||
{:label "Neutral"
|
||||
:key :neutral?
|
||||
:type :boolean}])
|
||||
|
||||
(defn cool-preview
|
||||
[]
|
||||
(let [state (reagent/atom {:emoji :main-icons/love16})]
|
||||
(let [state (reagent/atom {:emoji :reaction/love})]
|
||||
(fn []
|
||||
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||
[rn/view {:padding-bottom 150}
|
||||
[preview/customizer state descriptor]
|
||||
[rn/view
|
||||
{:padding-vertical 60
|
||||
:justify-content :center
|
||||
:flex-direction :row
|
||||
:align-items :center}
|
||||
[quo2.reaction/reaction @state]
|
||||
[quo2.reaction/add-reaction @state]]]])))
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
(ns status-im2.contexts.quo-preview.selectors.reactions
|
||||
(:require [quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.constants :as constants]))
|
||||
|
||||
(defn cool-preview
|
||||
[]
|
||||
[rn/view
|
||||
[rn/view {:style {:margin-vertical 24}}
|
||||
(into [rn/view
|
||||
{:style {:flex 1
|
||||
:margin-top 200
|
||||
:flex-direction :row
|
||||
:justify-content :center
|
||||
:align-items :center}}]
|
||||
(for [emoji (vals constants/reactions)]
|
||||
^{:key emoji}
|
||||
[quo/reactions emoji {:container-style {:margin-right 5}}]))]])
|
||||
|
||||
(defn preview
|
||||
[]
|
||||
[rn/view
|
||||
{:style {:background-color (colors/theme-colors colors/white colors/neutral-95)
|
||||
:flex 1}}
|
||||
[rn/flat-list
|
||||
{:style {:flex 1}
|
||||
:keyboard-should-persist-taps :always
|
||||
:header [cool-preview]
|
||||
:key-fn str}]])
|