Merge pull request #480 from status-im/bug/#435

Blue hashtags (#435)
This commit is contained in:
Roman Volosovskyi 2016-11-23 12:32:04 +02:00 committed by GitHub
commit eaf5ad650a
19 changed files with 150 additions and 110 deletions

View File

@ -1,7 +1,7 @@
{ {
"name": "StatusIm", "name": "StatusIm",
"interface": "reagent", "interface": "reagent",
"androidHost": "localhost", "androidHost": "10.0.3.2",
"modules": [ "modules": [
"react-native-contacts", "react-native-contacts",
"react-native-invertible-scroll-view", "react-native-invertible-scroll-view",

View File

@ -3,7 +3,6 @@
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[status-im.components.react :refer [view [status-im.components.react :refer [view
text text
text-input
image image
linear-gradient linear-gradient
touchable-highlight touchable-highlight
@ -18,8 +17,7 @@
icon-search icon-search
icon-back icon-back
icon-qr icon-qr
button-input button-input]]
white-form-text-input]]
[status-im.i18n :refer [label]] [status-im.i18n :refer [label]]
[status-im.accounts.login.styles :as st])) [status-im.accounts.login.styles :as st]))

View File

@ -3,7 +3,6 @@
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[status-im.components.react :refer [view [status-im.components.react :refer [view
text text
text-input
image image
linear-gradient linear-gradient
touchable-highlight]] touchable-highlight]]

View File

@ -27,7 +27,7 @@
:margin-top 2 :margin-top 2
:margin-bottom 4 :margin-bottom 4
:margin-right 2 :margin-right 2
:elevation 3} :elevation 2}
:tag {:flex-direction "column" :tag {:flex-direction "column"
:background-color "#7099e619" :background-color "#7099e619"
:border-radius 5 :border-radius 5

View File

@ -4,7 +4,6 @@
[status-im.components.react :refer [view [status-im.components.react :refer [view
icon icon
text text
text-input
touchable-highlight]] touchable-highlight]]
[status-im.chat.styles.input :as st])) [status-im.chat.styles.input :as st]))

View File

@ -8,7 +8,6 @@
icon icon
image image
text text
text-input
touchable-highlight touchable-highlight
web-view web-view
scroll-view]] scroll-view]]

View File

