Skip to content

Commit 07e9d9e

Browse files
committed
[Feature] Implement Emoji Picker
Signed-off-by: Mohamed Javid <[email protected]>
1 parent b2840a7 commit 07e9d9e

34 files changed

+13888
-28
lines changed
984 Bytes
Loading
1.37 KB
Loading
939 Bytes
Loading
1.52 KB
Loading
350 Bytes
Loading
467 Bytes
Loading
819 Bytes
Loading
1.05 KB
Loading
1.05 KB
Loading
1.56 KB
Loading
622 Bytes
Loading
745 Bytes
Loading
1.06 KB
Loading
1.47 KB
Loading
848 Bytes
Loading
1.12 KB
Loading

src/js/data/emojis.json

+13,402
Large diffs are not rendered by default.

src/mocks/js_dependencies.cljs

+1
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@
420420
"react-native-transparent-video" react-native-transparent-video
421421
"react-native-orientation-locker" react-native-orientation-locker
422422
"react-native-gifted-charts" react-native-gifted-charts
423+
"../src/js/data/emojis.json" #js []
423424
"../src/js/worklets/core.js" worklet-factory
424425
"../src/js/worklets/shell/bottom_tabs.js" #js {}
425426
"../src/js/worklets/shell/home_stack.js" #js {}

src/quo2/components/dividers/divider_label/style.cljs

+5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
(ns quo2.components.dividers.divider-label.style
22
(:require [quo2.foundations.colors :as colors]))
33

4+
(defn get-height
5+
[tight?]
6+
(if tight? 34 42))
7+
48
(defn- get-border-color
59
[blur? theme]
610
(colors/theme-colors (if blur? colors/neutral-80-opa-5 colors/neutral-10)
@@ -17,6 +21,7 @@
1721
[blur? tight? chevron theme]
1822
{:border-top-width 1
1923
:border-top-color (get-border-color blur? theme)
24+
:height (get-height tight?)
2025
:padding-top (if tight? 6 14)
2126
:padding-bottom 7
2227
:padding-left (if (= :left chevron) 16 20)

src/quo2/components/profile/showcase_nav/style.cljs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
(ns quo2.components.profile.showcase-nav.style
22
(:require [quo2.foundations.colors :as colors]))
33

4+
(def height 56)
5+
46
(def root-container
5-
{:height 56})
7+
{:height height})
68

79
(defn container
810
[state theme]

src/quo2/components/profile/showcase_nav/view.cljs

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[react-native.core :as rn]))
66

77
(defn- render-button
8-
[{:keys [icon id]} _ _ {:keys [state on-press active-id]}]
8+
[{:keys [icon id]} index _ {:keys [state on-press active-id]}]
99
(let [active? (= id active-id)
1010
button-type (if active? :grey :ghost)
1111
scroll-state? (= state :scroll)]
@@ -17,21 +17,21 @@
1717
:icon-only? true
1818
:on-press (fn []
1919
(when on-press
20-
(on-press id)))
20+
(on-press id index)))
2121
:container-style style/button-container}
2222
icon]))
2323

