diff --git a/resources/images/icons/total_members12@2x.png b/resources/images/icons/total_members12@2x.png new file mode 100644 index 0000000000..a400e2ed01 Binary files /dev/null and b/resources/images/icons/total_members12@2x.png differ diff --git a/resources/images/icons/total_members12@3x.png b/resources/images/icons/total_members12@3x.png new file mode 100644 index 0000000000..4b76d4176a Binary files /dev/null and b/resources/images/icons/total_members12@3x.png differ diff --git a/resources/images/icons/total_members16@2x.png b/resources/images/icons/total_members16@2x.png new file mode 100644 index 0000000000..f6c4b348e1 Binary files /dev/null and b/resources/images/icons/total_members16@2x.png differ diff --git a/resources/images/icons/total_members16@3x.png b/resources/images/icons/total_members16@3x.png new file mode 100644 index 0000000000..45a0b234b1 Binary files /dev/null and b/resources/images/icons/total_members16@3x.png differ diff --git a/resources/images/icons/total_members20@2x.png b/resources/images/icons/total_members20@2x.png new file mode 100644 index 0000000000..06029b3622 Binary files /dev/null and b/resources/images/icons/total_members20@2x.png differ diff --git a/resources/images/icons/total_members20@3x.png b/resources/images/icons/total_members20@3x.png new file mode 100644 index 0000000000..2dece6c26c Binary files /dev/null and b/resources/images/icons/total_members20@3x.png differ diff --git a/src/quo2/components/activity_logs.cljs b/src/quo2/components/activity_logs.cljs new file mode 100644 index 0000000000..1a39388e68 --- /dev/null +++ b/src/quo2/components/activity_logs.cljs @@ -0,0 +1,81 @@ +(ns quo2.components.activity-logs + (:require [quo.react-native :as rn] + [quo2.foundations.colors :as colors] + [quo2.components.status-tags :as status-tags] + [quo2.components.button :as quo2.button] + [quo2.components.text :as text] + [quo2.components.icon :as quo2.icons])) + +(defn activity-logs [_] + (fn [{:keys [title + button-1 + button-2 + icon + unread + status + message + timestamp]}] + [rn/view {:flex-direction :row + :flex 1 + :border-radius 16 + :padding-top 8 + :padding-horizontal 12 + :padding-bottom 12 + :background-color (when unread + colors/primary-50-opa-10)} + [rn/view {:height 32 + :width 32 + :border-radius 100 + :margin-top 8 + :background-color colors/neutral-80-opa-60 + :flex-direction :column + :align-items :center + :justify-content :center} + [quo2.icons/icon icon {:color colors/white}]] + [rn/view {:flex-direction :column + :padding-left 8 + :flex 1} + [rn/view {:flex 1 + :flex-wrap :wrap} + [rn/view {:flex-direction :row} + [text/text {:weight :semi-bold + :style {:color colors/white} + :size :paragraph-1} + title] + [rn/view {:margin-left 8 + :margin-top 5} + [text/text {:size :label + :style {:text-transform :none + :color colors/neutral-40}} timestamp]]]] + (when message + [rn/view {:border-radius 12 + :margin-top 13 + :padding-horizontal 12 + :padding-vertical 8 + :background-color :red} + [text/text {:style {:color colors/white} + :size :paragraph-1} + message]]) + (when status + [rn/view {:padding-top 10 + :align-items :flex-start} + [status-tags/status-tag {:size :small + :override-theme :dark + :status status}]]) + (when (or button-1 button-2) + [rn/view {:padding-top 10 + :flex 1 + :flex-direction :row + :align-items :flex-start} + (when button-1 + [quo2.button/button + (assoc button-1 + :override-them :dark + :style {:margin-right 8}) + (:label button-1)]) + (when button-2 + [quo2.button/button + (assoc button-2 + :override-theme + :dark) + (:label button-2)])])]])) diff --git a/src/quo2/components/button.cljs b/src/quo2/components/button.cljs index d30f4e4669..17ff3c5b8b 100644 --- a/src/quo2/components/button.cljs +++ b/src/quo2/components/button.cljs @@ -28,6 +28,11 @@ :ghost {:icon-color colors/neutral-50 :label {:style {:color colors/black}} :background-color {:pr:pressedess colors/neutral-10}} + :success {:icon-color colors/white + :label {:style {:color colors/white}} + :background-color {:default colors/success-50 + :pressed colors/success-70 + :disabled colors/success-50}} :danger {:icon-color colors/white :label {:style {:color colors/white}} :background-color {:default colors/danger-50 @@ -55,6 +60,11 @@ :ghost {:icon-color colors/neutral-40 :label {:style {:color colors/white}} :background-color {:pressed colors/neutral-80}} + :success {:icon-color colors/white + :label {:style {:color colors/white}} + :background-color {:default colors/success-60 + :pressed colors/success-40 + :disabled colors/success-60}} :danger {:icon-color colors/white :label {:style {:color colors/white}} :background-color {:default colors/danger-50 @@ -105,12 +115,15 @@ [_ _] (let [pressed (reagent/atom false)] (fn [{:keys [on-press disabled type size before after above width + override-theme on-long-press accessibility-label icon style] :or {type :primary size 40}} children] (let [{:keys [icon-color background-color label border-color]} - (get-in themes [(theme/get-theme) type]) + (get-in themes [(or + override-theme + (theme/get-theme)) type]) state (cond disabled :disabled @pressed :pressed :else :default) icon-size (when (= 24 size) 12)] [rn/touchable-without-feedback (merge {:disabled disabled diff --git a/src/quo2/components/context_tags.cljs b/src/quo2/components/context_tags.cljs new file mode 100644 index 0000000000..894be4f3a9 --- /dev/null +++ b/src/quo2/components/context_tags.cljs @@ -0,0 +1,61 @@ +(ns quo2.components.context-tags + (:require [quo2.foundations.colors :as colors] + [quo.theme :as quo.theme] + [re-frame.core :as re-frame] + [quo2.components.text :as text] + [quo2.components.group-avatar :as group-avatar] + [quo.react-native :as rn])) + +(defn padding-left-for-type [type] + (case type + :group-avatar 3 + 8)) + +(defn trim-public-key [pk] + (str (subs pk 0 6) "..." (subs pk (- (count pk) 3)))) + +(defn base-tag [_ _] + (fn [{:keys [override-theme style]} & children] + (let [theme (or override-theme (quo.theme/get-theme))] + (into + [rn/view + (merge + {:border-radius 100 + :padding-vertical 3 + :flex-direction :row + :padding-right 8 + :padding-left 8 + :background-color (if (= theme :light) + colors/neutral-10 + colors/neutral-80)} style)] + children)))) + +(defn group-avatar-tag [_ _] + (fn [label opts] + [base-tag {:style {:padding-left 3}} + [group-avatar/group-avatar opts] + [text/text {:weight :medium + :size :paragraph-2} + + (str " " label)]])) + +(defn public-key-tag [_ _] + (fn [params public-key] + [base-tag params + [text/text {:weight :monospace + :size :paragraph-2} + (trim-public-key public-key)]])) + +(defn user-avatar-tag [_ _] + (fn [params public-key] + (let [{:keys [name photo]} @(re-frame/subscribe [:contacts/name-and-photo public-key])] + [base-tag (assoc-in params [:style :padding-left] 3) + [rn/image {:style {:width 20 + :border-radius 10 + :background-color :white + :height 20} + :source {:uri photo}}] + [text/text {:weight :medium + :size :paragraph-2} + + (str " " name)]]))) diff --git a/src/quo2/components/group_avatar.cljs b/src/quo2/components/group_avatar.cljs new file mode 100644 index 0000000000..5ab226ee6e --- /dev/null +++ b/src/quo2/components/group_avatar.cljs @@ -0,0 +1,27 @@ +(ns quo2.components.group-avatar + (:require [quo2.foundations.colors :as colors] + [quo.theme :as quo.theme] + [quo2.components.icon :as icon] + [quo.react-native :as rn])) + +(def sizes + {:icon {:small 12 + :medium 16 + :large 20} + :container {:small 20 + :medium 32 + :large 48}}) + +(defn group-avatar [_] + (fn [{:keys [color size override-theme]}] + (let [theme (or override-theme (quo.theme/get-theme)) + container-size (get-in sizes [:container size]) + icon-size (get-in sizes [:icon size])] + [rn/view {:width container-size + :height container-size + :align-items :center + :justify-content :center + :border-radius (/ container-size 2) + :background-color (colors/custom-color color theme)} + [icon/icon :total-members {:size icon-size + :color colors/white-opa-70}]]))) diff --git a/src/quo2/components/icon.cljs b/src/quo2/components/icon.cljs index b655095f64..c4f14b2697 100644 --- a/src/quo2/components/icon.cljs +++ b/src/quo2/components/icon.cljs @@ -10,11 +10,17 @@ [icons/icon (str (name icon-name) size) (merge props {:width size :height size})]))) +(defn icon-for-theme + ([icon-name theme] + (icon-for-theme icon-name theme nil)) + ([icon-name theme props] + (let [theme-icon-name (if (= theme :dark) + (str (name icon-name) "-dark") + icon-name)] + (icon theme-icon-name props)))) + (defn theme-icon ([icon-name] (theme-icon icon-name nil)) ([icon-name props] - (let [theme-icon-name (if (theme/dark?) - (str (name icon-name) "-dark") - icon-name)] - (icon theme-icon-name props)))) + (icon-for-theme icon-name (theme/get-theme) props))) diff --git a/src/quo2/components/status_tags.cljs b/src/quo2/components/status_tags.cljs index 828e2df38d..8b9ef7212d 100644 --- a/src/quo2/components/status_tags.cljs +++ b/src/quo2/components/status_tags.cljs @@ -1,6 +1,7 @@ (ns quo2.components.status-tags (:require [status-im.i18n.i18n :as i18n] [quo2.foundations.colors :as colors] + [quo.theme :as quo.theme] [quo2.components.icon :as icon] [quo2.components.text :as text] [quo.react-native :as rn])) @@ -24,6 +25,7 @@ border-color background-color icon + theme text-color label]}] (let [paragraph-size (if (= size :small) :paragraph-2 :paragraph-1)] @@ -31,49 +33,62 @@ (assoc (if (= size :small) small-container-style large-container-style) + :border-width 1 :border-color border-color :background-color background-color) - [text/text {:size paragraph-size} - [icon/theme-icon icon {:color :none - :size 12}] + [rn/view {:flex-direction :row + :flex 1} + [rn/view {:style {:justify-content :center + :align-items :center}} + [icon/icon-for-theme + icon + theme + {:no-color true + :size 12}]] [text/text {:size paragraph-size - :style {:color text-color}} (str " " label)]]]))) + :weight :medium + :style {:padding-left 5 + :color text-color}} label]]]))) -(defn positive [_] - (fn [size] +(defn positive [_ _] + (fn [size theme] [base-tag {:size size :background-color colors/success-50-opa-10 :icon :verified :border-color colors/success-50-opa-20 - :text-color (colors/theme-colors colors/success-50 - colors/success-60) + :text-color (if (= theme :light) colors/success-50 + colors/success-60) :label (i18n/label :positive)}])) -(defn negative [_] - (fn [size] +(defn negative [_ _] + (fn [size theme] [base-tag {:size size :icon :untrustworthy :background-color colors/danger-50-opa-10 :border-color colors/danger-50-opa-20 - :text-color (colors/theme-colors colors/danger-50 - colors/danger-60) + :text-color (if (= theme :light) + colors/danger-50 + colors/danger-60) :label (i18n/label :negative)}])) -(defn pending [_] - (fn [size] +(defn pending [_ _] + (fn [size theme] [base-tag {:size size :icon :pending - :background-color (colors/theme-colors colors/neutral-10 - colors/neutral-80) - :border-color (colors/theme-colors colors/neutral-20 - colors/neutral-70) + :background-color (if (= theme :light) + colors/neutral-10 + colors/neutral-80) + :border-color (if (= theme :light) + colors/neutral-20 + colors/neutral-70) :text-color colors/neutral-50 :label (i18n/label :pending)}])) (defn status-tag [_] - (fn [{:keys [status size]}] - [(case status - :positive positive - :negative negative - :pending pending - nil) size])) + (fn [{:keys [status size override-theme]}] + (let [theme (or override-theme (quo.theme/get-theme))] + [(case status + :positive positive + :negative negative + :pending pending + nil) size theme]))) diff --git a/src/quo2/foundations/colors.cljs b/src/quo2/foundations/colors.cljs index 5d24de88f0..89a0fc3a80 100644 --- a/src/quo2/foundations/colors.cljs +++ b/src/quo2/foundations/colors.cljs @@ -183,6 +183,67 @@ (def info-50-opa-30 (alpha info-50 0.3)) (def info-50-opa-40 (alpha info-50 0.4)) +;; Customization +(def purple-50 "#8661C1") +(def purple-60 "#5E478C") +(def indigo-50 "#496289") +(def indigo-60 "#3D5273") +(def turquoise-50 "#448EA2") +(def turquoise-60 "#397788") +(def blue-50 "#4CB4EF") +(def blue-60 "#4097C9") +(def green-50 "#5BCC95") +(def green-60 "#4CAB7D") +(def yellow-50 "#FFCB53") +(def yellow-60 "#D6AA46") +(def orange-50 "#FB8F61") +(def orange-60 "#D37851") +(def red-50 "#F46666") +(def red-60 "#CD565") +(def pink-50 "#FC7BAB") +(def pink-60 "#D46790") +(def brown-50 "#99604D") +(def brown-60 "#805141") +(def beige-50 "#CAAE93") +(def beige-60 "#AA927C") + +(def customization + {:dark {:purple purple-60 + :indigo indigo-60 + :turquoise turquoise-60 + :blue blue-60 + :green green-60 + :yellow yellow-60 + :orange orange-60 + :red red-60 + :pink pink-60 + :brown brown-60 + :beige beige-60} + :light {:purple purple-50 + :indigo indigo-50 + :turquoise turquoise-50 + :blue blue-50 + :green green-50 + :yellow yellow-50 + :orange orange-50 + :red red-50 + :pink pink-50 + :brown brown-50 + :beige beige-50}}) + +(defn custom-color [color theme] + (get-in customization [theme color])) + +;;;;Switcher +(def switcher-background "#040B14") + +;;switcher-screen with transparency +(def switcher-background-opa-60 (alpha switcher-background 0.6)) +(def switcher-background-opa-70 (alpha switcher-background 0.7)) +(def switcher-background-opa-80 (alpha switcher-background 0.8)) +(def switcher-background-opa-90 (alpha switcher-background 0.9)) +(def switcher-background-opa-95 (alpha switcher-background 0.95)) + ;;General ;; background diff --git a/src/quo2/foundations/typography.cljs b/src/quo2/foundations/typography.cljs index fa2a2e3db3..9172131068 100644 --- a/src/quo2/foundations/typography.cljs +++ b/src/quo2/foundations/typography.cljs @@ -1,24 +1,25 @@ (ns quo2.foundations.typography) +;; Formulat for letter spacing from figma %: 16/{figma-percentage)*100 (def heading-1 {:font-size 27 - :line-height 32.4 - :letter-spacing -0.5}) + :line-height 32 + :letter-spacing -0.762}) (def heading-2 {:font-size 19 :line-height 25.65 - :letter-spacing -0.4}) + :letter-spacing -0.1}) (def paragraph-1 {:font-size 15 :line-height 21.75 - :letter-spacing -0.1}) + :letter-spacing -0.177}) (def paragraph-2 {:font-size 13 :line-height 18.2 - :letter-spacing 0}) + :letter-spacing -0.533}) (def label {:font-size 11 :line-height 15.62 - :letter-spacing -0.055 + :letter-spacing 0.32 :text-transform :uppercase}) (def font-regular {:font-family "Inter-Regular"}) ; 400 diff --git a/src/quo2/screens/activity_logs.cljs b/src/quo2/screens/activity_logs.cljs new file mode 100644 index 0000000000..35f57d5490 --- /dev/null +++ b/src/quo2/screens/activity_logs.cljs @@ -0,0 +1,87 @@ +(ns quo2.screens.activity-logs + (:require [reagent.core :as reagent] + [quo.react-native :as rn] + [quo.previews.preview :as preview] + [quo2.foundations.colors :as colors] + [quo2.screens.status-tags :as status-tags] + [quo2.components.activity-logs :as activity-logs])) + +(def descriptor [{:label "Unread:" + :key :unread + :type :boolean} + {:label "Icon" + :key :icon + :type :select + :options [{:key :placeholder + :value :placeholder}]} + {:label "Title" + :key :title + :type :text} + {:label :message + :key :message + :type :text} + {:label "Timestamp" + :key :timestamp + :type :text} + {:label "Button 1 type" + :key :button-1-type + :type :select + :options [{:value "Danger" + :key :danger} + {:value "Primary" + :key :primary} + {:value "Success" + :key :success}]} + {:label "Button 1 label" + :key :button-1-label + :type :text} + {:label "Button 2 type" + :key :button-2-type + :type :select + :options [{:value "Danger" + :key :danger} + {:value "Primary" + :key :primary} + {:value "Success" + :key :success}]} + {:label "Button 2 label" + :key :button-2-label + :type :text} + status-tags/status-tags-options]) + +(defn preview [] + (let [state (reagent/atom {:title "Activity Title" + :timestamp "Yesterday ∙ 10:41" + :message "Hello Alisher! Do you remember me from the web 3.0 conference in Porto?" + :icon :placeholder})] + (fn [] + (let [{:keys [button-1-type + button-1-label + button-2-type + button-2-label]} @state + props (cond-> @state + (and (seq button-1-label) + button-1-type) + (assoc :button-1 {:label button-1-label + :type button-1-type}) + + (and (seq button-2-label) + button-2-type) + (assoc :button-2 {:label button-2-label + :type button-2-type}))] + [rn/view {:margin-bottom 50 + :padding 16} + [rn/view {:flex 1} + [preview/customizer state descriptor]] + [rn/view {:padding-vertical 60 + :background-color colors/neutral-95-opa-80 + :flex-direction :row + :justify-content :center} + [activity-logs/activity-logs props]]])))) + +(defn preview-activity-logs [] + [rn/view {:flex 1} + [rn/flat-list {:flex 1 + :keyboardShouldPersistTaps :always + :header [preview] + :key-fn str}]]) diff --git a/src/quo2/screens/context_tags.cljs b/src/quo2/screens/context_tags.cljs new file mode 100644 index 0000000000..b769e29e53 --- /dev/null +++ b/src/quo2/screens/context_tags.cljs @@ -0,0 +1,70 @@ +(ns quo2.screens.context-tags + (:require [reagent.core :as reagent] + [re-frame.core :as re-frame] + [status-im.multiaccounts.core :as multiaccounts] + [quo.react-native :as rn] + [quo.previews.preview :as preview] + [quo2.foundations.colors :as colors] + [quo2.components.context-tags :as quo2])) + +(def group-avatar-default-params + {:size :small + :color :purple}) + +(def example-pk "0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917") + +(def descriptor [{:label "Type" + :key :type + :type :select + :options [{:key :public-key + :value "Public key"} + {:key :avatar + :value "Avatar"} + {:key :group-avatar + :value "Group avatar"}]}]) + +(defn cool-preview [] + (let [state (reagent/atom {:label "Name" + :type :group-avatar})] + (fn [] + (let [contacts @(re-frame/subscribe [:contacts/contacts]) + descriptor + (cond-> descriptor + (= (:type @state) :group-avatar) + (conj {:label "Label" + :key :label + :type :text}) + (= (:type @state) :avatar) + (conj {:label "Contacts" + :key :contact + :type :select + :options + (map (fn [{:keys [public-key]}] + {:key public-key + :value (multiaccounts/displayed-name + (get contacts public-key))}) + (vals contacts))}))] + [rn/view {:margin-bottom 50 + :padding 16} + [rn/view {:flex 1} + [preview/customizer state descriptor]] + [rn/view {:padding-vertical 60 + :flex-direction :row + :justify-content :center} + (case (:type @state) + :group-avatar + [quo2/group-avatar-tag (:label @state) group-avatar-default-params] + :public-key + [quo2/public-key-tag {} example-pk] + + :avatar + [quo2/user-avatar-tag {} (:contact @state)])]])))) + +(defn preview-context-tags [] + [rn/view {:background-color (colors/theme-colors colors/white + colors/neutral-90) + :flex 1} + [rn/flat-list {:flex 1 + :keyboardShouldPersistTaps :always + :header [cool-preview] + :key-fn str}]]) diff --git a/src/quo2/screens/group_avatar.cljs b/src/quo2/screens/group_avatar.cljs new file mode 100644 index 0000000000..61ff4b96d4 --- /dev/null +++ b/src/quo2/screens/group_avatar.cljs @@ -0,0 +1,50 @@ +(ns quo2.screens.group-avatar + (:require [reagent.core :as reagent] + [quo.react-native :as rn] + [quo.previews.preview :as preview] + [quo2.foundations.colors :as colors] + [quo2.components.group-avatar :as quo2])) + +(def descriptor [{:label "Size" + :key :size + :type :select + :options [{:key :small + :value "Small"} + {:key :medium + :value "Medium"} + {:key :large + :value "Large"}]} + {:label "Color" + :key :color + :type :select + :options + (map + (fn [c] + {:key c + :value c}) + (-> colors/customization + :light + keys))}]) + +(defn cool-preview [] + (let [state (reagent/atom {:theme :light + :color :purple + :size :small})] + (fn [] + [rn/view {:margin-bottom 50 + :padding 16} + [rn/view {:flex 1} + [preview/customizer state descriptor]] + [rn/view {:padding-vertical 60 + :flex-direction :row + :justify-content :center} + [quo2/group-avatar @state]]]))) + +(defn preview-group-avatar [] + [rn/view {:background-color (colors/theme-colors colors/white + colors/neutral-90) + :flex 1} + [rn/flat-list {:flex 1 + :keyboardShouldPersistTaps :always + :header [cool-preview] + :key-fn str}]]) diff --git a/src/quo2/screens/main.cljs b/src/quo2/screens/main.cljs index 0147618b1d..f01ecc74bc 100644 --- a/src/quo2/screens/main.cljs +++ b/src/quo2/screens/main.cljs @@ -7,6 +7,9 @@ [quo2.screens.text :as text] [quo2.screens.tabs :as tabs] [quo2.screens.status-tags :as status-tags] + [quo2.screens.context-tags :as context-tags] + [quo2.screens.group-avatar :as group-avatar] + [quo2.screens.activity-logs :as activity-logs] [quo2.screens.counter :as counter] [quo2.screens.segmented :as segmented] [quo.components.safe-area :as safe-area] @@ -21,6 +24,15 @@ {:name :quo2-status-tags :insets {:top false} :component status-tags/preview-status-tags} + {:name :quo2-context-tags + :insets {:top false} + :component context-tags/preview-context-tags} + {:name :quo2-group-avatar + :insets {:top false} + :component group-avatar/preview-group-avatar} + {:name :quo2-activity-logs + :insets {:top false} + :component activity-logs/preview-activity-logs} {:name :quo2-tabs :insets {:top false} :component tabs/preview-tabs} diff --git a/src/quo2/screens/status_tags.cljs b/src/quo2/screens/status_tags.cljs index 29b4da7011..1c87b3d1df 100644 --- a/src/quo2/screens/status_tags.cljs +++ b/src/quo2/screens/status_tags.cljs @@ -5,15 +5,18 @@ [quo2.foundations.colors :as colors] [quo2.components.status-tags :as quo2])) -(def descriptor [{:label "Status" - :key :status - :type :select - :options [{:value "Positive" - :key :positive} - {:value "Negative" - :key :negative} - {:value "Pending" - :key :pending}]} +(def status-tags-options + {:label "Status" + :key :status + :type :select + :options [{:value "Positive" + :key :positive} + {:value "Negative" + :key :negative} + {:value "Pending" + :key :pending}]}) + +(def descriptor [status-tags-options {:label "Size" :key :size :type :select