@ -43,20 +43,30 @@
:text-align :center}) :text-align :center})
(def status-container (def status-container
{:margin-left 16 {:margin-left 16
:margin-right 16 :margin-right 16
:margin-top (if p/ios? 5 5) :flex-direction "row"
:align-items :center}) :margin-top (if p/ios? 5 5)
:justify-content :center})
(def status-input (def status-view
{:align-self "stretch" {:height 56
:height 56 :width 200
:font-size 14 :font-size 14
:padding-left 4
:text-align :center :text-align :center
:text-align-vertical :top :text-align-vertical :top
:color text2-color}) :color text2-color})
(def status-input
(merge status-view
{:padding-left 4
:padding-top (if p/ios? 0 5)}))
(def status-text
(merge status-view
{:padding-left 0
:padding-top 5}))
(def menu-items-container (def menu-items-container
{:flex 1 {:flex 1
:margin-top 20 :margin-top 20

View File

@ -12,10 +12,12 @@
touchable-without-feedback touchable-without-feedback
touchable-opacity]] touchable-opacity]]
[status-im.components.text-field.view :refer [text-field]] [status-im.components.text-field.view :refer [text-field]]
[status-im.components.status-view.view :refer [status-view]]
[status-im.components.drawer.styles :as st] [status-im.components.drawer.styles :as st]
[status-im.profile.validations :as v] [status-im.profile.validations :as v]
[status-im.resources :as res] [status-im.resources :as res]
[status-im.utils.gfycat.core :refer [generate-gfy]] [status-im.utils.gfycat.core :refer [generate-gfy]]
[status-im.utils.utils :refer [clean-text]]
[status-im.i18n :refer [label]] [status-im.i18n :refer [label]]
[status-im.components.react :refer [dismiss-keyboard!]] [status-im.components.react :refer [dismiss-keyboard!]]
[clojure.string :as str] [clojure.string :as str]
@ -39,18 +41,13 @@
:font :default} :font :default}
name]]) name]])
(defn clean-text [s]
(-> s
(str/replace #"\n" " ")
(str/replace #"\r" "")
(str/trim)))
(defn drawer-menu [] (defn drawer-menu []
(let (let
[account (subscribe [:get-current-account]) [account (subscribe [:get-current-account])
profile (subscribe [:get :profile-edit]) profile (subscribe [:get :profile-edit])
keyboard-height (subscribe [:get :keyboard-height]) keyboard-height (subscribe [:get :keyboard-height])
placeholder (generate-gfy)] placeholder (generate-gfy)
status-edit? (r/atom false)]
(fn [] (fn []
(let [{:keys [name photo-path status]} @account (let [{:keys [name photo-path status]} @account
{new-name :name new-status :status} @profile] {new-name :name new-status :status} @profile]
@ -73,19 +70,28 @@
:on-end-editing #(when (and new-name (not (str/blank? new-name))) :on-end-editing #(when (and new-name (not (str/blank? new-name)))
(dispatch [:account-update {:name (clean-text new-name)}]))}]] (dispatch [:account-update {:name (clean-text new-name)}]))}]]
[view st/status-container [view st/status-container
[text-input {:style st/status-input (if @status-edit?
:editable true [text-input {:style st/status-input
:multiline true :editable true
:blur-on-submit true :multiline true
:maxLength 140 :auto-focus true
:accessibility-label :input :blur-on-submit true
:placeholder (label :t/profile-no-status) :focus status-edit?
:on-change-text #(dispatch [:set-in [:profile-edit :status] %]) :maxLength 140
:on-blur (fn [] :accessibility-label :input
(when (and new-status (not (str/blank? new-status))) :placeholder (label :t/profile-no-status)
(dispatch [:check-status-change (clean-text new-status)]) :on-change-text (fn [t]
(dispatch [:account-update {:status (clean-text new-status)}]))) (dispatch [:set-in [:profile-edit :status] (clean-text t)]))
:default-value status}]] :on-submit-editing (fn []
(reset! status-edit? false)
(when (and new-status (not (str/blank? new-status)))
(dispatch [:check-status-change (clean-text new-status)])
(dispatch [:account-update {:status (clean-text new-status)}])))
:default-value status}]
[status-view {:style st/status-text
:on-press #(reset! status-edit? true)
:number-of-lines 3
:status status}])]
[view st/menu-items-container [view st/menu-items-container
[menu-item {:name (label :t/profile) [menu-item {:name (label :t/profile)
:handler #(dispatch [:navigate-to :my-profile])}] :handler #(dispatch [:navigate-to :my-profile])}]
@ -96,8 +102,7 @@
[menu-item {:name (label :t/discovery) [menu-item {:name (label :t/discovery)
:handler #(dispatch [:navigate-to :discovery])}] :handler #(dispatch [:navigate-to :discovery])}]
[menu-item {:name (label :t/contacts) [menu-item {:name (label :t/contacts)
:handler #(dispatch [:navigate-to :contact-list])}] :handler #(dispatch [:navigate-to :contact-list])}]]
]
(when (zero? @keyboard-height) (when (zero? @keyboard-height)
[text {:style st/feedback [text {:style st/feedback
:font :default} (label :t/feedback)]) :font :default} (label :t/feedback)])

View File

@ -5,7 +5,6 @@
[reagent.core :as r] [reagent.core :as r]
[status-im.components.react :refer [view [status-im.components.react :refer [view
animated-view animated-view
text-input
text text
image image
touchable-highlight touchable-highlight

View File

@ -67,13 +67,17 @@
(assoc :style (merge style font)))] (assoc :style (merge style font)))]
ts)))))) ts))))))
(defn text-input [props text] (defn text-input [{:keys [font style] :as opts
[text-input-class (merge :or {font :default}} text]
{:underline-color-android :transparent (let [font (get-in platform-specific [:fonts (keyword font)])]
:placeholder-text-color st/text2-color [text-input-class (merge
:placeholder "Type" {:underline-color-android :transparent
:value text} :placeholder-text-color st/text2-color
props)]) :placeholder "Type"
:value text}
(-> opts
(dissoc :font)
(assoc :style (merge style font))))]))
(defn icon (defn icon
([n] (icon n {})) ([n] (icon n {}))

View File

@ -0,0 +1,28 @@
(ns status-im.components.status-view.view
(:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch]]
[clojure.string :as str]
[status-im.components.react :refer [view text]]
[status-im.utils.platform :refer [platform-specific]]))
(defn tag-view [tag]
[text {:style {:color "#7099e6"}
:font :medium}
(str tag " ")])
(defn status-view [{:keys [style
message-id
status
on-press
number-of-lines]
:or {message-id "msg"}}]
[text {:style style
:on-press on-press
:number-of-lines number-of-lines
:font :default}
(for [[i status] (map-indexed vector (str/split status #" "))]
(if (.startsWith status "#")
^{:key (str "item-" message-id "-" i)}
[tag-view status]
^{:key (str "item-" message-id "-" i)}
(str status " ")))])

View File

@ -1,7 +1,6 @@
(ns status-im.components.toolbar.view (ns status-im.components.toolbar.view
(:require [re-frame.core :refer [subscribe dispatch]] (:require [re-frame.core :refer [subscribe dispatch]]
[status-im.components.react :refer [view [status-im.components.react :refer [view
text-input
icon icon
text text
image image

View File

@ -4,7 +4,6 @@
[clojure.string :as str] [clojure.string :as str]
[status-im.components.react :refer [view [status-im.components.react :refer [view
text text
text-input
image image
linear-gradient linear-gradient
touchable-highlight]] touchable-highlight]]

View File

@ -2,33 +2,19 @@
(:require-macros [status-im.utils.views :refer [defview]]) (:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch]] (:require [re-frame.core :refer [subscribe dispatch]]
[clojure.string :as str] [clojure.string :as str]
[status-im.components.react :refer [view text image touchable-highlight]] [status-im.components.react :refer [view text touchable-highlight]]
[status-im.discovery.styles :as st] [status-im.discovery.styles :as st]
[status-im.components.status-view.view :refer [status-view]]
[status-im.utils.gfycat.core :refer [generate-gfy]] [status-im.utils.gfycat.core :refer [generate-gfy]]
[status-im.utils.identicon :refer [identicon]] [status-im.utils.identicon :refer [identicon]]
[status-im.i18n :refer [label]]
[status-im.components.chat-icon.screen :as ci] [status-im.components.chat-icon.screen :as ci]
[status-im.utils.platform :refer [platform-specific]] [status-im.utils.platform :refer [platform-specific]]))
[taoensso.timbre :as log]))
(defn tag-view [tag]
[text {:style {:color "#7099e6"}
:font :medium}
(str tag " ")])
(defn status-view [item-style {:keys [message-id status]}]
[text {:style (:status-text item-style)
:font :default}
(for [[i status] (map-indexed vector (str/split status #" "))]
(if (.startsWith status "#")
^{:key (str "item-" message-id "-" i)}
[tag-view status]
^{:key (str "item-" message-id "-" i)}
(str status " ")))])
(defview discovery-list-item [{{:keys [name (defview discovery-list-item [{{:keys [name
photo-path photo-path
whisper-id] whisper-id
message-id
status]
:as message} :message :as message} :message
show-separator? :show-separator? show-separator? :show-separator?
{account-photo-path :photo-path {account-photo-path :photo-path
@ -49,7 +35,9 @@
(not (str/blank? contact-name)) contact-name (not (str/blank? contact-name)) contact-name
(not (str/blank? name)) name (not (str/blank? name)) name
:else (generate-gfy))] :else (generate-gfy))]
[status-view item-style message]] [status-view {:id message-id
:style (:status-text item-style)
:status status}]]
[view (merge st/popular-list-item-avatar-container [view (merge st/popular-list-item-avatar-container
(:icon item-style)) (:icon item-style))
[touchable-highlight {:on-press #(dispatch [:start-chat whisper-id])} [touchable-highlight {:on-press #(dispatch [:start-chat whisper-id])}

View File

@ -3,7 +3,6 @@
(:require [re-frame.core :refer [subscribe dispatch]] (:require [re-frame.core :refer [subscribe dispatch]]
[status-im.resources :as res] [status-im.resources :as res]
[status-im.components.react :refer [view [status-im.components.react :refer [view
text-input
text text
image image
icon icon

View File

@ -3,7 +3,6 @@
(:require [re-frame.core :refer [subscribe dispatch]] (:require [re-frame.core :refer [subscribe dispatch]]
[status-im.resources :as res] [status-im.resources :as res]
[status-im.components.react :refer [view [status-im.components.react :refer [view
text-input
text text
image image
touchable-highlight touchable-highlight

View File

@ -21,6 +21,7 @@
[status-im.components.status-bar :refer [status-bar]] [status-im.components.status-bar :refer [status-bar]]
[status-im.components.text-field.view :refer [text-field]] [status-im.components.text-field.view :refer [text-field]]
[status-im.components.selectable-field.view :refer [selectable-field]] [status-im.components.selectable-field.view :refer [selectable-field]]
[status-im.components.status-view.view :refer [status-view]]
[status-im.utils.phone-number :refer [format-phone-number]] [status-im.utils.phone-number :refer [format-phone-number]]
[status-im.utils.image-processing :refer [img->base64]] [status-im.utils.image-processing :refer [img->base64]]
[status-im.utils.platform :refer [platform-specific]] [status-im.utils.platform :refer [platform-specific]]
@ -28,9 +29,9 @@
[status-im.profile.validations :as v] [status-im.profile.validations :as v]
[status-im.profile.styles :as st] [status-im.profile.styles :as st]
[status-im.utils.random :refer [id]] [status-im.utils.random :refer [id]]
[status-im.utils.utils :refer [clean-text]]
[status-im.components.image-button.view :refer [show-qr-button]] [status-im.components.image-button.view :refer [show-qr-button]]
[status-im.i18n :refer [label]] [status-im.i18n :refer [label]]))
[taoensso.timbre :as log]))
(defn toolbar [{:keys [account edit?]}] (defn toolbar [{:keys [account edit?]}]
(let [profile-edit-data-valid? (s/valid? ::v/profile account)] (let [profile-edit-data-valid? (s/valid? ::v/profile account)]
@ -56,22 +57,10 @@
:style (st/ok-btn-icon profile-edit-data-valid?)}] :style (st/ok-btn-icon profile-edit-data-valid?)}]
[icon :dots st/edit-btn-icon])]]])) [icon :dots st/edit-btn-icon])]]]))
(defn- get-text
[word]
(let [props (merge {:key (id)}
(if (str/starts-with? word "#")
{:style st/hashtag}
{}))]
[text props (str word " ")]))
(defn- highlight-tags
[status]
(->>
(str/split status #" ")
(map get-text)))
(defn status-image-view [_] (defn status-image-view [_]
(let [component (r/current-component) (let [component (r/current-component)
just-opened? (r/atom true)
input-ref (r/atom nil)
set-status-height #(let [height (-> (.-nativeEvent %) set-status-height #(let [height (-> (.-nativeEvent %)
(.-contentSize) (.-contentSize)
(.-height))] (.-height))]
@ -102,15 +91,23 @@
:wrapper-style st/username-wrapper :wrapper-style st/username-wrapper
:value name :value name
:on-change-text #(dispatch [:set-in [:profile-edit :name] %])}] :on-change-text #(dispatch [:set-in [:profile-edit :name] %])}]
[text-input {:style (st/status-input (:height (r/state component))) (if (or edit? @just-opened?)
:on-change #(set-status-height %) [text-input {:ref #(reset! input-ref %)
:on-content-size-change #(set-status-height %) :style (st/status-input (:height (r/state component)))
:maxLength 140 :multiline true
:multiline true :editable true
:editable edit? :blur-on-submit true
:placeholder (label :t/profile-no-status) :on-content-size-change #(do (set-status-height %)
:on-change-text #(dispatch [:set-in [:profile-edit :status] %]) (reset! just-opened? false))
:default-value status}]])}))) :max-length 140
:placeholder (label :t/profile-no-status)
:on-change-text (fn [t]
(dispatch [:set-in [:profile-edit :status] (clean-text t)]))
:on-submit-editing (fn []
(.blur @input-ref))
:default-value status}]
[status-view {:style (st/status-text (:height (r/state component)))
:status status}])])})))
(defview profile [] (defview profile []
[{whisper-identity :whisper-identity [{whisper-identity :whisper-identity
@ -189,9 +186,10 @@
changed-account [:get :profile-edit]] changed-account [:get :profile-edit]]
(let [{:keys [phone (let [{:keys [phone
address address
public-key] :as account} (if edit? public-key]
changed-account :as account} (if edit?
current-account)] changed-account
current-account)]
[scroll-view {:style st/profile [scroll-view {:style st/profile
:bounces false} :bounces false}
[status-bar] [status-bar]

View File

@ -72,16 +72,26 @@
:margin-left 55 :margin-left 55
:margin-right 55}) :margin-right 55})
(defn status-view [height]
{:align-self "stretch"
:font-size 14
:height height
:min-height 30
:text-align "center"
:color text2-color})
(defn status-input [height] (defn status-input [height]
{:align-self "stretch" (merge (status-view height)
:margin-left (if p/ios? 22 16) {:margin-left (if p/ios? 21 16)
:margin-right 16 :margin-right 16
:margin-top (if p/ios? 6 1) :margin-top (if p/ios? 6 1)}))
:font-size 14
:height height (defn status-text [height]
:min-height 30 (merge (status-view (- height (if p/ios? 5 10)))
:text-align "center" {:margin-left 18
:color text2-color}) :margin-right 18
:margin-top 11
:margin-bottom 0}))
(def btns-container (def btns-container
{:margin-top 0 {:margin-top 0

View File

@ -1,6 +1,7 @@
(ns status-im.utils.utils (ns status-im.utils.utils
(:require [status-im.constants :as const] (:require [status-im.constants :as const]
[reagent.core :as r])) [reagent.core :as r]
[clojure.string :as str]))
(defn require [module] (defn require [module]
(if (exists? js/window) (if (exists? js/window)
@ -54,6 +55,12 @@
(str (subs s 0 (- max 3)) "...") (str (subs s 0 (- max 3)) "...")
s)) s))
(defn clean-text [s]
(-> s
(str/replace #"\n" " ")
(str/replace #"\r" "")
(str/trim)))
(defn first-index (defn first-index
[cond coll] [cond coll]
(loop [index 0 (loop [index 0