2424
(defn- view-internal
2525
[{:keys [theme container-style default-active state data on-press active-id]}]
2626
[rn/view
27-
{:style style/root-container
27+
{:style (merge style/root-container container-style)
2828
:accessibility-label :showcase-nav}
2929
[rn/flat-list
3030
{:data data
31-
:key-fn str
31+
:key-fn :id
3232
:horizontal true
3333
:shows-horizontal-scroll-indicator false
34-
:content-container-style (merge (style/container state theme) container-style)
34+
:content-container-style (style/container state theme)
3535
:render-fn render-button
3636
:render-data {:state state
3737
:on-press on-press

src/react_native/flat_list.cljs

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66

77
(defn- wrap-render-fn
88
[f render-data]
9-
(fn [data]
10-
(reagent/as-element [f (.-item ^js data) (.-index ^js data)
11-
(.-separators ^js data) render-data
12-
(.-isActive ^js data) (.-drag ^js data)])))
9+
(fn [^js data]
10+
(reagent/as-element [f (.-item data) (.-index data)
11+
(.-separators data) render-data
12+
(.-isActive data) (.-drag data)])))
1313

1414
(defn- wrap-on-drag-end-fn
1515
[f]
16-
(fn [data]
17-
(f (.-from ^js data) (.-to ^js data) (.-data ^js data))))
16+
(fn [^js data]
17+
(f (.-from data) (.-to data) (.-data data))))
1818

1919
(defn- wrap-key-fn
2020
[f]

src/status_im/events.cljs

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
status-im.wallet.choose-recipient.core
5252
[status-im.wallet.core :as wallet]
5353
status-im.wallet.custom-tokens.core
54+
status-im2.contexts.emoji-picker.events
5455
status-im2.contexts.shell.activity-center.events
5556
status-im2.contexts.shell.activity-center.notification.contact-requests.events
5657
status-im2.contexts.shell.jump-to.events
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
(ns status-im2.contexts.emoji-picker.constants
2+
(:require [react-native.core :as rn]))
3+
4+
(def search-debounce-ms 600)
5+
6+
(def emojis-per-row 7)
7+
8+
(def emoji-size 32)
9+
10+
(def emoji-row-padding-horizontal 20)
11+
12+
(def emoji-section-header-margin-bottom 6)
13+
14+
(def emoji-row-separator-height 16)
15+
16+
(def emoji-item-margin-right
17+
(/ (- (:width (rn/get-window)) (* emoji-row-padding-horizontal 2) (* emoji-size emojis-per-row))
18+
(- emojis-per-row 1)))
19+
20+
(def get-item-height
21+
(+ emoji-size emoji-row-separator-height))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
(ns status-im2.contexts.emoji-picker.data
2+
(:require [status-im2.contexts.emoji-picker.constants :as constants]
3+
[utils.transforms :as transforms]))
4+
5+
;; The dataset is grouped by number to reduce the file size.
6+
;; It is then categorized below:
7+
;; - people (0 and 1)
8+
;; - nature (3)
9+
;; - food (4)
10+
;; - activity (6)
11+
;; - travel (5)
12+
;; - objects (7)
13+
;; - symbols (8)
14+
;; - flags (9)
15+
;;
16+
;; NOTE: smileys & emoticons (0) and people (1) are grouped in one section
17+
18+
(def emoji-data (transforms/js->clj (js/require "../src/js/data/emojis.json")))
19+
20+
(def list-data
21+
[{:title :t/emoji-people
22+
:icon :i/faces ;; 0 and 1
23+
:id :people
24+
:data []}
25+
{:title :t/emoji-nature
26+
:icon :i/nature ;; 3
27+
:id :nature
28+
:data []}
29+
{:title :t/emoji-food
30+
:icon :i/food ;; 4
31+
:id :food
32+
:data []}
33+
{:title :t/emoji-activity
34+
:icon :i/activity ;; 6
35+
:id :activity
36+
:data []}
37+
{:title :t/emoji-travel
38+
:icon :i/travel ;; 5
39+
:id :travel
40+
:data []}
41+
{:title :t/emoji-objects
42+
:icon :i/objects ;; 7
43+
:id :objects
44+
:data []}
45+
{:title :t/emoji-symbols
46+
:icon :i/symbols ;; 8
47+
:id :symbols
48+
:data []}
49+
{:title :t/emoji-flags
50+
:icon :i/flags ;; 9
51+
:id :flags
52+
:data []}])
53+
54+
(def categorized-and-partitioned
55+
(->> (reduce
56+
(fn [acc {:keys [group] :as emoji}]
57+
(case group
58+
59+
0
60+
(update-in acc [0 :data] conj emoji)
61+
62+
1
63+
(update-in acc [0 :data] conj emoji)
64+
65+
3
66+
(update-in acc [1 :data] conj emoji)
67+
68+
4
69+
(update-in acc [2 :data] conj emoji)
70+
71+
5
72+
(update-in acc [4 :data] conj emoji)
73+
74+
6
75+
(update-in acc [3 :data] conj emoji)
76+
77+
7
78+
(update-in acc [5 :data] conj emoji)
79+
80+
8
81+
(update-in acc [6 :data] conj emoji)
82+
83+
9
84+
(update-in acc [7 :data] conj emoji)))
85+
list-data
86+
emoji-data)
87+
(reduce (fn [acc {:keys [data] :as item}]
88+
(conj acc (assoc item :data (partition-all constants/emojis-per-row data))))
89+
[])))
90+
91+
(def flatten-data
92+
(mapcat (fn [{:keys [title id data]}]
93+
(into [{:title title :id id :header? true}] data))
94+
categorized-and-partitioned))
95+
96+
(def filter-section-header-index
97+
(keep-indexed #(when (:header? %2) %1) flatten-data))
98+
99+
(defn get-section-header-index-in-data
100+
[index]
101+
(nth filter-section-header-index index))
102+
103+
(def section-group
104+
{0 :people
105+
1 :people
106+
3 :nature
107+
4 :food
108+
6 :activity
109+
5 :travel
110+
7 :objects
111+
8 :symbols
112+
9 :flags})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
(ns status-im2.contexts.emoji-picker.events
2+
(:require [utils.re-frame :as rf]))
3+
4+
(rf/defn open-emoji-picker
5+
{:events [:emoji-picker/open]}
6+
[_ {:keys [on-select]}]
7+
{:dispatch [:open-modal :emoji-picker {:on-select on-select}]})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
(ns status-im2.contexts.emoji-picker.style
2+
(:require [quo2.components.profile.showcase-nav.style :as showcase-nav.style]
3+
[quo2.foundations.colors :as colors]
4+
[react-native.safe-area :as safe-area]
5+
[status-im2.contexts.emoji-picker.constants :as constants]))
6+
7+
(def flex-spacer {:flex 1})
8+
9+
(def category-nav-height (+ (safe-area/get-bottom) showcase-nav.style/height))
10+
11+
(def search-input-container
12+
{:padding-horizontal 20
13+
:padding-bottom 12})
14+
15+
(defn section-header
16+
[theme]
17+
{:background-color (colors/theme-colors colors/white colors/neutral-95 theme)
18+
:z-index 1
19+
:margin-bottom constants/emoji-section-header-margin-bottom})
20+
21+
(def emoji-row-container
22+
{:padding-horizontal constants/emoji-row-padding-horizontal
23+
:padding-bottom constants/emoji-row-separator-height
24+
:flex-direction :row
25+
:overflow :hidden})
26+
27+
(defn emoji-container
28+
[last-item-on-row?]
29+
(cond-> {:height constants/emoji-size
30+
:width constants/emoji-size
31+
:margin-right constants/emoji-item-margin-right}
32+
33+
last-item-on-row?
34+
(dissoc :margin-right)))
35+
36+
(def list-container-style
37+
{:padding-bottom showcase-nav.style/height})
38+
39+
(def empty-results
40+
{:margin-top 100})
41+
42+
(def category-container
43+
{:height category-nav-height
44+
:overflow :hidden
45+
:position :absolute
46+
:left 0
47+
:right 0
48+
:bottom 0
49+
:z-index 1})
50+
51+
(def category-blur-container
52+
{:height category-nav-height
53+
:overflow :hidden})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
(ns status-im2.contexts.emoji-picker.utils
2+
(:require [clojure.string :as string]
3+
[status-im2.contexts.emoji-picker.constants :as constants]
4+
[status-im2.contexts.emoji-picker.data :refer [emoji-data]]))
5+
6+
(defn search-emoji
7+
[search-query]
8+
(let [cleaned-query (string/lower-case (string/trim search-query))]
9+
(->> (filter (fn [{:keys [label tags emoticon]}]
10+
(or (string/includes? label cleaned-query)
11+
(when emoticon
12+
(if (vector? emoticon)
13+
(some #(string/includes? (string/lower-case %) cleaned-query) emoticon)
14+
(string/includes? (string/lower-case emoticon) cleaned-query)))
15+
(some #(string/includes? % cleaned-query) tags)))
16+
emoji-data)
17+
(partition-all constants/emojis-per-row))))

0 commit comments

Comments
 (0)