sanitize quo2 (#14859)

This commit is contained in:
flexsurfer 2023-01-23 14:41:55 +01:00 committed by GitHub
parent 098821d20b
commit d79d2e9d36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 124 additions and 110 deletions

View File

@ -1,6 +1,5 @@
(ns quo2.components.code.snippet
(:require ["react-native" :as react-native]
[cljs-bean.core :as bean]
(:require [cljs-bean.core :as bean]
[clojure.string :as string]
[oops.core :as oops]
[quo2.components.buttons.button :as button]
@ -168,8 +167,8 @@
:on-copy-press #(when on-copy-press
(on-copy-press children))})
;; Default props to adapt Highlighter for react-native.
:CodeTag react-native/View
:PreTag react-native/View
;;:CodeTag react-native/View
;;:PreTag react-native/View
:show-line-numbers false
:style #js {}
:custom-style #js {:backgroundColor nil}}

View File

@ -1,6 +1,5 @@
(ns quo2.components.community.token-gating
(:require [quo.react-native :as rn]
[quo2.components.avatars.channel-avatar :as channel-avatar]
(:require [quo2.components.avatars.channel-avatar :as channel-avatar]
[quo2.components.buttons.button :as button]
[quo2.components.icon :as icon]
[quo2.components.info.information-box :as information-box]
@ -8,7 +7,8 @@
[quo2.components.tags.token-tag :as token-tag]
[quo2.foundations.colors :as colors]
[utils.i18n :as i18n]
[react-native.fast-image :as fast-image]))
[react-native.fast-image :as fast-image]
[react-native.core :as rn]))
(def ^:private token-tag-horizontal-spacing 7)
(def token-tag-vertical-spacing 5)

View File

@ -3,8 +3,7 @@
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.components.messages.author.style :as style]
[react-native.core :as rn]
[status-im.utils.utils :as utils]))
[react-native.core :as rn]))
(def middle-dot "·")
@ -35,7 +34,7 @@
profile-name])])))
(defn author
[{:keys [profile-name nickname chat-key ens-name time-str contact? verified? untrustworthy?]}]
[{:keys [profile-name nickname short-chat-key ens-name time-str contact? verified? untrustworthy?]}]
[:f>
(fn []
(let [ens? (-> ens-name string/blank? not)
@ -85,7 +84,7 @@
{:monospace true
:size :paragraph-2
:style style/chat-key-text}
(utils/get-shortened-address chat-key)])
short-chat-key])
(when-not ens?
[text/text
{:monospace true

View File

@ -1,11 +1,12 @@
(ns quo2.components.tags.tags
(:require [reagent.core :as reagent]
[quo.react-native :as rn]
[oops.core :refer [oget]]
[status-im.ui.components.react :as react]
[status-im.utils.core :as utils]
[quo2.components.tags.tag :as tag]
[utils.number :as number-utils]))
[utils.number :as number-utils]
[react-native.core :as rn]
[react-native.masked-view :as masked-view]
[react-native.linear-gradient :as linear-gradient]
[utils.collection :as utils.collection]))
(def default-tab-size 32)
@ -76,9 +77,9 @@
size default-tab-size}
:as props}]
(let [maybe-mask-wrapper (if fade-end?
[react/masked-view
[masked-view/masked-view
{:mask-element (reagent/as-element
[react/linear-gradient
[linear-gradient/linear-gradient
{:colors [:black :transparent]
:locations [(get @fading :fade-end-percentage)
1]
@ -92,64 +93,65 @@
(conj
maybe-mask-wrapper
[rn/flat-list
(merge (dissoc props
:default-active
:fade-end-percentage
:fade-end?
:on-change
:scroll-on-press?
:size)
(when scroll-on-press?
{:initial-scroll-index (utils/first-index #(= @active-tab-id (:id %)) data)})
{:ref #(reset! flat-list-ref %)
:extra-data (str @active-tab-id)
:horizontal true
:scroll-event-throttle scroll-event-throttle
:shows-horizontal-scroll-indicator false
:data data
:key-fn (comp str :id)
:on-scroll (fn [^js e]
(when fade-end?
(let [offset-x (oget e "nativeEvent.contentOffset.x")
content-width (oget e "nativeEvent.contentSize.width")
layout-width (oget e "nativeEvent.layoutMeasurement.width")
new-percentage (calculate-fade-end-percentage
{:offset-x offset-x
:content-width content-width
:layout-width layout-width
:max-fade-percentage fade-end-percentage})]
;; Avoid unnecessary re-rendering.
(when (not= new-percentage (get @fading :fade-end-percentage))
(swap! fading assoc :fade-end-percentage new-percentage))))
(when on-scroll
(on-scroll e)))
:render-fn (fn [{:keys [id label resource]} index]
[rn/view
{:style {:margin-right (if (= size default-tab-size) 12 8)
:padding-right (when (= index (dec (count data)))
(get-in props [:style :padding-left]))}}
[tag/tag
{:id id
:size size
:active (= id @active-tab-id)
:resource resource
:blurred? blurred?
:icon-color icon-color
:disabled? disabled?
:label label
:type type
:labelled? labelled?
:on-press (fn [id]
(reset! active-tab-id id)
(when scroll-on-press?
(.scrollToIndex ^js @flat-list-ref
#js
{:animated true
:index index
:viewPosition 0.5}))
(when on-change
(on-change id)))}
label]])})])
(merge
(dissoc props
:default-active
:fade-end-percentage
:fade-end?
:on-change
:scroll-on-press?
:size)
(when scroll-on-press?
{:initial-scroll-index (utils.collection/first-index #(= @active-tab-id (:id %)) data)})
{:ref #(reset! flat-list-ref %)
:extra-data (str @active-tab-id)
:horizontal true
:scroll-event-throttle scroll-event-throttle
:shows-horizontal-scroll-indicator false
:data data
:key-fn (comp str :id)
:on-scroll (fn [^js e]
(when fade-end?
(let [offset-x (oget e "nativeEvent.contentOffset.x")
content-width (oget e "nativeEvent.contentSize.width")
layout-width (oget e "nativeEvent.layoutMeasurement.width")
new-percentage (calculate-fade-end-percentage
{:offset-x offset-x
:content-width content-width
:layout-width layout-width
:max-fade-percentage fade-end-percentage})]
;; Avoid unnecessary re-rendering.
(when (not= new-percentage (get @fading :fade-end-percentage))
(swap! fading assoc :fade-end-percentage new-percentage))))
(when on-scroll
(on-scroll e)))
:render-fn (fn [{:keys [id label resource]} index]
[rn/view
{:style {:margin-right (if (= size default-tab-size) 12 8)
:padding-right (when (= index (dec (count data)))
(get-in props [:style :padding-left]))}}
[tag/tag
{:id id
:size size
:active (= id @active-tab-id)
:resource resource
:blurred? blurred?
:icon-color icon-color
:disabled? disabled?
:label label
:type type
:labelled? labelled?
:on-press (fn [id]
(reset! active-tab-id id)
(when scroll-on-press?
(.scrollToIndex ^js @flat-list-ref
#js
{:animated true
:index index
:viewPosition 0.5}))
(when on-change
(on-change id)))}
label]])})])
[rn/view {:style {:flex-direction :row}}
(for [{:keys [label id resource]} data]
^{:key id}

View File

@ -0,0 +1,10 @@
(ns react-native.clipboard
(:require ["@react-native-community/clipboard" :default Clipboard]))
(defn set-string
[text]
(.setString ^js Clipboard text))
(defn get-string
[callback]
(.then (.getString ^js Clipboard) #(callback %)))

View File

@ -117,3 +117,14 @@
{:ease-in-ease-out (-> ^js layout-animation .-Presets .-easeInEaseOut)
:linear (-> ^js layout-animation .-Presets .-linear)
:spring (-> ^js layout-animation .-Presets .-spring)})
(def find-node-handle (.-findNodeHandle ^js react-native))
(defn selectable-text-input-manager
[]
(when (exists? (.-NativeModules ^js react-native))
(.-RNSelectableTextInputManager ^js (.-NativeModules ^js react-native))))
(defonce selectable-text-input
(reagent/adapt-react-class
(.requireNativeComponent ^js react-native "RNSelectableTextInput")))

View File

@ -1,22 +1,20 @@
(ns status-im.ui2.screens.chat.composer.input
(:require ["react-native" :as react-native]
[clojure.string :as string]
(:require [clojure.string :as string]
[oops.core :as oops]
[quo.design-system.colors :as quo.colors]
[quo.react]
[quo.react-native :as rn]
[quo2.foundations.colors :as colors]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im2.constants :as chat.constants]
[status-im.chat.models.mentions :as mentions]
[utils.i18n :as i18n]
[status-im.ui.components.react :as react]
[utils.re-frame :as rf]
[status-im.utils.platform :as platform]
[status-im.utils.utils :as utils.utils]
[utils.transforms :as transforms]
[quo2.foundations.typography :as typography]))
[quo2.foundations.typography :as typography]
[react-native.background-timer :as background-timer]
[react-native.platform :as platform]
[react-native.core :as rn]
[react-native.clipboard :as clipboard]
[quo.react :as quo.react]))
(defonce input-texts (atom {}))
(defonce input-text-content-heights (atom {}))
@ -94,7 +92,7 @@
(when platform/ios?
(reset!
timeout-id
(utils.utils/set-timeout
(background-timer/set-timeout
#(rf/dispatch [::mentions/on-selection-change
{:start start
:end end}
@ -128,7 +126,7 @@
;; happens during typing because it is not needed for mention
;; suggestions calculation
(when (and platform/ios? @timeout-id)
(utils.utils/clear-timeout @timeout-id))
(background-timer/clear-timeout @timeout-id))
(when platform/android?
(reset! last-text-change (js/Date.now)))
@ -169,7 +167,7 @@
:min-height 34
:margin 0
:flex-shrink 1
:color (:text-01 @quo.colors/theme)
:color (colors/theme-colors colors/neutral-100 colors/white)
:margin-horizontal 20}
(if platform/android?
{:padding-vertical 8
@ -195,7 +193,7 @@
:blur-on-submit false
:auto-focus false
:max-length chat.constants/max-text-size
:placeholder-text-color (:text-02 @quo.colors/theme)
:placeholder-text-color (colors/theme-colors colors/neutral-40 colors/white-opa-30)
:placeholder (if cooldown-enabled?
(i18n/label :cooldown/text-input-disabled)
(i18n/label :t/type-a-message))
@ -230,14 +228,6 @@
[rn/text-input props
children])))
(defn selectable-text-input-manager
[]
(when (exists? (.-NativeModules react-native))
(.-RNSelectableTextInputManager ^js (.-NativeModules react-native))))
(defonce rn-selectable-text-input
(reagent/adapt-react-class (.requireNativeComponent react-native "RNSelectableTextInput")))
(declare first-level-menu-items second-level-menu-items)
(defn update-input-text
@ -269,24 +259,24 @@
;https://lightrun.com/answers/facebook-react-native-textinput-controlled-selection-broken-on-both-ios-and-android
;use native invoke instead! do not use setNativeProps! e.g. (.setNativeProps ^js text-input (clj->js
;{:selection {:start selection-start :end selection-end}}))
(let [manager (selectable-text-input-manager)]
(let [manager (rn/selectable-text-input-manager)]
(oops/ocall manager :setSelection text-input-handle selection-start selection-end)))
(def first-level-menus
{:cut (fn [{:keys [content] :as params}]
(let [new-text (calculate-input-text params "")]
(react/copy-to-clipboard content)
(clipboard/set-string content)
(update-input-text params new-text)))
:copy-to-clipboard (fn [{:keys [content]}]
(react/copy-to-clipboard content))
(clipboard/set-string content))
:paste (fn [params]
(let [callback (fn [paste-content]
(let [content (string/trim paste-content)
new-text (calculate-input-text params content)]
(update-input-text params new-text)))]
(react/get-from-clipboard callback)))
(clipboard/get-string callback)))
:biu (fn [{:keys [first-level text-input-handle menu-items selection-start
selection-end]}]
@ -340,7 +330,7 @@
menu-items (reagent/atom first-level-menu-items)
first-level (reagent/atom true)
selection-event (atom nil)
manager (selectable-text-input-manager)]
manager (rn/selectable-text-input-manager)]
(reagent/create-class
{:component-did-mount
(fn [this]
@ -395,6 +385,6 @@
:style (dissoc style :margin-horizontal)
:on-selection-change on-selection-change
:on-selection on-selection})]
[rn-selectable-text-input {:menuItems @menu-items :style style}
[rn/selectable-text-input {:menuItems @menu-items :style style}
[rn/text-input props
children]]))})))

View File

@ -16,7 +16,8 @@
[utils.re-frame :as rf]
[status-im.ui2.screens.chat.messages.message :as old-message]
[status-im2.common.not-implemented :as not-implemented]
[utils.datetime :as datetime]))
[utils.datetime :as datetime]
[status-im.utils.utils :as utils]))
(defn avatar
[{:keys [response-to last-in-group? pinned quoted-message from]}]
@ -41,11 +42,11 @@
(let [display-name (first (rf/sub [:contacts/contact-two-names-by-identity from]))
{:keys [ens-verified added?]} (rf/sub [:contacts/contact-by-address from])]
[quo/author
{:profile-name display-name
:chat-key from
:time-str (datetime/timestamp->time timestamp)
:contact? added?
:verified? ens-verified}])))
{:profile-name display-name
:short-chat-key (utils/get-shortened-address from)
:time-str (datetime/timestamp->time timestamp)
:contact? added?
:verified? ens-verified}])))
(defn system-message-content
[{:keys [content-type quoted-message] :as message-data}]

View File

@ -4,7 +4,8 @@
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
[status-im2.contexts.quo-preview.preview :as preview]
[status-im.utils.utils :as utils]))
(def descriptor
[{:label "Profile name"
@ -39,7 +40,8 @@
[]
(let [state (reagent/atom {:profile-name "Alisher Yakupov"
:nickname ""
:chat-key "zQ3ssgRy5TtB47MMiMKMKaGyaawkCgMqqbrnAUYrZJ1sgt5N"
:short-chat-key (utils/get-shortened-address
"zQ3ssgRy5TtB47MMiMKMKaGyaawkCgMqqbrnAUYrZJ1sgt5N")
:time-str "09:30"
:ens-name ""
:contact? false