Base chat dedesign
Signed-off-by: Brian Sztamfater <brian@status.im>
|
@ -2,7 +2,7 @@ PODS:
|
||||||
- boost-for-react-native (1.63.0)
|
- boost-for-react-native (1.63.0)
|
||||||
- BVLinearGradient (2.5.6):
|
- BVLinearGradient (2.5.6):
|
||||||
- React
|
- React
|
||||||
- CryptoSwift (1.4.3)
|
- CryptoSwift (1.5.1)
|
||||||
- DoubleConversion (1.1.6)
|
- DoubleConversion (1.1.6)
|
||||||
- FBLazyVector (0.63.4)
|
- FBLazyVector (0.63.4)
|
||||||
- FBReactNativeSpec (0.63.4):
|
- FBReactNativeSpec (0.63.4):
|
||||||
|
@ -349,7 +349,7 @@ PODS:
|
||||||
- React
|
- React
|
||||||
- RNReactNativeHapticFeedback (1.9.0):
|
- RNReactNativeHapticFeedback (1.9.0):
|
||||||
- React
|
- React
|
||||||
- RNReanimated (2.1.0):
|
- RNReanimated (2.3.3):
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- FBLazyVector
|
- FBLazyVector
|
||||||
- FBReactNativeSpec
|
- FBReactNativeSpec
|
||||||
|
@ -375,7 +375,6 @@ PODS:
|
||||||
- React-RCTNetwork
|
- React-RCTNetwork
|
||||||
- React-RCTSettings
|
- React-RCTSettings
|
||||||
- React-RCTText
|
- React-RCTText
|
||||||
- React-RCTVibration
|
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- Yoga
|
- Yoga
|
||||||
- RNShare (7.0.1):
|
- RNShare (7.0.1):
|
||||||
|
@ -468,7 +467,7 @@ DEPENDENCIES:
|
||||||
- RNSVG (from `../node_modules/react-native-svg`)
|
- RNSVG (from `../node_modules/react-native-svg`)
|
||||||
- secp256k1 (from `https://github.com/status-im/secp256k1.swift.git`)
|
- secp256k1 (from `https://github.com/status-im/secp256k1.swift.git`)
|
||||||
- SQLCipher (~> 3.0)
|
- SQLCipher (~> 3.0)
|
||||||
- SSZipArchive
|
- SSZipArchive (= 2.4.3)
|
||||||
- TouchID (from `../node_modules/react-native-touch-id`)
|
- TouchID (from `../node_modules/react-native-touch-id`)
|
||||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||||
|
|
||||||
|
@ -631,14 +630,14 @@ CHECKOUT OPTIONS:
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||||
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
|
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
|
||||||
CryptoSwift: a0799ee936271bd2253a006f1e4523df21845000
|
CryptoSwift: c4f2debceb38bf44c80659afe009f71e23e4a082
|
||||||
DoubleConversion: cde416483dac037923206447da6e1454df403714
|
DoubleConversion: cde416483dac037923206447da6e1454df403714
|
||||||
FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
|
FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
|
||||||
FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e
|
FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e
|
||||||
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
|
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
|
||||||
glog: 2d7c14bbcd0c3139c6258f813895cb61d7860fcc
|
glog: 502275bc0747df92346edbab1f40dacde2ec86d4
|
||||||
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
|
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
|
||||||
Keycard: 07f1b4d4fadcf1218084cb3e1bb3a8bac3870c5a
|
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
|
||||||
libwebp: 98a37e597e40bfdb4c911fc98f2c53d0b12d05fc
|
libwebp: 98a37e597e40bfdb4c911fc98f2c53d0b12d05fc
|
||||||
Permission-Camera: afad27bf90337684d4a86f3825112d648c8c4d3b
|
Permission-Camera: afad27bf90337684d4a86f3825112d648c8c4d3b
|
||||||
Permission-Microphone: 0ffabc3fe1c75cfb260525ee3f529383c9f4368c
|
Permission-Microphone: 0ffabc3fe1c75cfb260525ee3f529383c9f4368c
|
||||||
|
@ -666,7 +665,7 @@ SPEC CHECKSUMS:
|
||||||
react-native-shake: de052eaa3eadc4a326b8ddd7ac80c06e8d84528c
|
react-native-shake: de052eaa3eadc4a326b8ddd7ac80c06e8d84528c
|
||||||
react-native-slider: 12bd76d3d568c9c5500825db54123d44b48e4ad4
|
react-native-slider: 12bd76d3d568c9c5500825db54123d44b48e4ad4
|
||||||
react-native-splash-screen: 4312f786b13a81b5169ef346d76d33bc0c6dc457
|
react-native-splash-screen: 4312f786b13a81b5169ef346d76d33bc0c6dc457
|
||||||
react-native-status: 45dbf1302ce3c258b459dfab137cd1c2c68c295d
|
react-native-status: 21f75d492fd311dc111303da38a7a2b23a8a8466
|
||||||
react-native-status-keycard: 961d01ca190889ddf220206822fd752f8f4f3f7a
|
react-native-status-keycard: 961d01ca190889ddf220206822fd752f8f4f3f7a
|
||||||
react-native-webview: 28a8636d97ee641f2ee8f20492d7a6c269c1d703
|
react-native-webview: 28a8636d97ee641f2ee8f20492d7a6c269c1d703
|
||||||
React-RCTActionSheet: 89a0ca9f4a06c1f93c26067af074ccdce0f40336
|
React-RCTActionSheet: 89a0ca9f4a06c1f93c26067af074ccdce0f40336
|
||||||
|
@ -693,7 +692,7 @@ SPEC CHECKSUMS:
|
||||||
RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e
|
RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e
|
||||||
RNPermissions: ad71dd4f767ec254f2cd57592fbee02afee75467
|
RNPermissions: ad71dd4f767ec254f2cd57592fbee02afee75467
|
||||||
RNReactNativeHapticFeedback: 2566b468cc8d0e7bb2f84b23adc0f4614594d071
|
RNReactNativeHapticFeedback: 2566b468cc8d0e7bb2f84b23adc0f4614594d071
|
||||||
RNReanimated: 70f662b5232dd5d19ccff581e919a54ea73df51c
|
RNReanimated: 69eda0e8790a2ee00de2fff03e89361e9bac749a
|
||||||
RNShare: 2dc2fcac3f7321cfd6b60a23ed4bf4d549f86f5f
|
RNShare: 2dc2fcac3f7321cfd6b60a23ed4bf4d549f86f5f
|
||||||
RNSVG: 8ba35cbeb385a52fd960fd28db9d7d18b4c2974f
|
RNSVG: 8ba35cbeb385a52fd960fd28db9d7d18b4c2974f
|
||||||
SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d
|
SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d
|
||||||
|
@ -705,6 +704,6 @@ SPEC CHECKSUMS:
|
||||||
TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4
|
TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4
|
||||||
Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6
|
Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6
|
||||||
|
|
||||||
PODFILE CHECKSUM: 1a5b8878f89edd08eb4d37898a3a8721a7bb3388
|
PODFILE CHECKSUM: a1de9468266e7f0b5273acea713782ab759690f1
|
||||||
|
|
||||||
COCOAPODS: 1.11.0
|
COCOAPODS: 1.11.3
|
||||||
|
|
After Width: | Height: | Size: 1014 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 498 B |
After Width: | Height: | Size: 659 B |
After Width: | Height: | Size: 569 B |
After Width: | Height: | Size: 819 B |
After Width: | Height: | Size: 463 B |
After Width: | Height: | Size: 605 B |
After Width: | Height: | Size: 773 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 851 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 909 B |
After Width: | Height: | Size: 1.3 KiB |
|
@ -193,5 +193,19 @@
|
||||||
(def switcher-background-opa-90 (alpha switcher-background 0.9))
|
(def switcher-background-opa-90 (alpha switcher-background 0.9))
|
||||||
(def switcher-background-opa-95 (alpha switcher-background 0.95))
|
(def switcher-background-opa-95 (alpha switcher-background 0.95))
|
||||||
|
|
||||||
|
;;General
|
||||||
|
|
||||||
|
;; background
|
||||||
|
|
||||||
|
(def ui-background-02-light "#F5F9FA")
|
||||||
|
|
||||||
|
;; divider
|
||||||
|
(def divider-light "#EDF2f4")
|
||||||
|
(def divider-dark "#0E1620")
|
||||||
|
|
||||||
|
;; Visibility status
|
||||||
|
|
||||||
|
(def color-online "#26A69A")
|
||||||
|
|
||||||
(defn theme-colors [light dark]
|
(defn theme-colors [light dark]
|
||||||
(if (theme/dark?) dark light))
|
(if (theme/dark?) dark light))
|
||||||
|
|
|
@ -29,4 +29,4 @@
|
||||||
|
|
||||||
(def font-bold {:font-family "Inter-Bold"}) ; 700
|
(def font-bold {:font-family "Inter-Bold"}) ; 700
|
||||||
|
|
||||||
(def monospace {:font-family "InterStatus-Regular"})
|
(def monospace {:font-family "InterStatus-Regular"})
|
|
@ -63,6 +63,25 @@
|
||||||
[react/view {:style dot-styles
|
[react/view {:style dot-styles
|
||||||
:accessibility-label dot-accessibility-label}])]))
|
:accessibility-label dot-accessibility-label}])]))
|
||||||
|
|
||||||
|
(defn profile-photo-plus-dot-view-old
|
||||||
|
[{:keys [public-key photo-container photo-path community?]}]
|
||||||
|
(let [photo-path (if (nil? photo-path)
|
||||||
|
@(re-frame.core/subscribe [:chats/photo-path public-key])
|
||||||
|
photo-path)
|
||||||
|
photo-container (if (nil? photo-container)
|
||||||
|
styles/container-chat-list photo-container)
|
||||||
|
size (:width photo-container)
|
||||||
|
identicon? (when photo-path (profile.db/base64-png? photo-path))
|
||||||
|
dot-styles (visibility-status-utils/icon-visibility-status-dot-old
|
||||||
|
public-key size identicon?)
|
||||||
|
dot-accessibility-label (:accessibility-label dot-styles)]
|
||||||
|
[react/view {:style photo-container
|
||||||
|
:accessibility-label :profile-photo}
|
||||||
|
[photos/photo photo-path {:size size}]
|
||||||
|
(when-not community?
|
||||||
|
[react/view {:style dot-styles
|
||||||
|
:accessibility-label dot-accessibility-label}])]))
|
||||||
|
|
||||||
(defn emoji-chat-icon-view
|
(defn emoji-chat-icon-view
|
||||||
[chat-id group-chat name emoji styles]
|
[chat-id group-chat name emoji styles]
|
||||||
[react/view (:container styles)
|
[react/view (:container styles)
|
||||||
|
@ -73,6 +92,16 @@
|
||||||
[profile-photo-plus-dot-view {:public-key chat-id
|
[profile-photo-plus-dot-view {:public-key chat-id
|
||||||
:photo-container (:default-chat-icon styles)}])])
|
:photo-container (:default-chat-icon styles)}])])
|
||||||
|
|
||||||
|
(defn emoji-chat-icon-view-old
|
||||||
|
[chat-id group-chat name emoji styles]
|
||||||
|
[react/view (:container styles)
|
||||||
|
(if group-chat
|
||||||
|
(if (string/blank? emoji)
|
||||||
|
[default-chat-icon name styles]
|
||||||
|
[emoji-chat-icon emoji styles])
|
||||||
|
[profile-photo-plus-dot-view-old {:public-key chat-id
|
||||||
|
:photo-container (:default-chat-icon styles)}])])
|
||||||
|
|
||||||
(defn chat-icon-view-toolbar
|
(defn chat-icon-view-toolbar
|
||||||
[chat-id group-chat name color emoji]
|
[chat-id group-chat name color emoji]
|
||||||
[emoji-chat-icon-view chat-id group-chat name emoji
|
[emoji-chat-icon-view chat-id group-chat name emoji
|
||||||
|
@ -163,10 +192,10 @@
|
||||||
(styles/emoji-chat-icon-text size))} override-styles)]
|
(styles/emoji-chat-icon-text size))} override-styles)]
|
||||||
[react/view (:container styles)
|
[react/view (:container styles)
|
||||||
(if (and photo-path (seq photo-path))
|
(if (and photo-path (seq photo-path))
|
||||||
[profile-photo-plus-dot-view {:photo-path photo-path
|
[profile-photo-plus-dot-view-old {:photo-path photo-path
|
||||||
:public-key public-key
|
:public-key public-key
|
||||||
:photo-container (:container styles)
|
:photo-container (:container styles)
|
||||||
:community? community?}]
|
:community? community?}]
|
||||||
(if (string/blank? emoji)
|
(if (string/blank? emoji)
|
||||||
[default-chat-icon name styles]
|
[default-chat-icon name styles]
|
||||||
[emoji-chat-icon emoji styles]))
|
[emoji-chat-icon emoji styles]))
|
||||||
|
|
|
@ -2,9 +2,24 @@
|
||||||
(:require [quo.design-system.colors :as colors]
|
(:require [quo.design-system.colors :as colors]
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.components.icons.icons :as icons]))
|
[status-im.ui.components.icons.icons :as icons]
|
||||||
|
[quo2.components.button :as quo2.button]))
|
||||||
|
|
||||||
(def action-button-container
|
(def action-button-container
|
||||||
|
{:align-items :center
|
||||||
|
:justify-content :center
|
||||||
|
:height 32
|
||||||
|
:border-radius 16
|
||||||
|
:overflow :hidden})
|
||||||
|
|
||||||
|
(defn action-button []
|
||||||
|
{:width 32
|
||||||
|
:height 32
|
||||||
|
:border-radius 18
|
||||||
|
:align-items :center
|
||||||
|
:justify-content :center})
|
||||||
|
|
||||||
|
(def action-button-container-old
|
||||||
{:position :absolute
|
{:position :absolute
|
||||||
:z-index 2
|
:z-index 2
|
||||||
:align-items :center
|
:align-items :center
|
||||||
|
@ -14,7 +29,7 @@
|
||||||
:bottom 16
|
:bottom 16
|
||||||
:height 40})
|
:height 40})
|
||||||
|
|
||||||
(defn action-button []
|
(defn action-button-old []
|
||||||
{:width 40
|
{:width 40
|
||||||
:height 40
|
:height 40
|
||||||
:background-color colors/blue
|
:background-color colors/blue
|
||||||
|
@ -31,10 +46,23 @@
|
||||||
|
|
||||||
(defn plus-button [{:keys [on-press loading accessibility-label]}]
|
(defn plus-button [{:keys [on-press loading accessibility-label]}]
|
||||||
[react/view action-button-container
|
[react/view action-button-container
|
||||||
[quo/button {:type :scale
|
[quo2.button/button {:type :primary
|
||||||
:accessibility-label (or accessibility-label :plus-button)
|
:size 32
|
||||||
:on-press on-press}
|
:width 32
|
||||||
|
:accessibility-label (or accessibility-label :plus-button)
|
||||||
|
:on-press on-press}
|
||||||
[react/view (action-button)
|
[react/view (action-button)
|
||||||
|
(if loading
|
||||||
|
[react/activity-indicator {:color colors/white-persist
|
||||||
|
:animating true}]
|
||||||
|
[icons/icon :main-icons/add {:color colors/white-persist}])]]])
|
||||||
|
|
||||||
|
(defn plus-button-old [{:keys [on-press loading accessibility-label]}]
|
||||||
|
[react/view action-button-container-old
|
||||||
|
[quo/button {:type :scale
|
||||||
|
:accessibility-label (or accessibility-label :plus-button)
|
||||||
|
:on-press on-press}
|
||||||
|
[react/view (action-button-old)
|
||||||
(if loading
|
(if loading
|
||||||
[react/activity-indicator {:color colors/white-persist
|
[react/activity-indicator {:color colors/white-persist
|
||||||
:animating true}]
|
:animating true}]
|
||||||
|
|
|
@ -2,9 +2,53 @@
|
||||||
(:require [reagent.core :as reagent]
|
(:require [reagent.core :as reagent]
|
||||||
[status-im.i18n.i18n :as i18n]
|
[status-im.i18n.i18n :as i18n]
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[quo.design-system.colors :as colors]))
|
[quo.design-system.colors :as colors]
|
||||||
|
[quo2.foundations.colors :as quo2.colors]))
|
||||||
|
|
||||||
(defn search-input [{:keys [search-active?]}]
|
(defn search-input [{:keys [search-active?]}]
|
||||||
|
(let [input-ref (atom nil)
|
||||||
|
search-active? (or search-active? (reagent/atom nil))]
|
||||||
|
(fn [{:keys [on-focus on-change on-blur on-cancel search-filter auto-focus]}]
|
||||||
|
[quo/text-input {:placeholder (i18n/label :t/search)
|
||||||
|
:accessibility-label :search-input
|
||||||
|
:blur-on-submit true
|
||||||
|
:multiline false
|
||||||
|
:get-ref #(reset! input-ref %)
|
||||||
|
:default-value search-filter
|
||||||
|
:auto-focus auto-focus
|
||||||
|
:on-cancel on-cancel
|
||||||
|
:show-cancel true
|
||||||
|
:auto-correct false
|
||||||
|
:auto-capitalize :none
|
||||||
|
:container-style {:border-radius 10
|
||||||
|
:border-width 1
|
||||||
|
:border-color (:ui-01 @colors/theme)
|
||||||
|
:background-color (quo2.colors/theme-colors quo2.colors/white quo2.colors/neutral-90)
|
||||||
|
:overflow :hidden}
|
||||||
|
:input-style {:height 32
|
||||||
|
:padding-top 2
|
||||||
|
:padding-bottom 2
|
||||||
|
:background-color (quo2.colors/theme-colors quo2.colors/white quo2.colors/neutral-90)}
|
||||||
|
:before {:icon :main-icons/search2
|
||||||
|
:style {:padding-horizontal 8
|
||||||
|
:background-color (quo2.colors/theme-colors quo2.colors/white quo2.colors/neutral-90)}
|
||||||
|
:on-press #(some-> ^js @input-ref (.focus))
|
||||||
|
:icon-opts {:color (quo2.colors/theme-colors quo2.colors/neutral-50 quo2.colors/white)}}
|
||||||
|
:on-focus #(do
|
||||||
|
(when on-focus
|
||||||
|
(on-focus search-filter))
|
||||||
|
(reset! search-active? true))
|
||||||
|
:on-blur #(do
|
||||||
|
(when on-blur
|
||||||
|
(on-blur))
|
||||||
|
(reset! search-active? false))
|
||||||
|
:on-change (fn [e]
|
||||||
|
(let [^js native-event (.-nativeEvent ^js e)
|
||||||
|
text (.-text native-event)]
|
||||||
|
(when on-change
|
||||||
|
(on-change text))))}])))
|
||||||
|
|
||||||
|
(defn search-input-old [{:keys [search-active?]}]
|
||||||
(let [input-ref (atom nil)
|
(let [input-ref (atom nil)
|
||||||
search-active? (or search-active? (reagent/atom nil))]
|
search-active? (or search-active? (reagent/atom nil))]
|
||||||
(fn [{:keys [on-focus on-change on-blur on-cancel search-filter auto-focus]}]
|
(fn [{:keys [on-focus on-change on-blur on-cancel search-filter auto-focus]}]
|
||||||
|
@ -38,4 +82,4 @@
|
||||||
(let [^js native-event (.-nativeEvent ^js e)
|
(let [^js native-event (.-nativeEvent ^js e)
|
||||||
text (.-text native-event)]
|
text (.-text native-event)]
|
||||||
(when on-change
|
(when on-change
|
||||||
(on-change text))))}])))
|
(on-change text))))}])))
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im.ui.components.topbar
|
(ns status-im.ui.components.topbar
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[quo.core :as quo]))
|
[quo.core :as quo]
|
||||||
|
[quo2.foundations.colors :as quo2.colors]))
|
||||||
|
|
||||||
(def default-button-width 48)
|
(def default-button-width 48)
|
||||||
|
|
||||||
|
@ -20,7 +21,9 @@
|
||||||
label
|
label
|
||||||
(assoc :label label)))
|
(assoc :label label)))
|
||||||
|
|
||||||
(defn topbar [{:keys [navigation use-insets right-accessories modal? content]
|
(defn topbar [{:keys [navigation use-insets right-accessories modal? content border-bottom? new-ui?] ;; remove new-ui? key, temp fix
|
||||||
|
:or {border-bottom? true
|
||||||
|
new-ui? false}
|
||||||
:as props}]
|
:as props}]
|
||||||
(let [navigation (if (= navigation :none)
|
(let [navigation (if (= navigation :none)
|
||||||
nil
|
nil
|
||||||
|
@ -31,7 +34,10 @@
|
||||||
:title-component content
|
:title-component content
|
||||||
:insets (when use-insets insets)
|
:insets (when use-insets insets)
|
||||||
:left-width (when navigation
|
:left-width (when navigation
|
||||||
default-button-width)}
|
default-button-width)
|
||||||
|
:border-bottom border-bottom?}
|
||||||
props
|
props
|
||||||
(when (seq right-accessories)
|
(when (seq right-accessories)
|
||||||
{:right-accessories right-accessories}))])]))
|
{:right-accessories right-accessories})
|
||||||
|
(when new-ui?
|
||||||
|
{:background (quo2.colors/theme-colors quo2.colors/white quo2.colors/divider-dark)}))])]))
|
||||||
|
|
|
@ -71,5 +71,5 @@
|
||||||
:key-fn :browser-id
|
:key-fn :browser-id
|
||||||
:render-fn list-item}]
|
:render-fn list-item}]
|
||||||
|
|
||||||
[components.plus-button/plus-button
|
[components.plus-button/plus-button-old
|
||||||
{:on-press #(re-frame/dispatch [:browser.ui/open-empty-tab])}]]))
|
{:on-press #(re-frame/dispatch [:browser.ui/open-empty-tab])}]]))
|
|
@ -171,16 +171,16 @@
|
||||||
(update-state params))
|
(update-state params))
|
||||||
#(update-state (merge params {:error (:message %)}))))))
|
#(update-state (merge params {:error (:message %)}))))))
|
||||||
|
|
||||||
(defn- play-pause-button [state-ref outgoing on-press]
|
(defn- play-pause-button [state-ref on-press]
|
||||||
(let [color (if outgoing colors/blue colors/white-persist)]
|
(let [color colors/blue]
|
||||||
(if (= (:general @state-ref) :preparing)
|
(if (= (:general @state-ref) :preparing)
|
||||||
[react/view {:style (style/play-pause-container outgoing true)}
|
[react/view {:style (style/play-pause-container true)}
|
||||||
[react/small-loading-indicator color]]
|
[react/small-loading-indicator color]]
|
||||||
[react/touchable-highlight {:on-press on-press}
|
[react/touchable-highlight {:on-press on-press}
|
||||||
[icons/icon (case (:general @state-ref)
|
[icons/icon (case (:general @state-ref)
|
||||||
:playing :main-icons/pause
|
:playing :main-icons/pause
|
||||||
:main-icons/play)
|
:main-icons/play)
|
||||||
{:container-style (style/play-pause-container outgoing false)
|
{:container-style (style/play-pause-container false)
|
||||||
:accessibility-label :play-pause-audio-message-button
|
:accessibility-label :play-pause-audio-message-button
|
||||||
:color color}]])))
|
:color color}]])))
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@
|
||||||
:message-id @current-player-message-id}))
|
:message-id @current-player-message-id}))
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(defview message-content [{:keys [audio audio-duration-ms message-id outgoing]}]
|
(defview message-content [{:keys [audio audio-duration-ms message-id]}]
|
||||||
(letsubs [state (reagent/atom nil)
|
(letsubs [state (reagent/atom nil)
|
||||||
progress (reagent/atom 0)
|
progress (reagent/atom 0)
|
||||||
progress-anim (anim/create-value 0)
|
progress-anim (anim/create-value 0)
|
||||||
|
@ -218,9 +218,9 @@
|
||||||
:margin-bottom 16}} (:error-msg @state)]
|
:margin-bottom 16}} (:error-msg @state)]
|
||||||
[react/view (style/container width)
|
[react/view (style/container width)
|
||||||
[react/view style/play-pause-slider-container
|
[react/view style/play-pause-slider-container
|
||||||
[play-pause-button state outgoing #(play-pause base-params audio)]
|
[play-pause-button state #(play-pause base-params audio)]
|
||||||
[react/view style/slider-container
|
[react/view style/slider-container
|
||||||
[slider/animated-slider (merge (style/slider outgoing)
|
[slider/animated-slider (merge (style/slider)
|
||||||
{:minimum-value 0
|
{:minimum-value 0
|
||||||
:maximum-value (:duration @state)
|
:maximum-value (:duration @state)
|
||||||
:value progress-anim
|
:value progress-anim
|
||||||
|
@ -229,7 +229,7 @@
|
||||||
:on-sliding-complete #(seek (merge base-params {:slider-new-state-seeking? false}) % true nil)})]]]
|
:on-sliding-complete #(seek (merge base-params {:slider-new-state-seeking? false}) % true nil)})]]]
|
||||||
|
|
||||||
[react/view style/times-container
|
[react/view style/times-container
|
||||||
[react/text {:style (style/timestamp outgoing)}
|
[react/text {:style (style/timestamp)}
|
||||||
(let [time (cond
|
(let [time (cond
|
||||||
(or (:slider-seeking @state) (> (:seek-to-ms @state) 0)) (:seek-to-ms @state)
|
(or (:slider-seeking @state) (> (:seek-to-ms @state) 0)) (:seek-to-ms @state)
|
||||||
(#{:playing :paused :seeking} (:general @state)) @progress
|
(#{:playing :paused :seeking} (:general @state)) @progress
|
||||||
|
|
|
@ -0,0 +1,238 @@
|
||||||
|
(ns status-im.ui.screens.chat.message.audio-old
|
||||||
|
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||||
|
(:require [status-im.utils.utils :as utils]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[goog.string :as gstring]
|
||||||
|
[status-im.audio.core :as audio]
|
||||||
|
[status-im.utils.fx :as fx]
|
||||||
|
[status-im.ui.screens.chat.styles.message.audio-old :as style]
|
||||||
|
[status-im.ui.components.animation :as anim]
|
||||||
|
[quo.design-system.colors :as colors]
|
||||||
|
[status-im.ui.components.icons.icons :as icons]
|
||||||
|
[status-im.ui.components.react :as react]
|
||||||
|
[status-im.ui.components.slider :as slider]
|
||||||
|
["react-native-blob-util" :default ReactNativeBlobUtil]
|
||||||
|
[status-im.utils.platform :as platform]
|
||||||
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
|
(defonce player-ref (atom nil))
|
||||||
|
(defonce current-player-message-id (atom nil))
|
||||||
|
(defonce current-active-state-ref-ref (atom nil))
|
||||||
|
(defonce progress-timer (atom nil))
|
||||||
|
|
||||||
|
(defn start-stop-progress-timer [{:keys [state-ref progress-ref progress-anim]} start?]
|
||||||
|
(when @progress-timer
|
||||||
|
(utils/clear-interval @progress-timer)
|
||||||
|
(when-not start?
|
||||||
|
(reset! progress-timer nil)))
|
||||||
|
(when start?
|
||||||
|
(when @progress-timer
|
||||||
|
(utils/clear-interval @progress-timer))
|
||||||
|
(reset! progress-timer (utils/set-interval
|
||||||
|
#(when (and @state-ref (not (:slider-seeking @state-ref)))
|
||||||
|
(let [ct (audio/get-player-current-time @player-ref)]
|
||||||
|
(reset! progress-ref ct)
|
||||||
|
(when ct
|
||||||
|
(anim/start (anim/timing progress-anim {:toValue @progress-ref
|
||||||
|
:duration 100
|
||||||
|
:easing (.-linear ^js anim/easing)
|
||||||
|
:useNativeDriver true})))))
|
||||||
|
100))))
|
||||||
|
|
||||||
|
(defn update-state [{:keys [state-ref progress-ref progress-anim message-id seek-to-ms audio-duration-ms slider-new-state-seeking? unloaded? error]}]
|
||||||
|
(let [player-state (audio/get-state @player-ref)
|
||||||
|
slider-seeking (if (some? slider-new-state-seeking?)
|
||||||
|
slider-new-state-seeking?
|
||||||
|
(:slider-seeking @state-ref))
|
||||||
|
general (cond
|
||||||
|
(some? error) :error
|
||||||
|
(or unloaded? (not= message-id @current-player-message-id)) :not-loaded
|
||||||
|
slider-seeking (:general @state-ref) ; persist player state at the time user started sliding
|
||||||
|
(= player-state audio/PLAYING) :playing
|
||||||
|
(= player-state audio/PAUSED) :paused
|
||||||
|
(= player-state audio/SEEKING) :seeking
|
||||||
|
(= player-state audio/PREPARED) :ready-to-play
|
||||||
|
:else :preparing)
|
||||||
|
new-state {:general general
|
||||||
|
:error-msg error
|
||||||
|
:duration (cond (not (#{:preparing :not-loaded :error} general))
|
||||||
|
(audio/get-player-duration @player-ref)
|
||||||
|
|
||||||
|
audio-duration-ms audio-duration-ms
|
||||||
|
|
||||||
|
:else (:duration @state-ref))
|
||||||
|
:progress-ref (or progress-ref (:progress-ref @state-ref))
|
||||||
|
:progress-anim (or progress-anim (:progress-anim @state-ref))
|
||||||
|
:slider-seeking slider-seeking
|
||||||
|
|
||||||
|
; persist seek-to-ms while seeking or audio is not loaded
|
||||||
|
:seek-to-ms (when (or
|
||||||
|
slider-seeking
|
||||||
|
(#{:preparing :not-loaded :error} general))
|
||||||
|
(or seek-to-ms (:seek-to-ms @state-ref)))}]
|
||||||
|
; update state if needed
|
||||||
|
(when (not= @state-ref new-state)
|
||||||
|
(reset! state-ref new-state))
|
||||||
|
|
||||||
|
; update progress UI on slider release
|
||||||
|
(when (and (some? slider-new-state-seeking?) (not slider-new-state-seeking?) (some? seek-to-ms))
|
||||||
|
(reset! (:progress-ref new-state) seek-to-ms))
|
||||||
|
|
||||||
|
; update progres anim value to follow the slider
|
||||||
|
(when (and slider-seeking (some? seek-to-ms))
|
||||||
|
(anim/set-value (:progress-anim new-state) seek-to-ms))
|
||||||
|
|
||||||
|
; on unload, reset values
|
||||||
|
(when unloaded?
|
||||||
|
(reset! (:progress-ref new-state) 0)
|
||||||
|
(anim/set-value (:progress-anim new-state) 0))))
|
||||||
|
|
||||||
|
(defn destroy-player [{:keys [message-id reloading?]}]
|
||||||
|
(when (and @player-ref (or reloading?
|
||||||
|
(= message-id @current-player-message-id)))
|
||||||
|
(audio/destroy-player @player-ref)
|
||||||
|
(reset! player-ref nil)
|
||||||
|
(when @current-active-state-ref-ref
|
||||||
|
(update-state {:state-ref @current-active-state-ref-ref :unloaded? true}))
|
||||||
|
(reset! current-player-message-id nil)
|
||||||
|
(reset! current-active-state-ref-ref nil)))
|
||||||
|
|
||||||
|
(defonce last-seek (atom (js/Date.now)))
|
||||||
|
|
||||||
|
(defn seek [{:keys [message-id] :as params} value immediate? on-success]
|
||||||
|
(when (and @player-ref (= message-id @current-player-message-id))
|
||||||
|
(let [now (js/Date.now)]
|
||||||
|
(when (or immediate? (> (- now @last-seek) 200))
|
||||||
|
(reset! last-seek (js/Date.now))
|
||||||
|
(audio/seek-player
|
||||||
|
@player-ref
|
||||||
|
value
|
||||||
|
#(do
|
||||||
|
(update-state params)
|
||||||
|
(when on-success (on-success)))
|
||||||
|
#(update-state (merge params {:error (:message %)}))))))
|
||||||
|
(update-state (merge params {:seek-to-ms value})))
|
||||||
|
|
||||||
|
(defn download-audio-http [base64-uri on-success]
|
||||||
|
(-> (.config ReactNativeBlobUtil (clj->js {:trusty platform/ios?}))
|
||||||
|
(.fetch "GET" (str base64-uri))
|
||||||
|
(.then #(on-success (.base64 ^js %)))
|
||||||
|
(.catch #(log/error "could not fetch audio"))))
|
||||||
|
|
||||||
|
(defn reload-player [{:keys [message-id state-ref] :as params} audio-url on-success]
|
||||||
|
;; to avoid reloading player while is initializing,
|
||||||
|
;; we go ahead only if there is no player or
|
||||||
|
;; if it is already prepared
|
||||||
|
(when (or (nil? @player-ref) (audio/can-play? @player-ref))
|
||||||
|
(when @player-ref
|
||||||
|
(destroy-player (merge params {:reloading? true})))
|
||||||
|
(download-audio-http
|
||||||
|
audio-url
|
||||||
|
(fn [base64-data]
|
||||||
|
(reset! player-ref (audio/new-player
|
||||||
|
(str "data:audio/acc;base64," base64-data)
|
||||||
|
{:autoDestroy false
|
||||||
|
:continuesToPlayInBackground false}
|
||||||
|
#(seek params 0 true nil)))
|
||||||
|
(audio/prepare-player
|
||||||
|
@player-ref
|
||||||
|
#(when on-success (on-success))
|
||||||
|
#(update-state (merge params {:error (:message %)})))
|
||||||
|
(reset! current-player-message-id message-id)
|
||||||
|
(reset! current-active-state-ref-ref state-ref)
|
||||||
|
(update-state params)))))
|
||||||
|
|
||||||
|
(defn play-pause [{:keys [message-id state-ref] :as params} audio]
|
||||||
|
(if (not= message-id @current-player-message-id)
|
||||||
|
;; player has audio from another message, we need to reload
|
||||||
|
(reload-player params
|
||||||
|
audio
|
||||||
|
;; on-success: audio is loaded, do we have an existing value to seek to?
|
||||||
|
#(if-some [seek-time (:seek-to-ms @state-ref)]
|
||||||
|
;; check seek time against real audio duration and play
|
||||||
|
(let [checked-seek-time (min (audio/get-player-duration @player-ref) seek-time)]
|
||||||
|
(seek params
|
||||||
|
checked-seek-time
|
||||||
|
true
|
||||||
|
(fn [] (play-pause params audio))))
|
||||||
|
|
||||||
|
;; nothing to seek to, play
|
||||||
|
(play-pause params audio)))
|
||||||
|
|
||||||
|
;; loaded audio corresponds to current message we can play
|
||||||
|
(when @player-ref
|
||||||
|
(audio/toggle-playpause-player
|
||||||
|
@player-ref
|
||||||
|
#(do
|
||||||
|
(start-stop-progress-timer params true)
|
||||||
|
(update-state params))
|
||||||
|
#(do
|
||||||
|
(start-stop-progress-timer params false)
|
||||||
|
(update-state params))
|
||||||
|
#(update-state (merge params {:error (:message %)}))))))
|
||||||
|
|
||||||
|
(defn- play-pause-button [state-ref outgoing on-press]
|
||||||
|
(let [color (if outgoing colors/blue colors/white-persist)]
|
||||||
|
(if (= (:general @state-ref) :preparing)
|
||||||
|
[react/view {:style (style/play-pause-container outgoing true)}
|
||||||
|
[react/small-loading-indicator color]]
|
||||||
|
[react/touchable-highlight {:on-press on-press}
|
||||||
|
[icons/icon (case (:general @state-ref)
|
||||||
|
:playing :main-icons/pause
|
||||||
|
:main-icons/play)
|
||||||
|
{:container-style (style/play-pause-container outgoing false)
|
||||||
|
:accessibility-label :play-pause-audio-message-button
|
||||||
|
:color color}]])))
|
||||||
|
|
||||||
|
(fx/defn on-background
|
||||||
|
{:events [:audio-message/on-background]}
|
||||||
|
[_]
|
||||||
|
(when (and @current-active-state-ref-ref
|
||||||
|
@@current-active-state-ref-ref)
|
||||||
|
(update-state {:state-ref @current-active-state-ref-ref
|
||||||
|
:message-id @current-player-message-id}))
|
||||||
|
nil)
|
||||||
|
|
||||||
|
(defview message-content [{:keys [audio audio-duration-ms message-id outgoing]}]
|
||||||
|
(letsubs [state (reagent/atom nil)
|
||||||
|
progress (reagent/atom 0)
|
||||||
|
progress-anim (anim/create-value 0)
|
||||||
|
width [:dimensions/window-width]]
|
||||||
|
{:component-did-mount (fn []
|
||||||
|
(update-state {:state-ref state
|
||||||
|
:audio-duration-ms audio-duration-ms
|
||||||
|
:message-id message-id
|
||||||
|
:unloaded? true
|
||||||
|
:progress-ref progress
|
||||||
|
:progress-anim progress-anim}))
|
||||||
|
:component-will-unmount (fn []
|
||||||
|
(destroy-player {:state-ref state :message-id message-id})
|
||||||
|
(when (= @current-player-message-id message-id)
|
||||||
|
(reset! current-active-state-ref-ref nil)
|
||||||
|
(reset! current-player-message-id nil))
|
||||||
|
(reset! state nil))}
|
||||||
|
|
||||||
|
(let [base-params {:state-ref state :message-id message-id :progress-ref progress :progress-anim progress-anim}]
|
||||||
|
(if (= (:general @state) :error)
|
||||||
|
[react/text {:style {:typography :main-medium
|
||||||
|
:margin-bottom 16}} (:error-msg @state)]
|
||||||
|
[react/view (style/container width)
|
||||||
|
[react/view style/play-pause-slider-container
|
||||||
|
[play-pause-button state outgoing #(play-pause base-params audio)]
|
||||||
|
[react/view style/slider-container
|
||||||
|
[slider/animated-slider (merge (style/slider outgoing)
|
||||||
|
{:minimum-value 0
|
||||||
|
:maximum-value (:duration @state)
|
||||||
|
:value progress-anim
|
||||||
|
:on-value-change #(seek base-params % false nil)
|
||||||
|
:on-sliding-start #(seek (merge base-params {:slider-new-state-seeking? true}) % true nil)
|
||||||
|
:on-sliding-complete #(seek (merge base-params {:slider-new-state-seeking? false}) % true nil)})]]]
|
||||||
|
|
||||||
|
[react/view style/times-container
|
||||||
|
[react/text {:style (style/timestamp outgoing)}
|
||||||
|
(let [time (cond
|
||||||
|
(or (:slider-seeking @state) (> (:seek-to-ms @state) 0)) (:seek-to-ms @state)
|
||||||
|
(#{:playing :paused :seeking} (:general @state)) @progress
|
||||||
|
:else (:duration @state))
|
||||||
|
s (quot time 1000)]
|
||||||
|
(gstring/format "%02d:%02d" (quot s 60) (mod s 60)))]]]))))
|
|
@ -1,12 +1,17 @@
|
||||||
(ns status-im.ui.screens.chat.message.datemark
|
(ns status-im.ui.screens.chat.message.datemark
|
||||||
(:require [status-im.ui.components.react :as react]
|
(:require [status-im.ui.components.react :as react]
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[status-im.ui.screens.chat.styles.message.datemark :as style]))
|
[status-im.ui.screens.chat.styles.message.datemark :as style]
|
||||||
|
[quo2.components.text :as quo2.text]
|
||||||
|
[quo2.foundations.colors :as quo2.colors]))
|
||||||
|
|
||||||
(defn chat-datemark [value]
|
(defn chat-datemark [value]
|
||||||
[react/touchable-without-feedback
|
[react/touchable-without-feedback
|
||||||
{:on-press (fn [_]
|
{:on-press (fn [_]
|
||||||
(react/dismiss-keyboard!))}
|
(react/dismiss-keyboard!))}
|
||||||
[react/view style/datemark-mobile
|
[react/view style/datemark-mobile
|
||||||
[react/text {:style (style/datemark-text)}
|
[quo2.text/text {:weight :medium
|
||||||
(string/capitalize value)]]])
|
:accessibility-label :message-datemark-text
|
||||||
|
:style {:color quo2.colors/neutral-50}}
|
||||||
|
(string/capitalize value)]
|
||||||
|
[react/view (style/divider)]]])
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
(ns status-im.ui.screens.chat.message.datemark-old
|
||||||
|
(:require [status-im.ui.components.react :as react]
|
||||||
|
[clojure.string :as string]
|
||||||
|
[status-im.ui.screens.chat.styles.message.datemark-old :as style]))
|
||||||
|
|
||||||
|
(defn chat-datemark [value]
|
||||||
|
[react/touchable-without-feedback
|
||||||
|
{:on-press (fn [_]
|
||||||
|
(react/dismiss-keyboard!))}
|
||||||
|
[react/view style/datemark-mobile
|
||||||
|
[react/text {:style (style/datemark-text)}
|
||||||
|
(string/capitalize value)]]])
|
|
@ -73,13 +73,13 @@
|
||||||
:height 12
|
:height 12
|
||||||
:color (if pinned colors/gray colors/white)
|
:color (if pinned colors/gray colors/white)
|
||||||
:accessibility-label (name outgoing-status)}])
|
:accessibility-label (name outgoing-status)}])
|
||||||
(when edited-at [react/text {:style (style/message-status-text (and outgoing (not pinned)))} edited-at-text])]))
|
(when edited-at [react/text {:style (style/message-status-text)} edited-at-text])]))
|
||||||
|
|
||||||
(defn message-timestamp
|
(defn message-timestamp
|
||||||
[{:keys [timestamp-str in-popover?] :as message} show-timestamp?]
|
[{:keys [timestamp-str in-popover?]} show-timestamp?]
|
||||||
(when-not in-popover? ;; We keep track if showing this message in a list in pin-limit-popover
|
(when-not in-popover? ;; We keep track if showing this message in a list in pin-limit-popover
|
||||||
(let [anim-opacity (animation/create-value 0)]
|
(let [anim-opacity (animation/create-value 0)]
|
||||||
[react/animated-view {:style (style/message-timestamp-wrapper message) :opacity anim-opacity}
|
[react/animated-view {:style (style/message-timestamp-wrapper) :opacity anim-opacity}
|
||||||
(when @show-timestamp? (message-timestamp-anim anim-opacity show-timestamp?))
|
(when @show-timestamp? (message-timestamp-anim anim-opacity show-timestamp?))
|
||||||
[react/text
|
[react/text
|
||||||
{:style (style/message-timestamp-text)
|
{:style (style/message-timestamp-text)
|
||||||
|
@ -87,16 +87,16 @@
|
||||||
timestamp-str]])))
|
timestamp-str]])))
|
||||||
|
|
||||||
(defview quoted-message
|
(defview quoted-message
|
||||||
[_ {:keys [from parsed-text image]} outgoing current-public-key public? pinned]
|
[_ {:keys [from parsed-text image]} current-public-key public? pinned]
|
||||||
(letsubs [contact-name [:contacts/contact-name-by-identity from]]
|
(letsubs [contact-name [:contacts/contact-name-by-identity from]]
|
||||||
[react/view {:style (style/quoted-message-container (and outgoing (not pinned)))}
|
[react/view {:style (style/quoted-message-container)}
|
||||||
[react/view {:style style/quoted-message-author-container}
|
[react/view {:style style/quoted-message-author-container}
|
||||||
[chat.utils/format-reply-author
|
[chat.utils/format-reply-author
|
||||||
from
|
from
|
||||||
contact-name
|
contact-name
|
||||||
current-public-key
|
current-public-key
|
||||||
(partial style/quoted-message-author (and outgoing (not pinned)))
|
(partial style/quoted-message-author (not pinned))
|
||||||
(and outgoing (not pinned))]]
|
false]]
|
||||||
(if (and image
|
(if (and image
|
||||||
;; Disabling images for public-chats
|
;; Disabling images for public-chats
|
||||||
(not public?))
|
(not public?))
|
||||||
|
@ -105,11 +105,11 @@
|
||||||
:background-color :black
|
:background-color :black
|
||||||
:border-radius 4}
|
:border-radius 4}
|
||||||
:source {:uri image}}]
|
:source {:uri image}}]
|
||||||
[react/text {:style (style/quoted-message-text (and outgoing (not pinned)))
|
[react/text {:style (style/quoted-message-text)
|
||||||
:number-of-lines 5}
|
:number-of-lines 5}
|
||||||
(components.reply/get-quoted-text-with-mentions parsed-text)])]))
|
(components.reply/get-quoted-text-with-mentions parsed-text)])]))
|
||||||
|
|
||||||
(defn render-inline [message-text outgoing pinned content-type acc {:keys [type literal destination]}]
|
(defn render-inline [message-text content-type acc {:keys [type literal destination]}]
|
||||||
(case type
|
(case type
|
||||||
""
|
""
|
||||||
(conj acc literal)
|
(conj acc literal)
|
||||||
|
@ -121,22 +121,22 @@
|
||||||
literal])
|
literal])
|
||||||
|
|
||||||
"emph"
|
"emph"
|
||||||
(conj acc [react/text-class (style/emph-style (and outgoing (not pinned))) literal])
|
(conj acc [react/text-class (style/emph-style) literal])
|
||||||
|
|
||||||
"strong"
|
"strong"
|
||||||
(conj acc [react/text-class (style/strong-style (and outgoing (not pinned))) literal])
|
(conj acc [react/text-class (style/strong-style) literal])
|
||||||
|
|
||||||
"strong-emph"
|
"strong-emph"
|
||||||
(conj acc [quo/text (style/strong-emph-style (and outgoing (not pinned))) literal])
|
(conj acc [quo/text (style/strong-emph-style) literal])
|
||||||
|
|
||||||
"del"
|
"del"
|
||||||
(conj acc [react/text-class (style/strikethrough-style (and outgoing (not pinned))) literal])
|
(conj acc [react/text-class (style/strikethrough-style) literal])
|
||||||
|
|
||||||
"link"
|
"link"
|
||||||
(conj acc
|
(conj acc
|
||||||
[react/text-class
|
[react/text-class
|
||||||
{:style
|
{:style
|
||||||
{:color (if (and outgoing (not pinned)) colors/white-persist colors/blue)
|
{:color colors/blue
|
||||||
:text-decoration-line :underline}
|
:text-decoration-line :underline}
|
||||||
:on-press
|
:on-press
|
||||||
#(when (and (security/safe-link? destination)
|
#(when (and (security/safe-link? destination)
|
||||||
|
@ -149,14 +149,13 @@
|
||||||
(conj acc [react/text-class
|
(conj acc [react/text-class
|
||||||
{:style {:color (cond
|
{:style {:color (cond
|
||||||
(= content-type constants/content-type-system-text) colors/black
|
(= content-type constants/content-type-system-text) colors/black
|
||||||
(and outgoing (not pinned)) colors/mention-outgoing
|
|
||||||
:else colors/mention-incoming)}
|
:else colors/mention-incoming)}
|
||||||
:on-press (when-not (= content-type constants/content-type-system-text)
|
:on-press (when-not (= content-type constants/content-type-system-text)
|
||||||
#(re-frame/dispatch [:chat.ui/show-profile literal]))}
|
#(re-frame/dispatch [:chat.ui/show-profile literal]))}
|
||||||
[mention-element literal]])
|
[mention-element literal]])
|
||||||
"status-tag"
|
"status-tag"
|
||||||
(conj acc [react/text-class
|
(conj acc [react/text-class
|
||||||
{:style {:color (if (and outgoing (not pinned)) colors/white-persist colors/blue)
|
{:style {:color colors/blue
|
||||||
:text-decoration-line :underline}
|
:text-decoration-line :underline}
|
||||||
:on-press
|
:on-press
|
||||||
#(re-frame/dispatch
|
#(re-frame/dispatch
|
||||||
|
@ -166,19 +165,19 @@
|
||||||
|
|
||||||
(conj acc literal)))
|
(conj acc literal)))
|
||||||
|
|
||||||
(defn render-block [{:keys [content outgoing content-type pinned in-popover?]} acc
|
(defn render-block [{:keys [content content-type in-popover?]} acc
|
||||||
{:keys [type ^js literal children]}]
|
{:keys [type ^js literal children]}]
|
||||||
(case type
|
(case type
|
||||||
|
|
||||||
"paragraph"
|
"paragraph"
|
||||||
(conj acc (reduce
|
(conj acc (reduce
|
||||||
(fn [acc e] (render-inline (:text content) outgoing pinned content-type acc e))
|
(fn [acc e] (render-inline (:text content) content-type acc e))
|
||||||
[react/text-class (style/text-style (and outgoing (not pinned)) content-type in-popover?)]
|
[react/text-class (style/text-style content-type in-popover?)]
|
||||||
children))
|
children))
|
||||||
|
|
||||||
"blockquote"
|
"blockquote"
|
||||||
(conj acc [react/view (style/blockquote-style (and outgoing (not pinned)))
|
(conj acc [react/view (style/blockquote-style)
|
||||||
[react/text-class (style/blockquote-text-style (and outgoing (not pinned)))
|
[react/text-class (style/blockquote-text-style)
|
||||||
(.substring literal 0 (.-length literal))]])
|
(.substring literal 0 (.-length literal))]])
|
||||||
|
|
||||||
"codeblock"
|
"codeblock"
|
||||||
|
@ -193,10 +192,10 @@
|
||||||
(defn render-parsed-text [message tree]
|
(defn render-parsed-text [message tree]
|
||||||
(reduce (fn [acc e] (render-block message acc e)) [:<>] tree))
|
(reduce (fn [acc e] (render-block message acc e)) [:<>] tree))
|
||||||
|
|
||||||
(defn render-parsed-text-with-message-status [{:keys [outgoing edited-at in-popover?] :as message} tree]
|
(defn render-parsed-text-with-message-status [{:keys [edited-at in-popover?] :as message} tree]
|
||||||
(let [elements (render-parsed-text message tree)
|
(let [elements (render-parsed-text message tree)
|
||||||
message-status [react/text {:style (style/message-status-placeholder)}
|
message-status [react/text {:style (style/message-status-placeholder)}
|
||||||
(str (if (and outgoing (not in-popover?)) " " " ") (when (and (not in-popover?) edited-at) edited-at-text))]
|
(str (if (not in-popover?) " " " ") (when (and (not in-popover?) edited-at) edited-at-text))]
|
||||||
last-element (peek elements)]
|
last-element (peek elements)]
|
||||||
;; Using `nth` here as slightly faster than `first`, roughly 30%
|
;; Using `nth` here as slightly faster than `first`, roughly 30%
|
||||||
;; It's worth considering pure js structures for this code path as
|
;; It's worth considering pure js structures for this code path as
|
||||||
|
@ -208,10 +207,10 @@
|
||||||
(conj elements message-status))))
|
(conj elements message-status))))
|
||||||
|
|
||||||
(defn unknown-content-type
|
(defn unknown-content-type
|
||||||
[{:keys [outgoing content-type content] :as message}]
|
[{:keys [content-type content] :as message}]
|
||||||
[react/view (style/message-view message)
|
[react/view (style/message-view message)
|
||||||
[react/text
|
[react/text
|
||||||
{:style {:color (if outgoing colors/white-persist colors/black)}}
|
{:style {:color colors/white-persist}}
|
||||||
(if (seq (:text content))
|
(if (seq (:text content))
|
||||||
(:text content)
|
(:text content)
|
||||||
(str "Unhandled content-type " content-type))]])
|
(str "Unhandled content-type " content-type))]])
|
||||||
|
@ -242,8 +241,8 @@
|
||||||
|
|
||||||
(def pin-icon-height 15)
|
(def pin-icon-height 15)
|
||||||
|
|
||||||
(defn pinned-by-indicator [outgoing display-photo? pinned-by]
|
(defn pinned-by-indicator [display-photo? pinned-by]
|
||||||
[react/view {:style (style/pin-indicator outgoing display-photo?)
|
[react/view {:style (style/pin-indicator display-photo?)
|
||||||
:accessibility-label :pinned-by}
|
:accessibility-label :pinned-by}
|
||||||
[react/view {:style (style/pinned-by-text-icon-container)}
|
[react/view {:style (style/pinned-by-text-icon-container)}
|
||||||
[react/view {:style (style/pin-icon-container)}
|
[react/view {:style (style/pin-icon-container)}
|
||||||
|
@ -309,33 +308,40 @@
|
||||||
|
|
||||||
(defn message-content-wrapper
|
(defn message-content-wrapper
|
||||||
"Author, userpic and delivery wrapper"
|
"Author, userpic and delivery wrapper"
|
||||||
[{:keys [first-in-group? display-photo? display-username?
|
[{:keys [last-in-group?
|
||||||
identicon
|
identicon
|
||||||
from outgoing in-popover?]
|
from in-popover? timestamp-str]
|
||||||
:as message} content {:keys [modal close-modal]}]
|
:as message} content {:keys [modal close-modal]}]
|
||||||
[react/view {:style (style/message-wrapper message)
|
[react/view {:style (style/message-wrapper message)
|
||||||
:pointer-events :box-none
|
:pointer-events :box-none
|
||||||
:accessibility-label :chat-item}
|
:accessibility-label :chat-item}
|
||||||
[react/view {:style (style/message-body message)
|
[react/view {:style (style/message-body)
|
||||||
:pointer-events :box-none}
|
:pointer-events :box-none}
|
||||||
(when display-photo?
|
[react/view (style/message-author-userpic)
|
||||||
[react/view (style/message-author-userpic outgoing)
|
(when last-in-group?
|
||||||
(when first-in-group?
|
[react/touchable-highlight {:on-press #(do (when modal (close-modal))
|
||||||
[react/touchable-highlight {:on-press #(do (when modal (close-modal))
|
(re-frame/dispatch [:chat.ui/show-profile from]))}
|
||||||
(re-frame/dispatch [:chat.ui/show-profile from]))}
|
[photos/member-photo from identicon]])]
|
||||||
[photos/member-photo from identicon]])])
|
[react/view {:style (style/message-author-wrapper)}
|
||||||
[react/view {:style (style/message-author-wrapper outgoing display-photo? in-popover?)}
|
(when last-in-group?
|
||||||
(when display-username?
|
[react/view {:style {:flex-direction :row :align-items :center}}
|
||||||
[react/touchable-opacity {:style style/message-author-touchable
|
[react/touchable-opacity {:style style/message-author-touchable
|
||||||
:disabled in-popover?
|
:disabled in-popover?
|
||||||
:on-press #(do (when modal (close-modal))
|
:on-press #(do (when modal (close-modal))
|
||||||
(re-frame/dispatch [:chat.ui/show-profile from]))}
|
(re-frame/dispatch [:chat.ui/show-profile from]))}
|
||||||
[message-author-name from {:modal modal}]])
|
[message-author-name from {:modal modal}]]
|
||||||
|
[react/text
|
||||||
|
{:style (merge
|
||||||
|
{:padding-left 5
|
||||||
|
:margin-top 2}
|
||||||
|
(style/message-timestamp-text))
|
||||||
|
:accessibility-label :message-timestamp}
|
||||||
|
timestamp-str]])
|
||||||
;;MESSAGE CONTENT
|
;;MESSAGE CONTENT
|
||||||
content
|
content
|
||||||
[link-preview/link-preview-wrapper (:links (:content message)) outgoing false]]]
|
[link-preview/link-preview-wrapper (:links (:content message)) false false]]]
|
||||||
; delivery status
|
; delivery status
|
||||||
[react/view (style/delivery-status outgoing)
|
[react/view (style/delivery-status)
|
||||||
[message-delivery-status message]]])
|
[message-delivery-status message]]])
|
||||||
|
|
||||||
(def image-max-width 260)
|
(def image-max-width 260)
|
||||||
|
@ -353,13 +359,13 @@
|
||||||
(swap! dimensions assoc :loaded true)))))
|
(swap! dimensions assoc :loaded true)))))
|
||||||
|
|
||||||
(defn message-content-image
|
(defn message-content-image
|
||||||
[{:keys [content outgoing in-popover?] :as message}
|
[{:keys [content in-popover?] :as message}
|
||||||
{:keys [on-long-press]}]
|
{:keys [on-long-press]}]
|
||||||
(let [dimensions (reagent/atom {:width image-max-width :height image-max-height :loaded false})
|
(let [dimensions (reagent/atom {:width image-max-width :height image-max-height :loaded false})
|
||||||
visible (reagent/atom false)
|
visible (reagent/atom false)
|
||||||
uri (:image content)]
|
uri (:image content)]
|
||||||
(fn []
|
(fn []
|
||||||
(let [style-opts {:outgoing outgoing
|
(let [style-opts {:outgoing false
|
||||||
:opacity (if (:loaded @dimensions) 1 0)
|
:opacity (if (:loaded @dimensions) 1 0)
|
||||||
:width (:width @dimensions)
|
:width (:width @dimensions)
|
||||||
:height (:height @dimensions)}]
|
:height (:height @dimensions)}]
|
||||||
|
@ -405,9 +411,6 @@
|
||||||
[react/view (style/message-view-content)
|
[react/view (style/message-view-content)
|
||||||
[render-parsed-text message (:parsed-text content)]]]]])
|
[render-parsed-text message (:parsed-text content)]]]]])
|
||||||
|
|
||||||
(def message-height-px 200)
|
|
||||||
(def max-message-height-px 150)
|
|
||||||
|
|
||||||
(defn pin-message [{:keys [chat-id pinned] :as message}]
|
(defn pin-message [{:keys [chat-id pinned] :as message}]
|
||||||
(let [pinned-messages @(re-frame/subscribe [:chats/pinned chat-id])]
|
(let [pinned-messages @(re-frame/subscribe [:chats/pinned chat-id])]
|
||||||
(if (and (not pinned) (> (count pinned-messages) 2))
|
(if (and (not pinned) (> (count pinned-messages) 2))
|
||||||
|
@ -443,62 +446,31 @@
|
||||||
:label (i18n/label :t/delete)
|
:label (i18n/label :t/delete)
|
||||||
:id :delete}]))))
|
:id :delete}]))))
|
||||||
|
|
||||||
(defn collapsible-text-message [{:keys [mentioned]} _]
|
(defn collapsible-text-message [_ _]
|
||||||
(let [collapsed? (reagent/atom false)
|
(let [collapsed? (reagent/atom false)
|
||||||
collapsible? (reagent/atom false)
|
|
||||||
show-timestamp? (reagent/atom false)]
|
show-timestamp? (reagent/atom false)]
|
||||||
(fn [{:keys [content outgoing current-public-key public? pinned in-popover?] :as message} on-long-press modal]
|
(fn [{:keys [content current-public-key public? pinned in-popover?] :as message} on-long-press modal]
|
||||||
(let [max-height (when-not (or outgoing modal)
|
[react/touchable-highlight
|
||||||
(if @collapsible?
|
(when-not modal
|
||||||
(if @collapsed? message-height-px nil)
|
{:on-press (fn [_]
|
||||||
message-height-px))]
|
(react/dismiss-keyboard!)
|
||||||
[react/touchable-highlight
|
(reset! show-timestamp? true))
|
||||||
(when-not modal
|
:delay-long-press 100
|
||||||
{:on-press (fn [_]
|
:on-long-press (fn []
|
||||||
(react/dismiss-keyboard!)
|
(if @collapsed?
|
||||||
(reset! show-timestamp? true))
|
(do (reset! collapsed? false)
|
||||||
:delay-long-press 100
|
(js/setTimeout #(on-long-press-fn on-long-press message content) 200))
|
||||||
:on-long-press (fn []
|
(on-long-press-fn on-long-press message content)))
|
||||||
(if @collapsed?
|
:disabled in-popover?})
|
||||||
(do (reset! collapsed? false)
|
[react/view style/message-view-wrapper
|
||||||
(js/setTimeout #(on-long-press-fn on-long-press message content) 200))
|
[message-timestamp message show-timestamp?]
|
||||||
(on-long-press-fn on-long-press message content)))
|
[react/view {:style (style/message-view message)}
|
||||||
:disabled in-popover?})
|
[react/view {:style (style/message-view-content)}
|
||||||
[react/view (style/message-view-wrapper outgoing)
|
(let [response-to (:response-to content)]
|
||||||
[message-timestamp message show-timestamp?]
|
[react/view
|
||||||
[react/view {:style (style/message-view message)}
|
(when (and (seq response-to) (:quoted-message message))
|
||||||
[react/view {:style (style/message-view-content)
|
[quoted-message response-to (:quoted-message message) current-public-key public? pinned])
|
||||||
:max-height max-height}
|
[render-parsed-text-with-message-status message (:parsed-text content)]])]]]])))
|
||||||
(let [response-to (:response-to content)]
|
|
||||||
[react/view {:on-layout
|
|
||||||
#(when (and (> (.-nativeEvent.layout.height ^js %) max-message-height-px)
|
|
||||||
(not @collapsible?)
|
|
||||||
(not outgoing)
|
|
||||||
(not modal))
|
|
||||||
(reset! collapsed? true)
|
|
||||||
(reset! collapsible? true))}
|
|
||||||
(when (and (seq response-to) (:quoted-message message))
|
|
||||||
[quoted-message response-to (:quoted-message message) outgoing current-public-key public? pinned])
|
|
||||||
[render-parsed-text-with-message-status message (:parsed-text content)]])
|
|
||||||
(when-not @collapsible? [message-status message])
|
|
||||||
(when (and @collapsible? (not modal))
|
|
||||||
(if @collapsed?
|
|
||||||
(let [color (if pinned colors/pin-background (if mentioned colors/mentioned-background colors/blue-light))]
|
|
||||||
[react/touchable-highlight
|
|
||||||
{:on-press #(swap! collapsed? not)
|
|
||||||
:style {:position :absolute :bottom 0 :left 0 :right 0 :height 72}}
|
|
||||||
[react/linear-gradient {:colors [(str color "00") color]
|
|
||||||
:start {:x 0 :y 0} :end {:x 0 :y 0.9}}
|
|
||||||
[react/view {:height 72 :align-self :center :justify-content :flex-end
|
|
||||||
:padding-bottom 10}
|
|
||||||
[react/view (style/collapse-button)
|
|
||||||
[icons/icon :main-icons/dropdown
|
|
||||||
{:color colors/white}]]]]])
|
|
||||||
[react/touchable-highlight {:on-press #(swap! collapsed? not)
|
|
||||||
:style {:align-self :center :margin 5}}
|
|
||||||
[react/view (style/collapse-button)
|
|
||||||
[icons/icon :main-icons/dropdown-up
|
|
||||||
{:color colors/white}]]]))]]]]))))
|
|
||||||
|
|
||||||
(defmethod ->message constants/content-type-text
|
(defmethod ->message constants/content-type-text
|
||||||
[message {:keys [on-long-press modal] :as reaction-picker}]
|
[message {:keys [on-long-press modal] :as reaction-picker}]
|
||||||
|
@ -511,12 +483,12 @@
|
||||||
[community-content message])
|
[community-content message])
|
||||||
|
|
||||||
(defmethod ->message constants/content-type-status
|
(defmethod ->message constants/content-type-status
|
||||||
[{:keys [content content-type pinned] :as message}]
|
[{:keys [content content-type] :as message}]
|
||||||
[message-content-wrapper message
|
[message-content-wrapper message
|
||||||
[react/view style/status-container
|
[react/view style/status-container
|
||||||
[react/text {:style (style/status-text)}
|
[react/text {:style (style/status-text)}
|
||||||
(reduce
|
(reduce
|
||||||
(fn [acc e] (render-inline (:text content) false pinned content-type acc e))
|
(fn [acc e] (render-inline (:text content) content-type acc e))
|
||||||
[react/text-class {:style (style/status-text)}]
|
[react/text-class {:style (style/status-text)}]
|
||||||
(-> content :parsed-text peek :children))]]])
|
(-> content :parsed-text peek :children))]]])
|
||||||
|
|
||||||
|
@ -544,11 +516,11 @@
|
||||||
:label (i18n/label :t/sharing-copy-to-clipboard)}]
|
:label (i18n/label :t/sharing-copy-to-clipboard)}]
|
||||||
(when message-pin-enabled [{:on-press #(pin-message message)
|
(when message-pin-enabled [{:on-press #(pin-message message)
|
||||||
:label (if pinned (i18n/label :t/unpin) (i18n/label :t/pin))}]))))})
|
:label (if pinned (i18n/label :t/unpin) (i18n/label :t/pin))}]))))})
|
||||||
[react/view (style/message-view-wrapper outgoing)
|
[react/view style/message-view-wrapper
|
||||||
[message-timestamp message show-timestamp?]
|
[message-timestamp message show-timestamp?]
|
||||||
[react/view (style/message-view message)
|
[react/view (style/message-view message)
|
||||||
[react/view {:style (style/message-view-content)}
|
[react/view {:style (style/message-view-content)}
|
||||||
[react/view {:style (style/style-message-text outgoing)}
|
[react/view {:style (style/style-message-text)}
|
||||||
(when (and (seq response-to) (:quoted-message message))
|
(when (and (seq response-to) (:quoted-message message))
|
||||||
[quoted-message response-to (:quoted-message message) outgoing current-public-key public? pinned])
|
[quoted-message response-to (:quoted-message message) outgoing current-public-key public? pinned])
|
||||||
[react/text {:style (style/emoji-message message)}
|
[react/text {:style (style/emoji-message message)}
|
||||||
|
@ -624,7 +596,7 @@
|
||||||
[])))
|
[])))
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(reset! show-timestamp? true))})
|
(reset! show-timestamp? true))})
|
||||||
[react/view (style/message-view-wrapper (:outgoing message))
|
[react/view style/message-view-wrapper
|
||||||
[message-timestamp message show-timestamp?]
|
[message-timestamp message show-timestamp?]
|
||||||
[react/view {:style (style/message-view message) :accessibility-label :audio-message}
|
[react/view {:style (style/message-view message) :accessibility-label :audio-message}
|
||||||
[react/view {:style (style/message-view-content)}
|
[react/view {:style (style/message-view-content)}
|
||||||
|
@ -659,8 +631,8 @@
|
||||||
constants/contact-request-message-state-declined [contact-request-status-declined])])
|
constants/contact-request-message-state-declined [contact-request-status-declined])])
|
||||||
|
|
||||||
(defmethod ->message constants/content-type-contact-request
|
(defmethod ->message constants/content-type-contact-request
|
||||||
[{:keys [outgoing] :as message} _]
|
[message _]
|
||||||
[react/view {:style (style/content-type-contact-request outgoing)}
|
[react/view {:style (style/content-type-contact-request)}
|
||||||
[react/image {:source (resources/get-image :hand-wave)
|
[react/image {:source (resources/get-image :hand-wave)
|
||||||
:style {:width 112
|
:style {:width 112
|
||||||
:height 97}}]
|
:height 97}}]
|
||||||
|
@ -678,7 +650,7 @@
|
||||||
[message-content-wrapper message
|
[message-content-wrapper message
|
||||||
[unknown-content-type message]])
|
[unknown-content-type message]])
|
||||||
|
|
||||||
(defn chat-message [{:keys [outgoing display-photo? pinned pinned-by] :as message} space-keeper]
|
(defn chat-message [{:keys [display-photo? pinned pinned-by] :as message} space-keeper]
|
||||||
[:<>
|
[:<>
|
||||||
[reactions/with-reaction-picker
|
[reactions/with-reaction-picker
|
||||||
{:message message
|
{:message message
|
||||||
|
@ -698,5 +670,5 @@
|
||||||
:emoji-reaction-id emoji-reaction-id}]))
|
:emoji-reaction-id emoji-reaction-id}]))
|
||||||
:render ->message}]
|
:render ->message}]
|
||||||
(when pinned
|
(when pinned
|
||||||
[react/view {:style (style/pin-indicator-container outgoing)}
|
[react/view {:style (style/pin-indicator-container)}
|
||||||
[pinned-by-indicator outgoing display-photo? pinned-by]])])
|
[pinned-by-indicator display-photo? pinned-by]])])
|
||||||
|
|
|
@ -0,0 +1,702 @@
|
||||||
|
(ns status-im.ui.screens.chat.message.message-old
|
||||||
|
(:require [re-frame.core :as re-frame]
|
||||||
|
[status-im.constants :as constants]
|
||||||
|
[status-im.i18n.i18n :as i18n]
|
||||||
|
[status-im.react-native.resources :as resources]
|
||||||
|
[quo.design-system.colors :as colors]
|
||||||
|
[status-im.ui.components.icons.icons :as icons]
|
||||||
|
[status-im.ui.components.react :as react]
|
||||||
|
[status-im.ui.screens.chat.message.audio-old :as message.audio]
|
||||||
|
[status-im.chat.models.reactions :as models.reactions]
|
||||||
|
[status-im.ui.screens.chat.message.command :as message.command]
|
||||||
|
[status-im.ui.screens.chat.photos :as photos]
|
||||||
|
[status-im.ui.screens.chat.sheets :as sheets]
|
||||||
|
[status-im.ui.screens.chat.message.gap :as message.gap]
|
||||||
|
[status-im.ui.screens.chat.styles.message.message-old :as style]
|
||||||
|
[status-im.ui.screens.chat.utils :as chat.utils]
|
||||||
|
[status-im.utils.security :as security]
|
||||||
|
[status-im.ui.screens.chat.message.reactions :as reactions]
|
||||||
|
[status-im.ui.screens.chat.image.preview.views :as preview]
|
||||||
|
[quo.core :as quo]
|
||||||
|
[status-im.utils.config :as config]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[status-im.ui.screens.chat.components.reply :as components.reply]
|
||||||
|
[status-im.ui.screens.chat.message.link-preview :as link-preview]
|
||||||
|
[status-im.ui.screens.communities.icon :as communities.icon]
|
||||||
|
[status-im.ui.components.animation :as animation]
|
||||||
|
[status-im.chat.models.images :as images]
|
||||||
|
[status-im.chat.models.pin-message :as models.pin-message]
|
||||||
|
[status-im.ui.components.fast-image :as fast-image])
|
||||||
|
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||||
|
|
||||||
|
(defn message-timestamp-anim
|
||||||
|
[anim-opacity show-timestamp?]
|
||||||
|
(animation/start
|
||||||
|
(animation/anim-sequence
|
||||||
|
[(animation/timing
|
||||||
|
anim-opacity
|
||||||
|
{:toValue 1
|
||||||
|
:duration 100
|
||||||
|
:easing (.-ease ^js animation/easing)
|
||||||
|
:useNativeDriver true})
|
||||||
|
(animation/timing
|
||||||
|
anim-opacity
|
||||||
|
{:toValue 0
|
||||||
|
:delay 2000
|
||||||
|
:duration 100
|
||||||
|
:easing (.-ease ^js animation/easing)
|
||||||
|
:useNativeDriver true})]) #(reset! show-timestamp? false)))
|
||||||
|
|
||||||
|
(defview mention-element [from]
|
||||||
|
(letsubs [contact-name [:contacts/contact-name-by-identity from]]
|
||||||
|
contact-name))
|
||||||
|
|
||||||
|
(def edited-at-text (str " ⌫ " (i18n/label :t/edited)))
|
||||||
|
|
||||||
|
(defn message-status [{:keys [outgoing content outgoing-status pinned edited-at in-popover?]}]
|
||||||
|
(when-not in-popover? ;; We keep track if showing this message in a list in pin-limit-popover
|
||||||
|
[react/view
|
||||||
|
{:align-self :flex-end
|
||||||
|
:position :absolute
|
||||||
|
:bottom 9 ; 6 Bubble bottom, 3 message baseline
|
||||||
|
(if (:rtl? content) :left :right) 0
|
||||||
|
:flex-direction :row
|
||||||
|
:align-items :flex-end}
|
||||||
|
(when outgoing
|
||||||
|
[icons/icon (case outgoing-status
|
||||||
|
:sending :tiny-icons/tiny-pending
|
||||||
|
:sent :tiny-icons/tiny-sent
|
||||||
|
:not-sent :tiny-icons/tiny-warning
|
||||||
|
:delivered :tiny-icons/tiny-delivered
|
||||||
|
:tiny-icons/tiny-pending)
|
||||||
|
{:width 16
|
||||||
|
:height 12
|
||||||
|
:color (if pinned colors/gray colors/white)
|
||||||
|
:accessibility-label (name outgoing-status)}])
|
||||||
|
(when edited-at [react/text {:style (style/message-status-text (and outgoing (not pinned)))} edited-at-text])]))
|
||||||
|
|
||||||
|
(defn message-timestamp
|
||||||
|
[{:keys [timestamp-str in-popover?] :as message} show-timestamp?]
|
||||||
|
(when-not in-popover? ;; We keep track if showing this message in a list in pin-limit-popover
|
||||||
|
(let [anim-opacity (animation/create-value 0)]
|
||||||
|
[react/animated-view {:style (style/message-timestamp-wrapper message) :opacity anim-opacity}
|
||||||
|
(when @show-timestamp? (message-timestamp-anim anim-opacity show-timestamp?))
|
||||||
|
[react/text
|
||||||
|
{:style (style/message-timestamp-text)
|
||||||
|
:accessibility-label :message-timestamp}
|
||||||
|
timestamp-str]])))
|
||||||
|
|
||||||
|
(defview quoted-message
|
||||||
|
[_ {:keys [from parsed-text image]} outgoing current-public-key public? pinned]
|
||||||
|
(letsubs [contact-name [:contacts/contact-name-by-identity from]]
|
||||||
|
[react/view {:style (style/quoted-message-container (and outgoing (not pinned)))}
|
||||||
|
[react/view {:style style/quoted-message-author-container}
|
||||||
|
[chat.utils/format-reply-author
|
||||||
|
from
|
||||||
|
contact-name
|
||||||
|
current-public-key
|
||||||
|
(partial style/quoted-message-author (and outgoing (not pinned)))
|
||||||
|
(and outgoing (not pinned))]]
|
||||||
|
(if (and image
|
||||||
|
;; Disabling images for public-chats
|
||||||
|
(not public?))
|
||||||
|
[fast-image/fast-image {:style {:width 56
|
||||||
|
:height 56
|
||||||
|
:background-color :black
|
||||||
|
:border-radius 4}
|
||||||
|
:source {:uri image}}]
|
||||||
|
[react/text {:style (style/quoted-message-text (and outgoing (not pinned)))
|
||||||
|
:number-of-lines 5}
|
||||||
|
(components.reply/get-quoted-text-with-mentions parsed-text)])]))
|
||||||
|
|
||||||
|
(defn render-inline [message-text outgoing pinned content-type acc {:keys [type literal destination]}]
|
||||||
|
(case type
|
||||||
|
""
|
||||||
|
(conj acc literal)
|
||||||
|
|
||||||
|
"code"
|
||||||
|
(conj acc [quo/text {:max-font-size-multiplier react/max-font-size-multiplier
|
||||||
|
:style (style/inline-code-style)
|
||||||
|
:monospace true}
|
||||||
|
literal])
|
||||||
|
|
||||||
|
"emph"
|
||||||
|
(conj acc [react/text-class (style/emph-style (and outgoing (not pinned))) literal])
|
||||||
|
|
||||||
|
"strong"
|
||||||
|
(conj acc [react/text-class (style/strong-style (and outgoing (not pinned))) literal])
|
||||||
|
|
||||||
|
"strong-emph"
|
||||||
|
(conj acc [quo/text (style/strong-emph-style (and outgoing (not pinned))) literal])
|
||||||
|
|
||||||
|
"del"
|
||||||
|
(conj acc [react/text-class (style/strikethrough-style (and outgoing (not pinned))) literal])
|
||||||
|
|
||||||
|
"link"
|
||||||
|
(conj acc
|
||||||
|
[react/text-class
|
||||||
|
{:style
|
||||||
|
{:color (if (and outgoing (not pinned)) colors/white-persist colors/blue)
|
||||||
|
:text-decoration-line :underline}
|
||||||
|
:on-press
|
||||||
|
#(when (and (security/safe-link? destination)
|
||||||
|
(security/safe-link-text? message-text))
|
||||||
|
(re-frame/dispatch
|
||||||
|
[:browser.ui/message-link-pressed destination]))}
|
||||||
|
destination])
|
||||||
|
|
||||||
|
"mention"
|
||||||
|
(conj acc [react/text-class
|
||||||
|
{:style {:color (cond
|
||||||
|
(= content-type constants/content-type-system-text) colors/black
|
||||||
|
(and outgoing (not pinned)) colors/mention-outgoing
|
||||||
|
:else colors/mention-incoming)}
|
||||||
|
:on-press (when-not (= content-type constants/content-type-system-text)
|
||||||
|
#(re-frame/dispatch [:chat.ui/show-profile literal]))}
|
||||||
|
[mention-element literal]])
|
||||||
|
"status-tag"
|
||||||
|
(conj acc [react/text-class
|
||||||
|
{:style {:color (if (and outgoing (not pinned)) colors/white-persist colors/blue)
|
||||||
|
:text-decoration-line :underline}
|
||||||
|
:on-press
|
||||||
|
#(re-frame/dispatch
|
||||||
|
[:chat.ui/start-public-chat literal])}
|
||||||
|
"#"
|
||||||
|
literal])
|
||||||
|
|
||||||
|
(conj acc literal)))
|
||||||
|
|
||||||
|
(defn render-block [{:keys [content outgoing content-type pinned in-popover?]} acc
|
||||||
|
{:keys [type ^js literal children]}]
|
||||||
|
(case type
|
||||||
|
|
||||||
|
"paragraph"
|
||||||
|
(conj acc (reduce
|
||||||
|
(fn [acc e] (render-inline (:text content) outgoing pinned content-type acc e))
|
||||||
|
[react/text-class (style/text-style (and outgoing (not pinned)) content-type in-popover?)]
|
||||||
|
children))
|
||||||
|
|
||||||
|
"blockquote"
|
||||||
|
(conj acc [react/view (style/blockquote-style (and outgoing (not pinned)))
|
||||||
|
[react/text-class (style/blockquote-text-style (and outgoing (not pinned)))
|
||||||
|
(.substring literal 0 (.-length literal))]])
|
||||||
|
|
||||||
|
"codeblock"
|
||||||
|
(conj acc [react/view {:style style/codeblock-style}
|
||||||
|
[quo/text {:max-font-size-multiplier react/max-font-size-multiplier
|
||||||
|
:style style/codeblock-text-style
|
||||||
|
:monospace true}
|
||||||
|
(.substring literal 0 (dec (.-length literal)))]])
|
||||||
|
|
||||||
|
acc))
|
||||||
|
|
||||||
|
(defn render-parsed-text [message tree]
|
||||||
|
(reduce (fn [acc e] (render-block message acc e)) [:<>] tree))
|
||||||
|
|
||||||
|
(defn render-parsed-text-with-message-status [{:keys [outgoing edited-at in-popover?] :as message} tree]
|
||||||
|
(let [elements (render-parsed-text message tree)
|
||||||
|
message-status [react/text {:style (style/message-status-placeholder)}
|
||||||
|
(str (if (and outgoing (not in-popover?)) " " " ") (when (and (not in-popover?) edited-at) edited-at-text))]
|
||||||
|
last-element (peek elements)]
|
||||||
|
;; Using `nth` here as slightly faster than `first`, roughly 30%
|
||||||
|
;; It's worth considering pure js structures for this code path as
|
||||||
|
;; it's perfomance critical
|
||||||
|
(if (= react/text-class (nth last-element 0))
|
||||||
|
;; Append message status to last text
|
||||||
|
(conj (pop elements) (conj last-element message-status))
|
||||||
|
;; Append message status to new block
|
||||||
|
(conj elements message-status))))
|
||||||
|
|
||||||
|
(defn unknown-content-type
|
||||||
|
[{:keys [outgoing content-type content] :as message}]
|
||||||
|
[react/view (style/message-view message)
|
||||||
|
[react/text
|
||||||
|
{:style {:color (if outgoing colors/white-persist colors/black)}}
|
||||||
|
(if (seq (:text content))
|
||||||
|
(:text content)
|
||||||
|
(str "Unhandled content-type " content-type))]])
|
||||||
|
|
||||||
|
(defn message-not-sent-text
|
||||||
|
[chat-id message-id]
|
||||||
|
[react/touchable-highlight
|
||||||
|
{:on-press
|
||||||
|
(fn []
|
||||||
|
(re-frame/dispatch
|
||||||
|
[:bottom-sheet/show-sheet
|
||||||
|
{:content (sheets/options chat-id message-id)
|
||||||
|
:content-height 200}])
|
||||||
|
(react/dismiss-keyboard!))}
|
||||||
|
[react/view style/not-sent-view
|
||||||
|
[react/text {:style style/not-sent-text}
|
||||||
|
(i18n/label :t/status-not-sent-tap)]
|
||||||
|
[react/view style/not-sent-icon
|
||||||
|
[icons/icon :main-icons/warning {:color colors/red}]]]])
|
||||||
|
|
||||||
|
(defn pin-author-name [pinned-by]
|
||||||
|
(let [user-contact @(re-frame/subscribe [:multiaccount/contact])
|
||||||
|
contact-names @(re-frame/subscribe [:contacts/contact-two-names-by-identity pinned-by])]
|
||||||
|
;; We append empty spaces to the name as a workaround to make one-line and multi-line label components show correctly
|
||||||
|
(str " " (if (= pinned-by (user-contact :public-key)) (i18n/label :t/You) (first contact-names)))))
|
||||||
|
|
||||||
|
(def pin-icon-width 9)
|
||||||
|
|
||||||
|
(def pin-icon-height 15)
|
||||||
|
|
||||||
|
(defn pinned-by-indicator [outgoing display-photo? pinned-by]
|
||||||
|
[react/view {:style (style/pin-indicator outgoing display-photo?)
|
||||||
|
:accessibility-label :pinned-by}
|
||||||
|
[react/view {:style (style/pinned-by-text-icon-container)}
|
||||||
|
[react/view {:style (style/pin-icon-container)}
|
||||||
|
[icons/icon :main-icons/pin {:color colors/gray
|
||||||
|
:height pin-icon-height
|
||||||
|
:width pin-icon-width
|
||||||
|
:background-color :red}]]
|
||||||
|
[quo/text {:weight :regular
|
||||||
|
:size :small
|
||||||
|
:color :main
|
||||||
|
:style (style/pinned-by-text)}
|
||||||
|
(i18n/label :t/pinned-by)]]
|
||||||
|
[quo/text {:weight :medium
|
||||||
|
:size :small
|
||||||
|
:color :main
|
||||||
|
:style (style/pin-author-text)}
|
||||||
|
(pin-author-name pinned-by)]])
|
||||||
|
|
||||||
|
(defn message-delivery-status
|
||||||
|
[{:keys [chat-id message-id outgoing-status message-type]}]
|
||||||
|
(when (and (not= constants/message-type-private-group-system-message message-type)
|
||||||
|
(= outgoing-status :not-sent))
|
||||||
|
[message-not-sent-text chat-id message-id]))
|
||||||
|
|
||||||
|
(defview message-author-name [from opts]
|
||||||
|
(letsubs [contact-with-names [:contacts/contact-by-identity from]]
|
||||||
|
(chat.utils/format-author-old contact-with-names opts)))
|
||||||
|
|
||||||
|
(defview message-my-name [opts]
|
||||||
|
(letsubs [contact-with-names [:multiaccount/contact]]
|
||||||
|
(chat.utils/format-author-old contact-with-names opts)))
|
||||||
|
|
||||||
|
(defview community-content [{:keys [community-id] :as message}]
|
||||||
|
(letsubs [{:keys [name description verified] :as community} [:communities/community community-id]
|
||||||
|
communities-enabled? [:communities/enabled?]]
|
||||||
|
(when (and communities-enabled? community)
|
||||||
|
[react/view {:style (assoc (style/message-wrapper message)
|
||||||
|
:margin-vertical 10
|
||||||
|
:margin-left 8
|
||||||
|
:width 271)}
|
||||||
|
(when verified
|
||||||
|
[react/view (style/community-verified)
|
||||||
|
[react/text {:style {:font-size 13
|
||||||
|
:color colors/blue}} (i18n/label :t/communities-verified)]])
|
||||||
|
[react/view (style/community-message verified)
|
||||||
|
[react/view {:width 62
|
||||||
|
:padding-left 14}
|
||||||
|
(if (= community-id constants/status-community-id)
|
||||||
|
[react/image {:source (resources/get-image :status-logo)
|
||||||
|
:style {:width 40
|
||||||
|
:height 40}}]
|
||||||
|
[communities.icon/community-icon community])]
|
||||||
|
[react/view {:padding-right 14 :flex 1}
|
||||||
|
[react/text {:style {:font-weight "700" :font-size 17}}
|
||||||
|
name]
|
||||||
|
[react/text description]]]
|
||||||
|
[react/view (style/community-view-button)
|
||||||
|
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to
|
||||||
|
:community
|
||||||
|
{:community-id (:id community)}])}
|
||||||
|
[react/text {:style {:text-align :center
|
||||||
|
:color colors/blue}} (i18n/label :t/view)]]]])))
|
||||||
|
|
||||||
|
(defn message-content-wrapper
|
||||||
|
"Author, userpic and delivery wrapper"
|
||||||
|
[{:keys [first-in-group? display-photo? display-username?
|
||||||
|
identicon
|
||||||
|
from outgoing in-popover?]
|
||||||
|
:as message} content {:keys [modal close-modal]}]
|
||||||
|
[react/view {:style (style/message-wrapper message)
|
||||||
|
:pointer-events :box-none
|
||||||
|
:accessibility-label :chat-item}
|
||||||
|
[react/view {:style (style/message-body message)
|
||||||
|
:pointer-events :box-none}
|
||||||
|
(when display-photo?
|
||||||
|
[react/view (style/message-author-userpic outgoing)
|
||||||
|
(when first-in-group?
|
||||||
|
[react/touchable-highlight {:on-press #(do (when modal (close-modal))
|
||||||
|
(re-frame/dispatch [:chat.ui/show-profile from]))}
|
||||||
|
[photos/member-photo from identicon]])])
|
||||||
|
[react/view {:style (style/message-author-wrapper outgoing display-photo? in-popover?)}
|
||||||
|
(when display-username?
|
||||||
|
[react/touchable-opacity {:style style/message-author-touchable
|
||||||
|
:disabled in-popover?
|
||||||
|
:on-press #(do (when modal (close-modal))
|
||||||
|
(re-frame/dispatch [:chat.ui/show-profile from]))}
|
||||||
|
[message-author-name from {:modal modal}]])
|
||||||
|
;;MESSAGE CONTENT
|
||||||
|
content
|
||||||
|
[link-preview/link-preview-wrapper (:links (:content message)) outgoing false]]]
|
||||||
|
; delivery status
|
||||||
|
[react/view (style/delivery-status outgoing)
|
||||||
|
[message-delivery-status message]]])
|
||||||
|
|
||||||
|
(def image-max-width 260)
|
||||||
|
(def image-max-height 192)
|
||||||
|
|
||||||
|
(defn image-set-size [dimensions]
|
||||||
|
(fn [evt]
|
||||||
|
(let [width (.-width (.-nativeEvent evt))
|
||||||
|
height (.-height (.-nativeEvent evt))]
|
||||||
|
(if (< width height)
|
||||||
|
;; if width less than the height we reduce width proportionally to height
|
||||||
|
(let [k (/ height image-max-height)]
|
||||||
|
(when (not= (/ width k) (first @dimensions))
|
||||||
|
(reset! dimensions {:width (/ width k) :height image-max-height :loaded true})))
|
||||||
|
(swap! dimensions assoc :loaded true)))))
|
||||||
|
|
||||||
|
(defn message-content-image
|
||||||
|
[{:keys [content outgoing in-popover?] :as message}
|
||||||
|
{:keys [on-long-press]}]
|
||||||
|
(let [dimensions (reagent/atom {:width image-max-width :height image-max-height :loaded false})
|
||||||
|
visible (reagent/atom false)
|
||||||
|
uri (:image content)]
|
||||||
|
(fn []
|
||||||
|
(let [style-opts {:outgoing outgoing
|
||||||
|
:opacity (if (:loaded @dimensions) 1 0)
|
||||||
|
:width (:width @dimensions)
|
||||||
|
:height (:height @dimensions)}]
|
||||||
|
[:<>
|
||||||
|
[preview/preview-image {:message message
|
||||||
|
:visible @visible
|
||||||
|
:on-close #(do (reset! visible false)
|
||||||
|
(reagent/flush))}]
|
||||||
|
[react/touchable-highlight {:on-press (fn []
|
||||||
|
(reset! visible true)
|
||||||
|
(react/dismiss-keyboard!))
|
||||||
|
:on-long-press on-long-press
|
||||||
|
:disabled in-popover?}
|
||||||
|
[react/view {:style (style/image-message style-opts)
|
||||||
|
:accessibility-label :image-message}
|
||||||
|
(when (or (:error @dimensions) (not (:loaded @dimensions)))
|
||||||
|
[react/view
|
||||||
|
(merge (dissoc style-opts :opacity)
|
||||||
|
{:flex 1 :align-items :center :justify-content :center :position :absolute})
|
||||||
|
(if (:error @dimensions)
|
||||||
|
[icons/icon :main-icons/cancel]
|
||||||
|
[react/activity-indicator {:animating true}])])
|
||||||
|
[fast-image/fast-image {:style (dissoc style-opts :outgoing)
|
||||||
|
:on-load (image-set-size dimensions)
|
||||||
|
:on-error #(swap! dimensions assoc :error true)
|
||||||
|
:source {:uri uri}}]
|
||||||
|
[react/view {:style (style/image-message-border style-opts)}]]]]))))
|
||||||
|
|
||||||
|
(defmulti ->message :content-type)
|
||||||
|
|
||||||
|
(defmethod ->message constants/content-type-command
|
||||||
|
[message]
|
||||||
|
[message.command/command-content message-content-wrapper message])
|
||||||
|
|
||||||
|
(defmethod ->message constants/content-type-gap
|
||||||
|
[message]
|
||||||
|
[message.gap/gap message])
|
||||||
|
|
||||||
|
(defmethod ->message constants/content-type-system-text [{:keys [content] :as message}]
|
||||||
|
[react/view {:accessibility-label :chat-item}
|
||||||
|
[react/view (style/system-message-body message)
|
||||||
|
[react/view (style/message-view message)
|
||||||
|
[react/view (style/message-view-content)
|
||||||
|
[render-parsed-text message (:parsed-text content)]]]]])
|
||||||
|
|
||||||
|
(def message-height-px 200)
|
||||||
|
(def max-message-height-px 150)
|
||||||
|
|
||||||
|
(defn pin-message [{:keys [chat-id pinned] :as message}]
|
||||||
|
(let [pinned-messages @(re-frame/subscribe [:chats/pinned chat-id])]
|
||||||
|
(if (and (not pinned) (> (count pinned-messages) 2))
|
||||||
|
(do
|
||||||
|
(js/setTimeout (fn [] (re-frame/dispatch [:dismiss-keyboard])) 500)
|
||||||
|
(re-frame/dispatch [:show-popover {:view :pin-limit
|
||||||
|
:message message
|
||||||
|
:prevent-closing? true}]))
|
||||||
|
(re-frame/dispatch [::models.pin-message/send-pin-message (assoc message :pinned (not pinned))]))))
|
||||||
|
|
||||||
|
(defn on-long-press-fn [on-long-press {:keys [pinned message-pin-enabled outgoing edit-enabled show-input?] :as message} content]
|
||||||
|
(on-long-press
|
||||||
|
(concat
|
||||||
|
(when (and outgoing edit-enabled)
|
||||||
|
[{:on-press #(re-frame/dispatch [:chat.ui/edit-message message])
|
||||||
|
:label (i18n/label :t/edit)
|
||||||
|
:id :edit}])
|
||||||
|
(when show-input?
|
||||||
|
[{:on-press #(re-frame/dispatch [:chat.ui/reply-to-message message])
|
||||||
|
:label (i18n/label :t/message-reply)
|
||||||
|
:id :reply}])
|
||||||
|
[{:on-press #(react/copy-to-clipboard
|
||||||
|
(components.reply/get-quoted-text-with-mentions
|
||||||
|
(get content :parsed-text)))
|
||||||
|
:label (i18n/label :t/sharing-copy-to-clipboard)
|
||||||
|
:id :copy}]
|
||||||
|
(when message-pin-enabled
|
||||||
|
[{:on-press #(pin-message message)
|
||||||
|
:label (if pinned (i18n/label :t/unpin) (i18n/label :t/pin))
|
||||||
|
:id (if pinned :unpin :pin)}])
|
||||||
|
(when (and outgoing config/delete-message-enabled?)
|
||||||
|
[{:on-press #(re-frame/dispatch [:chat.ui/soft-delete-message message])
|
||||||
|
:label (i18n/label :t/delete)
|
||||||
|
:id :delete}]))))
|
||||||
|
|
||||||
|
(defn collapsible-text-message [{:keys [mentioned]} _]
|
||||||
|
(let [collapsed? (reagent/atom false)
|
||||||
|
collapsible? (reagent/atom false)
|
||||||
|
show-timestamp? (reagent/atom false)]
|
||||||
|
(fn [{:keys [content outgoing current-public-key public? pinned in-popover?] :as message} on-long-press modal]
|
||||||
|
(let [max-height (when-not (or outgoing modal)
|
||||||
|
(if @collapsible?
|
||||||
|
(if @collapsed? message-height-px nil)
|
||||||
|
message-height-px))]
|
||||||
|
[react/touchable-highlight
|
||||||
|
(when-not modal
|
||||||
|
{:on-press (fn [_]
|
||||||
|
(react/dismiss-keyboard!)
|
||||||
|
(reset! show-timestamp? true))
|
||||||
|
:delay-long-press 100
|
||||||
|
:on-long-press (fn []
|
||||||
|
(if @collapsed?
|
||||||
|
(do (reset! collapsed? false)
|
||||||
|
(js/setTimeout #(on-long-press-fn on-long-press message content) 200))
|
||||||
|
(on-long-press-fn on-long-press message content)))
|
||||||
|
:disabled in-popover?})
|
||||||
|
[react/view (style/message-view-wrapper outgoing)
|
||||||
|
[message-timestamp message show-timestamp?]
|
||||||
|
[react/view {:style (style/message-view message)}
|
||||||
|
[react/view {:style (style/message-view-content)
|
||||||
|
:max-height max-height}
|
||||||
|
(let [response-to (:response-to content)]
|
||||||
|
[react/view {:on-layout
|
||||||
|
#(when (and (> (.-nativeEvent.layout.height ^js %) max-message-height-px)
|
||||||
|
(not @collapsible?)
|
||||||
|
(not outgoing)
|
||||||
|
(not modal))
|
||||||
|
(reset! collapsed? true)
|
||||||
|
(reset! collapsible? true))}
|
||||||
|
(when (and (seq response-to) (:quoted-message message))
|
||||||
|
[quoted-message response-to (:quoted-message message) outgoing current-public-key public? pinned])
|
||||||
|
[render-parsed-text-with-message-status message (:parsed-text content)]])
|
||||||
|
(when-not @collapsible? [message-status message])
|
||||||
|
(when (and @collapsible? (not modal))
|
||||||
|
(if @collapsed?
|
||||||
|
(let [color (if pinned colors/pin-background (if mentioned colors/mentioned-background colors/blue-light))]
|
||||||
|
[react/touchable-highlight
|
||||||
|
{:on-press #(swap! collapsed? not)
|
||||||
|
:style {:position :absolute :bottom 0 :left 0 :right 0 :height 72}}
|
||||||
|
[react/linear-gradient {:colors [(str color "00") color]
|
||||||
|
:start {:x 0 :y 0} :end {:x 0 :y 0.9}}
|
||||||
|
[react/view {:height 72 :align-self :center :justify-content :flex-end
|
||||||
|
:padding-bottom 10}
|
||||||
|
[react/view (style/collapse-button)
|
||||||
|
[icons/icon :main-icons/dropdown
|
||||||
|
{:color colors/white}]]]]])
|
||||||
|
[react/touchable-highlight {:on-press #(swap! collapsed? not)
|
||||||
|
:style {:align-self :center :margin 5}}
|
||||||
|
[react/view (style/collapse-button)
|
||||||
|
[icons/icon :main-icons/dropdown-up
|
||||||
|
{:color colors/white}]]]))]]]]))))
|
||||||
|
|
||||||
|
(defmethod ->message constants/content-type-text
|
||||||
|
[message {:keys [on-long-press modal] :as reaction-picker}]
|
||||||
|
[message-content-wrapper message
|
||||||
|
[collapsible-text-message message on-long-press modal]
|
||||||
|
reaction-picker])
|
||||||
|
|
||||||
|
(defmethod ->message constants/content-type-community
|
||||||
|
[message]
|
||||||
|
[community-content message])
|
||||||
|
|
||||||
|
(defmethod ->message constants/content-type-status
|
||||||
|
[{:keys [content content-type pinned] :as message}]
|
||||||
|
[message-content-wrapper message
|
||||||
|
[react/view style/status-container
|
||||||
|
[react/text {:style (style/status-text)}
|
||||||
|
(reduce
|
||||||
|
(fn [acc e] (render-inline (:text content) false pinned content-type acc e))
|
||||||
|
[react/text-class {:style (style/status-text)}]
|
||||||
|
(-> content :parsed-text peek :children))]]])
|
||||||
|
|
||||||
|
(defmethod ->message constants/content-type-emoji []
|
||||||
|
(let [show-timestamp? (reagent/atom false)]
|
||||||
|
(fn [{:keys [content current-public-key outgoing public? pinned in-popover? message-pin-enabled] :as message}
|
||||||
|
{:keys [on-long-press modal]
|
||||||
|
:as reaction-picker}]
|
||||||
|
(let [response-to (:response-to content)]
|
||||||
|
[message-content-wrapper message
|
||||||
|
[react/touchable-highlight (when-not modal
|
||||||
|
{:disabled in-popover?
|
||||||
|
:on-press (fn []
|
||||||
|
(react/dismiss-keyboard!)
|
||||||
|
(reset! show-timestamp? true))
|
||||||
|
:delay-long-press 100
|
||||||
|
:on-long-press (fn []
|
||||||
|
(on-long-press
|
||||||
|
(concat
|
||||||
|
[{:on-press #(re-frame/dispatch [:chat.ui/reply-to-message message])
|
||||||
|
:id :reply
|
||||||
|
:label (i18n/label :t/message-reply)}
|
||||||
|
{:on-press #(react/copy-to-clipboard (get content :text))
|
||||||
|
:id :copy
|
||||||
|
:label (i18n/label :t/sharing-copy-to-clipboard)}]
|
||||||
|
(when message-pin-enabled [{:on-press #(pin-message message)
|
||||||
|
:label (if pinned (i18n/label :t/unpin) (i18n/label :t/pin))}]))))})
|
||||||
|
[react/view (style/message-view-wrapper outgoing)
|
||||||
|
[message-timestamp message show-timestamp?]
|
||||||
|
[react/view (style/message-view message)
|
||||||
|
[react/view {:style (style/message-view-content)}
|
||||||
|
[react/view {:style (style/style-message-text outgoing)}
|
||||||
|
(when (and (seq response-to) (:quoted-message message))
|
||||||
|
[quoted-message response-to (:quoted-message message) outgoing current-public-key public? pinned])
|
||||||
|
[react/text {:style (style/emoji-message message)}
|
||||||
|
(:text content)]]
|
||||||
|
[message-status message]]]]]
|
||||||
|
reaction-picker]))))
|
||||||
|
|
||||||
|
(defmethod ->message constants/content-type-sticker
|
||||||
|
[{:keys [content from outgoing in-popover?]
|
||||||
|
:as message}
|
||||||
|
{:keys [on-long-press modal]
|
||||||
|
:as reaction-picker}]
|
||||||
|
(let [pack (get-in content [:sticker :pack])]
|
||||||
|
[message-content-wrapper message
|
||||||
|
[react/touchable-highlight (when-not modal
|
||||||
|
{:disabled in-popover?
|
||||||
|
:accessibility-label :sticker-message
|
||||||
|
:on-press (fn [_]
|
||||||
|
(when pack
|
||||||
|
(re-frame/dispatch [:stickers/open-sticker-pack (str pack)]))
|
||||||
|
(react/dismiss-keyboard!))
|
||||||
|
:delay-long-press 100
|
||||||
|
:on-long-press (fn []
|
||||||
|
(on-long-press
|
||||||
|
(when-not outgoing
|
||||||
|
[{:on-press #(when pack
|
||||||
|
(re-frame/dispatch [:chat.ui/show-profile from]))
|
||||||
|
:label (i18n/label :t/view-details)}])))})
|
||||||
|
[fast-image/fast-image {:style {:margin 10 :width 140 :height 140}
|
||||||
|
:source {:uri (str (-> content :sticker :url) "&download=true")}}]]
|
||||||
|
reaction-picker]))
|
||||||
|
|
||||||
|
(defmethod ->message constants/content-type-image
|
||||||
|
[{:keys [content in-popover? outgoing] :as message}
|
||||||
|
{:keys [on-long-press modal]
|
||||||
|
:as reaction-picker}]
|
||||||
|
[message-content-wrapper message
|
||||||
|
[message-content-image message
|
||||||
|
{:modal modal
|
||||||
|
:disabled in-popover?
|
||||||
|
:delay-long-press 100
|
||||||
|
:on-long-press (fn []
|
||||||
|
(on-long-press
|
||||||
|
(concat [{:on-press #(re-frame/dispatch [:chat.ui/reply-to-message message])
|
||||||
|
:id :reply
|
||||||
|
:label (i18n/label :t/message-reply)}
|
||||||
|
{:on-press #(re-frame/dispatch [:chat.ui/save-image-to-gallery (:image content)])
|
||||||
|
:id :save
|
||||||
|
:label (i18n/label :t/save)}
|
||||||
|
{:on-press #(images/download-image-http
|
||||||
|
(get-in message [:content :image]) preview/share)
|
||||||
|
:id :share
|
||||||
|
:label (i18n/label :t/share)}]
|
||||||
|
(when (and outgoing config/delete-message-enabled?)
|
||||||
|
[{:on-press #(re-frame/dispatch [:chat.ui/soft-delete-message message])
|
||||||
|
:label (i18n/label :t/delete)
|
||||||
|
:id :delete}]))))}]
|
||||||
|
reaction-picker])
|
||||||
|
|
||||||
|
(defmethod ->message constants/content-type-audio []
|
||||||
|
(let [show-timestamp? (reagent/atom false)]
|
||||||
|
(fn [{:keys [outgoing] :as message}
|
||||||
|
{:keys [on-long-press modal]
|
||||||
|
:as reaction-picker}]
|
||||||
|
[message-content-wrapper message
|
||||||
|
[react/touchable-highlight
|
||||||
|
(when-not modal
|
||||||
|
{:on-long-press
|
||||||
|
(fn [] (on-long-press (if (and outgoing config/delete-message-enabled?)
|
||||||
|
[{:on-press #(re-frame/dispatch [:chat.ui/soft-delete-message message])
|
||||||
|
:label (i18n/label :t/delete)
|
||||||
|
:id :delete}]
|
||||||
|
[])))
|
||||||
|
:on-press (fn []
|
||||||
|
(reset! show-timestamp? true))})
|
||||||
|
[react/view (style/message-view-wrapper (:outgoing message))
|
||||||
|
[message-timestamp message show-timestamp?]
|
||||||
|
[react/view {:style (style/message-view message) :accessibility-label :audio-message}
|
||||||
|
[react/view {:style (style/message-view-content)}
|
||||||
|
[message.audio/message-content message] [message-status message]]]]]
|
||||||
|
reaction-picker])))
|
||||||
|
|
||||||
|
(defn contact-request-status-pending []
|
||||||
|
[react/view {:style {:flex-direction :row}}
|
||||||
|
[quo/text {:style {:margin-right 5.27}
|
||||||
|
:weight :medium
|
||||||
|
:color :secondary}
|
||||||
|
(i18n/label :t/contact-request-pending)]
|
||||||
|
[react/activity-indicator {:animating true
|
||||||
|
:size :small
|
||||||
|
:color colors/gray}]])
|
||||||
|
|
||||||
|
(defn contact-request-status-accepted []
|
||||||
|
[quo/text {:style {:color colors/green}
|
||||||
|
:weight :medium}
|
||||||
|
(i18n/label :t/contact-request-accepted)])
|
||||||
|
|
||||||
|
(defn contact-request-status-declined []
|
||||||
|
[quo/text {:style {:color colors/red}
|
||||||
|
:weight :medium}
|
||||||
|
(i18n/label :t/contact-request-declined)])
|
||||||
|
|
||||||
|
(defn contact-request-status-label [state]
|
||||||
|
[react/view {:style (style/contact-request-status-label state)}
|
||||||
|
(case state
|
||||||
|
constants/contact-request-message-state-pending [contact-request-status-pending]
|
||||||
|
constants/contact-request-message-state-accepted [contact-request-status-accepted]
|
||||||
|
constants/contact-request-message-state-declined [contact-request-status-declined])])
|
||||||
|
|
||||||
|
(defmethod ->message constants/content-type-contact-request
|
||||||
|
[{:keys [outgoing] :as message} _]
|
||||||
|
[react/view {:style (style/content-type-contact-request outgoing)}
|
||||||
|
[react/image {:source (resources/get-image :hand-wave)
|
||||||
|
:style {:width 112
|
||||||
|
:height 97}}]
|
||||||
|
[quo/text {:style {:margin-top 6}
|
||||||
|
:weight :bold
|
||||||
|
:size :large}
|
||||||
|
(i18n/label :t/contact-request)]
|
||||||
|
[react/view {:style {:padding-horizontal 16}}
|
||||||
|
[quo/text {:style {:margin-top 2
|
||||||
|
:margin-bottom 14}}
|
||||||
|
(get-in message [:content :text])]]
|
||||||
|
[contact-request-status-label (:contact-request-state message)]])
|
||||||
|
|
||||||
|
(defmethod ->message :default [message]
|
||||||
|
[message-content-wrapper message
|
||||||
|
[unknown-content-type message]])
|
||||||
|
|
||||||
|
(defn chat-message [{:keys [outgoing display-photo? pinned pinned-by] :as message} space-keeper]
|
||||||
|
[:<>
|
||||||
|
[reactions/with-reaction-picker
|
||||||
|
{:message message
|
||||||
|
:reactions @(re-frame/subscribe [:chats/message-reactions (:message-id message) (:chat-id message)])
|
||||||
|
:picker-on-open (fn []
|
||||||
|
(space-keeper true))
|
||||||
|
:picker-on-close (fn []
|
||||||
|
(space-keeper false))
|
||||||
|
:send-emoji (fn [{:keys [emoji-id]}]
|
||||||
|
(re-frame/dispatch [::models.reactions/send-emoji-reaction
|
||||||
|
{:message-id (:message-id message)
|
||||||
|
:emoji-id emoji-id}]))
|
||||||
|
:retract-emoji (fn [{:keys [emoji-id emoji-reaction-id]}]
|
||||||
|
(re-frame/dispatch [::models.reactions/send-emoji-reaction-retraction
|
||||||
|
{:message-id (:message-id message)
|
||||||
|
:emoji-id emoji-id
|
||||||
|
:emoji-reaction-id emoji-reaction-id}]))
|
||||||
|
:render ->message}]
|
||||||
|
(when pinned
|
||||||
|
[react/view {:style (style/pin-indicator-container outgoing)}
|
||||||
|
[pinned-by-indicator outgoing display-photo? pinned-by]])])
|
|
@ -8,7 +8,7 @@
|
||||||
[status-im.chat.models.pin-message :as models.pin-message]
|
[status-im.chat.models.pin-message :as models.pin-message]
|
||||||
[status-im.ui.components.list.views :as list]
|
[status-im.ui.components.list.views :as list]
|
||||||
[status-im.utils.handlers :refer [<sub]]
|
[status-im.utils.handlers :refer [<sub]]
|
||||||
[status-im.ui.screens.chat.message.message :as message]))
|
[status-im.ui.screens.chat.message.message-old :as message]))
|
||||||
|
|
||||||
(def selected-unpin (reagent/atom nil))
|
(def selected-unpin (reagent/atom nil))
|
||||||
|
|
||||||
|
|
|
@ -81,8 +81,8 @@
|
||||||
{:justify-content :flex-end}
|
{:justify-content :flex-end}
|
||||||
{:justify-content :flex-start})
|
{:justify-content :flex-start})
|
||||||
(if (or display-photo? timeline)
|
(if (or display-photo? timeline)
|
||||||
{:padding-left (+ 16 photos/default-size (when timeline 8))}
|
{:padding-left (+ 30 photos/default-size (when timeline 8))}
|
||||||
{:padding-left 8})))
|
{:padding-left 30})))
|
||||||
|
|
||||||
(defn reaction-button [active]
|
(defn reaction-button [active]
|
||||||
(merge {:width 40
|
(merge {:width 40
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
[status-im.ui.components.topbar :as topbar]
|
[status-im.ui.components.topbar :as topbar]
|
||||||
[status-im.ui.screens.chat.views :as chat]
|
[status-im.ui.screens.chat.views :as chat]
|
||||||
[status-im.ui.components.list.views :as list]
|
[status-im.ui.components.list.views :as list]
|
||||||
[status-im.ui.screens.chat.message.message :as message]
|
[status-im.ui.screens.chat.message.message-old :as message]
|
||||||
[status-im.utils.datetime :as time]))
|
[status-im.utils.datetime :as time]))
|
||||||
|
|
||||||
(defn pins-topbar [chat]
|
(defn pins-topbar [chat]
|
||||||
|
|
|
@ -17,22 +17,16 @@
|
||||||
:align-items :stretch
|
:align-items :stretch
|
||||||
:flex-grow 1})
|
:flex-grow 1})
|
||||||
|
|
||||||
(defn slider [outgoing]
|
(defn slider []
|
||||||
{:style (merge {:margin-left 12
|
{:style (merge {:margin-left 12
|
||||||
:height 34}
|
:height 34}
|
||||||
(when platform/ios? {:margin-bottom 4}))
|
(when platform/ios? {:margin-bottom 4}))
|
||||||
:thumb-tint-color (if outgoing
|
:thumb-tint-color colors/white
|
||||||
colors/white
|
:minimum-track-tint-color colors/white
|
||||||
colors/blue)
|
:maximum-track-tint-color colors/white-transparent})
|
||||||
:minimum-track-tint-color (if outgoing
|
|
||||||
colors/white
|
|
||||||
colors/blue)
|
|
||||||
:maximum-track-tint-color (if outgoing
|
|
||||||
colors/white-transparent
|
|
||||||
colors/gray-transparent-40)})
|
|
||||||
|
|
||||||
(defn play-pause-container [outgoing? loading?]
|
(defn play-pause-container [loading?]
|
||||||
{:background-color (if outgoing? colors/white-persist colors/blue)
|
{:background-color colors/white-persist
|
||||||
:width 28
|
:width 28
|
||||||
:height 28
|
:height 28
|
||||||
:padding (if loading? 4 2)
|
:padding (if loading? 4 2)
|
||||||
|
@ -42,6 +36,6 @@
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
:justify-content :space-between})
|
:justify-content :space-between})
|
||||||
|
|
||||||
(defn timestamp [outgoing]
|
(defn timestamp []
|
||||||
(merge (message.style/audio-message-timestamp-text outgoing)
|
(merge (message.style/audio-message-timestamp-text)
|
||||||
{:margin-left 40}))
|
{:margin-left 40}))
|
|
@ -0,0 +1,47 @@
|
||||||
|
(ns status-im.ui.screens.chat.styles.message.audio-old
|
||||||
|
(:require [quo.design-system.colors :as colors]
|
||||||
|
[status-im.ui.screens.chat.styles.message.message-old :as message.style]
|
||||||
|
[status-im.utils.platform :as platform]))
|
||||||
|
|
||||||
|
(defn container [window-width]
|
||||||
|
{:width (* window-width 0.60)
|
||||||
|
:flex-direction :column
|
||||||
|
:justify-content :space-between})
|
||||||
|
|
||||||
|
(def play-pause-slider-container
|
||||||
|
{:flex-direction :row
|
||||||
|
:align-items :center})
|
||||||
|
|
||||||
|
(def slider-container
|
||||||
|
{:flex-direction :column
|
||||||
|
:align-items :stretch
|
||||||
|
:flex-grow 1})
|
||||||
|
|
||||||
|
(defn slider [outgoing]
|
||||||
|
{:style (merge {:margin-left 12
|
||||||
|
:height 34}
|
||||||
|
(when platform/ios? {:margin-bottom 4}))
|
||||||
|
:thumb-tint-color (if outgoing
|
||||||
|
colors/white
|
||||||
|
colors/blue)
|
||||||
|
:minimum-track-tint-color (if outgoing
|
||||||
|
colors/white
|
||||||
|
colors/blue)
|
||||||
|
:maximum-track-tint-color (if outgoing
|
||||||
|
colors/white-transparent
|
||||||
|
colors/gray-transparent-40)})
|
||||||
|
|
||||||
|
(defn play-pause-container [outgoing? loading?]
|
||||||
|
{:background-color (if outgoing? colors/white-persist colors/blue)
|
||||||
|
:width 28
|
||||||
|
:height 28
|
||||||
|
:padding (if loading? 4 2)
|
||||||
|
:border-radius 15})
|
||||||
|
|
||||||
|
(def times-container
|
||||||
|
{:flex-direction :row
|
||||||
|
:justify-content :space-between})
|
||||||
|
|
||||||
|
(defn timestamp [outgoing]
|
||||||
|
(merge (message.style/audio-message-timestamp-text outgoing)
|
||||||
|
{:margin-left 40}))
|
|
@ -1,11 +1,22 @@
|
||||||
(ns status-im.ui.screens.chat.styles.message.datemark
|
(ns status-im.ui.screens.chat.styles.message.datemark
|
||||||
(:require [quo.design-system.colors :as colors]))
|
(:require [quo2.foundations.colors :as quo2.colors]))
|
||||||
|
|
||||||
(def datemark-mobile
|
(def datemark-mobile
|
||||||
{:flex 1
|
{:flex 1
|
||||||
:align-items :center
|
:justify-content :center
|
||||||
:margin-top 16
|
:margin-vertical 16
|
||||||
:height 22})
|
:padding-left 65})
|
||||||
|
|
||||||
|
(defn divider []
|
||||||
|
{:flex 1
|
||||||
|
:width "100%"
|
||||||
|
:height 1
|
||||||
|
:padding-left 53
|
||||||
|
:background-color (quo2.colors/theme-colors quo2.colors/divider-light quo2.colors/divider-dark)
|
||||||
|
:margin-top 5})
|
||||||
|
|
||||||
(defn datemark-text []
|
(defn datemark-text []
|
||||||
{:color colors/gray})
|
{:color quo2.colors/neutral-50
|
||||||
|
:font-size 14
|
||||||
|
:line-height 16
|
||||||
|
:font-weight "500"})
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
(ns status-im.ui.screens.chat.styles.message.datemark-old
|
||||||
|
(:require [quo.design-system.colors :as colors]))
|
||||||
|
|
||||||
|
(def datemark-mobile
|
||||||
|
{:flex 1
|
||||||
|
:align-items :center
|
||||||
|
:margin-top 16
|
||||||
|
:height 22})
|
||||||
|
|
||||||
|
(defn datemark-text []
|
||||||
|
{:color colors/gray})
|
|
@ -3,11 +3,11 @@
|
||||||
[quo.design-system.colors :as colors]
|
[quo.design-system.colors :as colors]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.screens.chat.styles.photos :as photos]
|
[status-im.ui.screens.chat.styles.photos :as photos]
|
||||||
[status-im.ui.components.typography :as typography]))
|
[quo2.foundations.colors :as quo2.colors]))
|
||||||
|
|
||||||
(defn style-message-text
|
(defn style-message-text
|
||||||
[outgoing]
|
[]
|
||||||
{:color (if outgoing colors/white-persist colors/text)})
|
{:color colors/text})
|
||||||
|
|
||||||
(defn system-message-body
|
(defn system-message-body
|
||||||
[_]
|
[_]
|
||||||
|
@ -18,9 +18,9 @@
|
||||||
:align-items :center})
|
:align-items :center})
|
||||||
|
|
||||||
(defn message-body
|
(defn message-body
|
||||||
[{:keys [outgoing]}]
|
[]
|
||||||
(let [align (if outgoing :flex-end :flex-start)
|
(let [align :flex-start
|
||||||
direction (if outgoing :row-reverse :row)]
|
direction :row]
|
||||||
{:flex-direction direction
|
{:flex-direction direction
|
||||||
:margin-top 4
|
:margin-top 4
|
||||||
:align-self align
|
:align-self align
|
||||||
|
@ -33,14 +33,10 @@
|
||||||
[]
|
[]
|
||||||
(merge message-timestamp {:opacity 0 :color "rgba(0,0,0,0)"}))
|
(merge message-timestamp {:opacity 0 :color "rgba(0,0,0,0)"}))
|
||||||
|
|
||||||
(defn message-timestamp-wrapper [{:keys [last-in-group? outgoing group-chat]}]
|
(defn message-timestamp-wrapper []
|
||||||
{:justify-content :center
|
{:justify-content :center
|
||||||
(if outgoing :margin-right :margin-left) 12 ;; horizontal margin is only required at the adjust side of the message.
|
:margin-left 12 ;; horizontal margin is only required at the adjust side of the message.
|
||||||
:margin-top (if (and last-in-group?
|
:margin-top 0
|
||||||
(or outgoing
|
|
||||||
(not group-chat)))
|
|
||||||
16
|
|
||||||
0) ;; Add gap between message groups
|
|
||||||
:opacity 0})
|
:opacity 0})
|
||||||
|
|
||||||
(defn message-timestamp-text []
|
(defn message-timestamp-text []
|
||||||
|
@ -48,49 +44,38 @@
|
||||||
{:color colors/gray
|
{:color colors/gray
|
||||||
:text-align :center}))
|
:text-align :center}))
|
||||||
|
|
||||||
(defn message-status-text [outgoing]
|
(defn message-status-text []
|
||||||
{:font-size 10
|
{:font-size 10
|
||||||
:line-height 10
|
:line-height 10
|
||||||
:color (if outgoing
|
:color colors/gray})
|
||||||
colors/white-transparent-70-persist
|
|
||||||
colors/gray)})
|
|
||||||
|
|
||||||
(defn audio-message-timestamp-text
|
(defn audio-message-timestamp-text
|
||||||
[outgoing]
|
[]
|
||||||
(merge message-timestamp
|
(merge message-timestamp
|
||||||
{:line-height 10
|
{:line-height 10
|
||||||
:color (if outgoing
|
:color colors/gray}))
|
||||||
colors/white-transparent-70-persist
|
|
||||||
colors/gray)}))
|
|
||||||
|
|
||||||
(defn message-wrapper [{:keys [outgoing in-popover?]}]
|
(defn message-wrapper [{:keys [in-popover?]}]
|
||||||
(if (and outgoing (not in-popover?))
|
(if (not in-popover?)
|
||||||
{:margin-left 96}
|
{:margin-left 10
|
||||||
{:margin-right 96}))
|
:padding-right 5}
|
||||||
|
{:margin-right 10}))
|
||||||
|
|
||||||
(defn message-author-wrapper
|
(defn message-author-wrapper []
|
||||||
[outgoing display-photo? in-popover?]
|
{:flex-direction :column
|
||||||
(let [align (if (and outgoing (not in-popover?)) :flex-end :flex-start)]
|
:flex-shrink 1
|
||||||
(merge {:flex-direction :column
|
:align-items :flex-start
|
||||||
:flex-shrink 1
|
:margin-left 4})
|
||||||
:align-items align}
|
|
||||||
(if (and outgoing (not in-popover?))
|
|
||||||
{:margin-right 8}
|
|
||||||
(when-not display-photo?
|
|
||||||
{:margin-left 8})))))
|
|
||||||
|
|
||||||
(defn delivery-status [outgoing]
|
(defn delivery-status []
|
||||||
(if outgoing
|
{:align-self :flex-start
|
||||||
{:align-self :flex-end
|
:padding-left 8})
|
||||||
:padding-right 8}
|
|
||||||
{:align-self :flex-start
|
|
||||||
:padding-left 8}))
|
|
||||||
|
|
||||||
(defn pin-indicator [outgoing display-photo?]
|
(defn pin-indicator [display-photo?]
|
||||||
(merge
|
(merge
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
:border-top-left-radius (if outgoing 12 4)
|
:border-top-left-radius 4
|
||||||
:border-top-right-radius (if outgoing 4 12)
|
:border-top-right-radius 12
|
||||||
:border-bottom-left-radius 12
|
:border-bottom-left-radius 12
|
||||||
:border-bottom-right-radius 12
|
:border-bottom-right-radius 12
|
||||||
:padding-left 8
|
:padding-left 8
|
||||||
|
@ -98,27 +83,18 @@
|
||||||
:padding-vertical 5
|
:padding-vertical 5
|
||||||
:background-color colors/gray-lighter
|
:background-color colors/gray-lighter
|
||||||
:justify-content :center
|
:justify-content :center
|
||||||
:max-width "80%"}
|
:max-width "80%"
|
||||||
(if outgoing
|
:align-self :flex-start
|
||||||
{:align-self :flex-end
|
:align-items :flex-start}
|
||||||
:align-items :flex-end}
|
|
||||||
{:align-self :flex-start
|
|
||||||
:align-items :flex-start})
|
|
||||||
(when display-photo?
|
(when display-photo?
|
||||||
{:margin-left 44})))
|
{:margin-left 44})))
|
||||||
|
|
||||||
(defn pin-indicator-container [outgoing]
|
(defn pin-indicator-container []
|
||||||
(merge
|
{:margin-top 2
|
||||||
{:margin-top 2
|
:justify-content :center
|
||||||
:align-items :center
|
:align-self :flex-start
|
||||||
:justify-content :center}
|
:align-items :flex-start
|
||||||
(if outgoing
|
:padding-left 8})
|
||||||
{:align-self :flex-end
|
|
||||||
:align-items :flex-end
|
|
||||||
:padding-right 8}
|
|
||||||
{:align-self :flex-start
|
|
||||||
:align-items :flex-start
|
|
||||||
:padding-left 8})))
|
|
||||||
|
|
||||||
(defn pinned-by-text-icon-container []
|
(defn pinned-by-text-icon-container []
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
|
@ -145,17 +121,14 @@
|
||||||
{:margin-left 5})
|
{:margin-left 5})
|
||||||
|
|
||||||
(def message-author-touchable
|
(def message-author-touchable
|
||||||
{:margin-left 12
|
{:margin-left 0
|
||||||
:flex-direction :row})
|
:flex-direction :row})
|
||||||
|
|
||||||
(defn message-author-userpic [outgoing]
|
(defn message-author-userpic []
|
||||||
(merge
|
(merge
|
||||||
{:width (+ 16 photos/default-size) ;; 16 is for the padding
|
{:width (+ 16 photos/default-size)} ;; 16 is for the padding
|
||||||
:align-self :flex-end}
|
{:padding-left 8
|
||||||
(if outgoing
|
:padding-right 8}))
|
||||||
{:padding-left 8}
|
|
||||||
{:padding-horizontal 8
|
|
||||||
:padding-right 8})))
|
|
||||||
|
|
||||||
(def delivery-text
|
(def delivery-text
|
||||||
{:color colors/gray
|
{:color colors/gray
|
||||||
|
@ -178,10 +151,10 @@
|
||||||
:padding-left 3})
|
:padding-left 3})
|
||||||
|
|
||||||
(defn emoji-message
|
(defn emoji-message
|
||||||
[{:keys [incoming-group outgoing]}]
|
[{:keys [incoming-group]}]
|
||||||
{:font-size 28
|
{:font-size 28
|
||||||
:line-height 34 ;TODO: Smaller crops the icon on the top
|
:line-height 34 ;TODO: Smaller crops the icon on the top
|
||||||
:margin-right (if outgoing 18 0) ;; Margin to display outgoing message status
|
:margin-right 0 ;; Margin to display outgoing message status
|
||||||
:margin-top (if incoming-group 4 0)})
|
:margin-top (if incoming-group 4 0)})
|
||||||
|
|
||||||
(defn collapse-button []
|
(defn collapse-button []
|
||||||
|
@ -193,37 +166,25 @@
|
||||||
:shadow-color (:shadow-01 @colors/theme)
|
:shadow-color (:shadow-01 @colors/theme)
|
||||||
:shadow-offset {:width 0 :height 4}})
|
:shadow-offset {:width 0 :height 4}})
|
||||||
|
|
||||||
(defn message-view-wrapper [outgoing]
|
(def message-view-wrapper
|
||||||
{:align-self :flex-end
|
{:align-self :flex-end
|
||||||
:flex-direction (if outgoing :row :row-reverse)})
|
:flex-direction :row-reverse})
|
||||||
|
|
||||||
(defn message-view
|
(defn message-view
|
||||||
[{:keys [content-type outgoing group-chat last-in-group? mentioned pinned]}]
|
[{:keys [content-type mentioned pinned]}]
|
||||||
(merge
|
(merge
|
||||||
{:border-top-left-radius 16
|
{:border-radius 10}
|
||||||
:border-top-right-radius 16
|
|
||||||
:border-bottom-right-radius 16
|
|
||||||
:border-bottom-left-radius 16
|
|
||||||
:padding-top 6
|
|
||||||
:padding-horizontal 12
|
|
||||||
:border-radius 8
|
|
||||||
:margin-top (if (and last-in-group?
|
|
||||||
(or outgoing
|
|
||||||
(not group-chat)))
|
|
||||||
16
|
|
||||||
0)}
|
|
||||||
(if outgoing
|
|
||||||
{:border-bottom-right-radius 4}
|
|
||||||
{:border-bottom-left-radius 4})
|
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
pinned {:background-color colors/pin-background}
|
pinned {:background-color colors/pin-background}
|
||||||
(= content-type constants/content-type-system-text) nil
|
(= content-type constants/content-type-system-text) nil
|
||||||
outgoing {:background-color colors/blue}
|
|
||||||
mentioned {:background-color colors/mentioned-background
|
mentioned {:background-color colors/mentioned-background
|
||||||
:border-color colors/mentioned-border
|
:border-color colors/mentioned-border
|
||||||
:border-width 1}
|
:border-width 1}
|
||||||
:else {:background-color colors/blue-light})
|
(= content-type constants/content-type-audio) {:background-color colors/blue
|
||||||
|
:padding-horizontal 12
|
||||||
|
:padding-top 6}
|
||||||
|
:else {:background-color colors/white})
|
||||||
|
|
||||||
(when (= content-type constants/content-type-emoji)
|
(when (= content-type constants/content-type-emoji)
|
||||||
{:flex-direction :row})))
|
{:flex-direction :row})))
|
||||||
|
@ -247,12 +208,10 @@
|
||||||
:padding-left 12
|
:padding-left 12
|
||||||
:text-align-vertical :center})
|
:text-align-vertical :center})
|
||||||
|
|
||||||
(defn quoted-message-container [outgoing]
|
(defn quoted-message-container []
|
||||||
{:margin-bottom 6
|
{:margin-bottom 6
|
||||||
:padding-bottom 6
|
:padding-bottom 6
|
||||||
:border-bottom-color (if outgoing
|
:border-bottom-color colors/black-transparent
|
||||||
colors/white-transparent-10
|
|
||||||
colors/black-transparent)
|
|
||||||
:border-bottom-width 2
|
:border-bottom-width 2
|
||||||
:border-bottom-left-radius 2
|
:border-bottom-left-radius 2
|
||||||
:border-bottom-right-radius 2})
|
:border-bottom-right-radius 2})
|
||||||
|
@ -262,29 +221,31 @@
|
||||||
:align-items :center
|
:align-items :center
|
||||||
:justify-content :flex-start})
|
:justify-content :flex-start})
|
||||||
|
|
||||||
(defn quoted-message-author [outgoing chosen?]
|
(defn quoted-message-author [chosen?]
|
||||||
(assoc (message-author-name chosen?)
|
(assoc (message-author-name chosen?)
|
||||||
:padding-bottom 6
|
:padding-bottom 6
|
||||||
:padding-top 0
|
:padding-top 0
|
||||||
:padding-left 0
|
:padding-left 0
|
||||||
:line-height 18
|
:line-height 18
|
||||||
:font-weight "500"
|
:font-weight "500"
|
||||||
:color (if outgoing
|
:color colors/gray))
|
||||||
colors/white-transparent-70-persist
|
|
||||||
colors/gray)))
|
|
||||||
|
|
||||||
(defn quoted-message-text [outgoing]
|
(defn quoted-message-text []
|
||||||
{:font-size 14
|
{:font-size 14
|
||||||
:color (if outgoing
|
:color colors/gray})
|
||||||
colors/white-transparent-70-persist
|
|
||||||
colors/gray)})
|
(defn message-default-style []
|
||||||
|
{:font-family "Inter-Regular"
|
||||||
|
:color (quo2.colors/theme-colors quo2.colors/black quo2.colors/white)
|
||||||
|
:font-size 15
|
||||||
|
:line-height 21.75
|
||||||
|
:letter-spacing -0.135})
|
||||||
|
|
||||||
;; Markdown styles
|
;; Markdown styles
|
||||||
|
|
||||||
(defn default-text-style []
|
(defn default-text-style []
|
||||||
{:max-font-size-multiplier react/max-font-size-multiplier
|
{:max-font-size-multiplier react/max-font-size-multiplier
|
||||||
:style (assoc (typography/default-style)
|
:style (message-default-style)})
|
||||||
:line-height 22)})
|
|
||||||
|
|
||||||
(defn outgoing-text-style []
|
(defn outgoing-text-style []
|
||||||
(update (default-text-style) :style
|
(update (default-text-style) :style
|
||||||
|
@ -298,12 +259,11 @@
|
||||||
:text-align :center
|
:text-align :center
|
||||||
:font-weight "400"))
|
:font-weight "400"))
|
||||||
|
|
||||||
(defn text-style [outgoing content-type in-popover?]
|
(defn text-style [content-type in-popover?]
|
||||||
(merge
|
(merge
|
||||||
(when in-popover? {:number-of-lines 2})
|
(when in-popover? {:number-of-lines 2})
|
||||||
(cond
|
(cond
|
||||||
(= content-type constants/content-type-system-text) (system-text-style)
|
(= content-type constants/content-type-system-text) (system-text-style)
|
||||||
outgoing (outgoing-text-style)
|
|
||||||
:else (default-text-style))))
|
:else (default-text-style))))
|
||||||
|
|
||||||
(defn emph-text-style []
|
(defn emph-text-style []
|
||||||
|
@ -314,10 +274,8 @@
|
||||||
(update (emph-text-style) :style
|
(update (emph-text-style) :style
|
||||||
assoc :color colors/white-persist))
|
assoc :color colors/white-persist))
|
||||||
|
|
||||||
(defn emph-style [outgoing]
|
(defn emph-style []
|
||||||
(if outgoing
|
(emph-text-style))
|
||||||
(outgoing-emph-text-style)
|
|
||||||
(emph-text-style)))
|
|
||||||
|
|
||||||
(defn strong-text-style []
|
(defn strong-text-style []
|
||||||
(update (default-text-style) :style
|
(update (default-text-style) :style
|
||||||
|
@ -327,20 +285,17 @@
|
||||||
(update (strong-text-style) :style
|
(update (strong-text-style) :style
|
||||||
assoc :color colors/white-persist))
|
assoc :color colors/white-persist))
|
||||||
|
|
||||||
(defn strong-style [outgoing]
|
(defn strong-style []
|
||||||
(if outgoing
|
(outgoing-strong-text-style)
|
||||||
(outgoing-strong-text-style)
|
(strong-text-style))
|
||||||
(strong-text-style)))
|
|
||||||
|
|
||||||
(defn strong-emph-style [outgoing]
|
(defn strong-emph-style []
|
||||||
(update (strong-style outgoing) :style
|
(update (strong-style) :style
|
||||||
assoc :font-style :italic))
|
assoc :font-style :italic))
|
||||||
|
|
||||||
(defn strikethrough-style [outgoing]
|
(defn strikethrough-style []
|
||||||
(cond-> (update (default-text-style) :style
|
(cond-> (update (default-text-style) :style
|
||||||
assoc :text-decoration-line :line-through)
|
assoc :text-decoration-line :line-through)))
|
||||||
outgoing
|
|
||||||
(update :style assoc :color colors/white-persist)))
|
|
||||||
|
|
||||||
(def code-block-background "#2E386B")
|
(def code-block-background "#2E386B")
|
||||||
|
|
||||||
|
@ -366,10 +321,8 @@
|
||||||
assoc
|
assoc
|
||||||
:border-left-color colors/white-transparent-70-persist))
|
:border-left-color colors/white-transparent-70-persist))
|
||||||
|
|
||||||
(defn blockquote-style [outgoing]
|
(defn blockquote-style []
|
||||||
(if outgoing
|
(default-blockquote-style))
|
||||||
(outgoing-blockquote-style)
|
|
||||||
(default-blockquote-style)))
|
|
||||||
|
|
||||||
(defn default-blockquote-text-style []
|
(defn default-blockquote-text-style []
|
||||||
(update (default-text-style) :style
|
(update (default-text-style) :style
|
||||||
|
@ -383,20 +336,16 @@
|
||||||
assoc
|
assoc
|
||||||
:color colors/white-transparent-70-persist))
|
:color colors/white-transparent-70-persist))
|
||||||
|
|
||||||
(defn blockquote-text-style [outgoing]
|
(defn blockquote-text-style []
|
||||||
(if outgoing
|
(outgoing-blockquote-text-style)
|
||||||
(outgoing-blockquote-text-style)
|
(default-blockquote-text-style))
|
||||||
(default-blockquote-text-style)))
|
|
||||||
|
|
||||||
(defn image-message
|
(defn image-message
|
||||||
[{:keys [outgoing width height]}]
|
[{:keys [width height]}]
|
||||||
{:overflow :hidden
|
{:overflow :hidden
|
||||||
:border-top-left-radius 16
|
:border-radius 8
|
||||||
:border-top-right-radius 16
|
:width width
|
||||||
:border-bottom-left-radius (if outgoing 16 4)
|
:height height})
|
||||||
:border-bottom-right-radius (if outgoing 4 16)
|
|
||||||
:width width
|
|
||||||
:height height})
|
|
||||||
|
|
||||||
(defn image-message-border [opts]
|
(defn image-message-border [opts]
|
||||||
(merge (image-message opts)
|
(merge (image-message opts)
|
||||||
|
@ -453,7 +402,7 @@
|
||||||
:padding-vertical 10
|
:padding-vertical 10
|
||||||
:padding-horizontal 16})
|
:padding-horizontal 16})
|
||||||
|
|
||||||
(defn content-type-contact-request [outgoing]
|
(defn content-type-contact-request []
|
||||||
{:width 168
|
{:width 168
|
||||||
:min-height 224.71
|
:min-height 224.71
|
||||||
:border-radius 8
|
:border-radius 8
|
||||||
|
@ -462,6 +411,6 @@
|
||||||
:align-items :center
|
:align-items :center
|
||||||
:padding-bottom 10
|
:padding-bottom 10
|
||||||
:margin-vertical 4
|
:margin-vertical 4
|
||||||
:align-self (if outgoing :flex-end :flex-start)
|
:align-self :flex-start
|
||||||
:margin-right (if outgoing 8 0)
|
:margin-right 0
|
||||||
:margin-left (if outgoing 0 8)})
|
:margin-left 8})
|
||||||
|
|
|
@ -0,0 +1,467 @@
|
||||||
|
(ns status-im.ui.screens.chat.styles.message.message-old
|
||||||
|
(:require [status-im.constants :as constants]
|
||||||
|
[quo.design-system.colors :as colors]
|
||||||
|
[status-im.ui.components.react :as react]
|
||||||
|
[status-im.ui.screens.chat.styles.photos :as photos]
|
||||||
|
[status-im.ui.components.typography :as typography]))
|
||||||
|
|
||||||
|
(defn style-message-text
|
||||||
|
[outgoing]
|
||||||
|
{:color (if outgoing colors/white-persist colors/text)})
|
||||||
|
|
||||||
|
(defn system-message-body
|
||||||
|
[_]
|
||||||
|
{:margin-top 4
|
||||||
|
:margin-left 8
|
||||||
|
:margin-right 8
|
||||||
|
:align-self :center
|
||||||
|
:align-items :center})
|
||||||
|
|
||||||
|
(defn message-body
|
||||||
|
[{:keys [outgoing]}]
|
||||||
|
(let [align (if outgoing :flex-end :flex-start)
|
||||||
|
direction (if outgoing :row-reverse :row)]
|
||||||
|
{:flex-direction direction
|
||||||
|
:margin-top 4
|
||||||
|
:align-self align
|
||||||
|
:align-items align}))
|
||||||
|
|
||||||
|
(def message-timestamp
|
||||||
|
{:font-size 10})
|
||||||
|
|
||||||
|
(defn message-status-placeholder
|
||||||
|
[]
|
||||||
|
(merge message-timestamp {:opacity 0 :color "rgba(0,0,0,0)"}))
|
||||||
|
|
||||||
|
(defn message-timestamp-wrapper [{:keys [last-in-group? outgoing group-chat]}]
|
||||||
|
{:justify-content :center
|
||||||
|
(if outgoing :margin-right :margin-left) 12 ;; horizontal margin is only required at the adjust side of the message.
|
||||||
|
:margin-top (if (and last-in-group?
|
||||||
|
(or outgoing
|
||||||
|
(not group-chat)))
|
||||||
|
16
|
||||||
|
0) ;; Add gap between message groups
|
||||||
|
:opacity 0})
|
||||||
|
|
||||||
|
(defn message-timestamp-text []
|
||||||
|
(merge message-timestamp
|
||||||
|
{:color colors/gray
|
||||||
|
:text-align :center}))
|
||||||
|
|
||||||
|
(defn message-status-text [outgoing]
|
||||||
|
{:font-size 10
|
||||||
|
:line-height 10
|
||||||
|
:color (if outgoing
|
||||||
|
colors/white-transparent-70-persist
|
||||||
|
colors/gray)})
|
||||||
|
|
||||||
|
(defn audio-message-timestamp-text
|
||||||
|
[outgoing]
|
||||||
|
(merge message-timestamp
|
||||||
|
{:line-height 10
|
||||||
|
:color (if outgoing
|
||||||
|
colors/white-transparent-70-persist
|
||||||
|
colors/gray)}))
|
||||||
|
|
||||||
|
(defn message-wrapper [{:keys [outgoing in-popover?]}]
|
||||||
|
(if (and outgoing (not in-popover?))
|
||||||
|
{:margin-left 96}
|
||||||
|
{:margin-right 96}))
|
||||||
|
|
||||||
|
(defn message-author-wrapper
|
||||||
|
[outgoing display-photo? in-popover?]
|
||||||
|
(let [align (if (and outgoing (not in-popover?)) :flex-end :flex-start)]
|
||||||
|
(merge {:flex-direction :column
|
||||||
|
:flex-shrink 1
|
||||||
|
:align-items align}
|
||||||
|
(if (and outgoing (not in-popover?))
|
||||||
|
{:margin-right 8}
|
||||||
|
(when-not display-photo?
|
||||||
|
{:margin-left 8})))))
|
||||||
|
|
||||||
|
(defn delivery-status [outgoing]
|
||||||
|
(if outgoing
|
||||||
|
{:align-self :flex-end
|
||||||
|
:padding-right 8}
|
||||||
|
{:align-self :flex-start
|
||||||
|
:padding-left 8}))
|
||||||
|
|
||||||
|
(defn pin-indicator [outgoing display-photo?]
|
||||||
|
(merge
|
||||||
|
{:flex-direction :row
|
||||||
|
:border-top-left-radius (if outgoing 12 4)
|
||||||
|
:border-top-right-radius (if outgoing 4 12)
|
||||||
|
:border-bottom-left-radius 12
|
||||||
|
:border-bottom-right-radius 12
|
||||||
|
:padding-left 8
|
||||||
|
:padding-right 10
|
||||||
|
:padding-vertical 5
|
||||||
|
:background-color colors/gray-lighter
|
||||||
|
:justify-content :center
|
||||||
|
:max-width "80%"}
|
||||||
|
(if outgoing
|
||||||
|
{:align-self :flex-end
|
||||||
|
:align-items :flex-end}
|
||||||
|
{:align-self :flex-start
|
||||||
|
:align-items :flex-start})
|
||||||
|
(when display-photo?
|
||||||
|
{:margin-left 44})))
|
||||||
|
|
||||||
|
(defn pin-indicator-container [outgoing]
|
||||||
|
(merge
|
||||||
|
{:margin-top 2
|
||||||
|
:align-items :center
|
||||||
|
:justify-content :center}
|
||||||
|
(if outgoing
|
||||||
|
{:align-self :flex-end
|
||||||
|
:align-items :flex-end
|
||||||
|
:padding-right 8}
|
||||||
|
{:align-self :flex-start
|
||||||
|
:align-items :flex-start
|
||||||
|
:padding-left 8})))
|
||||||
|
|
||||||
|
(defn pinned-by-text-icon-container []
|
||||||
|
{:flex-direction :row
|
||||||
|
:align-items :flex-start
|
||||||
|
:top 5
|
||||||
|
:left 8
|
||||||
|
:position :absolute})
|
||||||
|
|
||||||
|
(defn pin-icon-container []
|
||||||
|
{:flex-direction :row
|
||||||
|
:margin-top 1})
|
||||||
|
|
||||||
|
(defn pin-author-text []
|
||||||
|
{:margin-left 2
|
||||||
|
:margin-right 12
|
||||||
|
:padding-right 0
|
||||||
|
:left 12
|
||||||
|
:flex-direction :row
|
||||||
|
:flex-shrink 1
|
||||||
|
:align-self :flex-start
|
||||||
|
:overflow :hidden})
|
||||||
|
|
||||||
|
(defn pinned-by-text []
|
||||||
|
{:margin-left 5})
|
||||||
|
|
||||||
|
(def message-author-touchable
|
||||||
|
{:margin-left 12
|
||||||
|
:flex-direction :row})
|
||||||
|
|
||||||
|
(defn message-author-userpic [outgoing]
|
||||||
|
(merge
|
||||||
|
{:width (+ 16 photos/default-size) ;; 16 is for the padding
|
||||||
|
:align-self :flex-end}
|
||||||
|
(if outgoing
|
||||||
|
{:padding-left 8}
|
||||||
|
{:padding-horizontal 8
|
||||||
|
:padding-right 8})))
|
||||||
|
|
||||||
|
(def delivery-text
|
||||||
|
{:color colors/gray
|
||||||
|
:margin-top 2
|
||||||
|
:font-size 12})
|
||||||
|
|
||||||
|
(def not-sent-view
|
||||||
|
{:flex-direction :row
|
||||||
|
:margin-bottom 2
|
||||||
|
:padding-top 2})
|
||||||
|
|
||||||
|
(def not-sent-text
|
||||||
|
(assoc delivery-text
|
||||||
|
:color colors/red
|
||||||
|
:text-align :right
|
||||||
|
:padding-top 4))
|
||||||
|
|
||||||
|
(def not-sent-icon
|
||||||
|
{:padding-top 3
|
||||||
|
:padding-left 3})
|
||||||
|
|
||||||
|
(defn emoji-message
|
||||||
|
[{:keys [incoming-group outgoing]}]
|
||||||
|
{:font-size 28
|
||||||
|
:line-height 34 ;TODO: Smaller crops the icon on the top
|
||||||
|
:margin-right (if outgoing 18 0) ;; Margin to display outgoing message status
|
||||||
|
:margin-top (if incoming-group 4 0)})
|
||||||
|
|
||||||
|
(defn collapse-button []
|
||||||
|
{:height 24 :width 24 :background-color colors/blue
|
||||||
|
:border-radius 12 :align-items :center :justify-content :center
|
||||||
|
:elevation 4
|
||||||
|
:shadow-opacity 1
|
||||||
|
:shadow-radius 16
|
||||||
|
:shadow-color (:shadow-01 @colors/theme)
|
||||||
|
:shadow-offset {:width 0 :height 4}})
|
||||||
|
|
||||||
|
(defn message-view-wrapper [outgoing]
|
||||||
|
{:align-self :flex-end
|
||||||
|
:flex-direction (if outgoing :row :row-reverse)})
|
||||||
|
|
||||||
|
(defn message-view
|
||||||
|
[{:keys [content-type outgoing group-chat last-in-group? mentioned pinned]}]
|
||||||
|
(merge
|
||||||
|
{:border-top-left-radius 16
|
||||||
|
:border-top-right-radius 16
|
||||||
|
:border-bottom-right-radius 16
|
||||||
|
:border-bottom-left-radius 16
|
||||||
|
:padding-top 6
|
||||||
|
:padding-horizontal 12
|
||||||
|
:border-radius 8
|
||||||
|
:margin-top (if (and last-in-group?
|
||||||
|
(or outgoing
|
||||||
|
(not group-chat)))
|
||||||
|
16
|
||||||
|
0)}
|
||||||
|
(if outgoing
|
||||||
|
{:border-bottom-right-radius 4}
|
||||||
|
{:border-bottom-left-radius 4})
|
||||||
|
|
||||||
|
(cond
|
||||||
|
pinned {:background-color colors/pin-background}
|
||||||
|
(= content-type constants/content-type-system-text) nil
|
||||||
|
outgoing {:background-color colors/blue}
|
||||||
|
mentioned {:background-color colors/mentioned-background
|
||||||
|
:border-color colors/mentioned-border
|
||||||
|
:border-width 1}
|
||||||
|
:else {:background-color colors/blue-light})
|
||||||
|
|
||||||
|
(when (= content-type constants/content-type-emoji)
|
||||||
|
{:flex-direction :row})))
|
||||||
|
|
||||||
|
(defn message-view-content []
|
||||||
|
{:padding-bottom 6
|
||||||
|
:overflow :hidden})
|
||||||
|
|
||||||
|
(def status-container
|
||||||
|
{:padding-horizontal 5})
|
||||||
|
|
||||||
|
(defn status-text []
|
||||||
|
{:margin-top 9
|
||||||
|
:font-size 14
|
||||||
|
:color colors/gray})
|
||||||
|
|
||||||
|
(defn message-author-name [chosen?]
|
||||||
|
{:font-size (if chosen? 13 12)
|
||||||
|
:font-weight (if chosen? "500" "400")
|
||||||
|
:padding-top 6
|
||||||
|
:padding-left 12
|
||||||
|
:text-align-vertical :center})
|
||||||
|
|
||||||
|
(defn quoted-message-container [outgoing]
|
||||||
|
{:margin-bottom 6
|
||||||
|
:padding-bottom 6
|
||||||
|
:border-bottom-color (if outgoing
|
||||||
|
colors/white-transparent-10
|
||||||
|
colors/black-transparent)
|
||||||
|
:border-bottom-width 2
|
||||||
|
:border-bottom-left-radius 2
|
||||||
|
:border-bottom-right-radius 2})
|
||||||
|
|
||||||
|
(def quoted-message-author-container
|
||||||
|
{:flex-direction :row
|
||||||
|
:align-items :center
|
||||||
|
:justify-content :flex-start})
|
||||||
|
|
||||||
|
(defn quoted-message-author [outgoing chosen?]
|
||||||
|
(assoc (message-author-name chosen?)
|
||||||
|
:padding-bottom 6
|
||||||
|
:padding-top 0
|
||||||
|
:padding-left 0
|
||||||
|
:line-height 18
|
||||||
|
:font-weight "500"
|
||||||
|
:color (if outgoing
|
||||||
|
colors/white-transparent-70-persist
|
||||||
|
colors/gray)))
|
||||||
|
|
||||||
|
(defn quoted-message-text [outgoing]
|
||||||
|
{:font-size 14
|
||||||
|
:color (if outgoing
|
||||||
|
colors/white-transparent-70-persist
|
||||||
|
colors/gray)})
|
||||||
|
|
||||||
|
;; Markdown styles
|
||||||
|
|
||||||
|
(defn default-text-style []
|
||||||
|
{:max-font-size-multiplier react/max-font-size-multiplier
|
||||||
|
:style (assoc (typography/default-style)
|
||||||
|
:line-height 22)})
|
||||||
|
|
||||||
|
(defn outgoing-text-style []
|
||||||
|
(update (default-text-style) :style
|
||||||
|
assoc :color colors/white-persist))
|
||||||
|
|
||||||
|
(defn system-text-style []
|
||||||
|
(update (default-text-style) :style assoc
|
||||||
|
:color colors/gray
|
||||||
|
:line-height 20
|
||||||
|
:font-size 14
|
||||||
|
:text-align :center
|
||||||
|
:font-weight "400"))
|
||||||
|
|
||||||
|
(defn text-style [outgoing content-type in-popover?]
|
||||||
|
(merge
|
||||||
|
(when in-popover? {:number-of-lines 2})
|
||||||
|
(cond
|
||||||
|
(= content-type constants/content-type-system-text) (system-text-style)
|
||||||
|
outgoing (outgoing-text-style)
|
||||||
|
:else (default-text-style))))
|
||||||
|
|
||||||
|
(defn emph-text-style []
|
||||||
|
(update (default-text-style) :style
|
||||||
|
assoc :font-style :italic))
|
||||||
|
|
||||||
|
(defn outgoing-emph-text-style []
|
||||||
|
(update (emph-text-style) :style
|
||||||
|
assoc :color colors/white-persist))
|
||||||
|
|
||||||
|
(defn emph-style [outgoing]
|
||||||
|
(if outgoing
|
||||||
|
(outgoing-emph-text-style)
|
||||||
|
(emph-text-style)))
|
||||||
|
|
||||||
|
(defn strong-text-style []
|
||||||
|
(update (default-text-style) :style
|
||||||
|
assoc :font-weight "700"))
|
||||||
|
|
||||||
|
(defn outgoing-strong-text-style []
|
||||||
|
(update (strong-text-style) :style
|
||||||
|
assoc :color colors/white-persist))
|
||||||
|
|
||||||
|
(defn strong-style [outgoing]
|
||||||
|
(if outgoing
|
||||||
|
(outgoing-strong-text-style)
|
||||||
|
(strong-text-style)))
|
||||||
|
|
||||||
|
(defn strong-emph-style [outgoing]
|
||||||
|
(update (strong-style outgoing) :style
|
||||||
|
assoc :font-style :italic))
|
||||||
|
|
||||||
|
(defn strikethrough-style [outgoing]
|
||||||
|
(cond-> (update (default-text-style) :style
|
||||||
|
assoc :text-decoration-line :line-through)
|
||||||
|
outgoing
|
||||||
|
(update :style assoc :color colors/white-persist)))
|
||||||
|
|
||||||
|
(def code-block-background "#2E386B")
|
||||||
|
|
||||||
|
(defn inline-code-style []
|
||||||
|
{:color colors/white-persist
|
||||||
|
:background-color code-block-background})
|
||||||
|
|
||||||
|
(def codeblock-style
|
||||||
|
{:padding 10
|
||||||
|
:background-color code-block-background
|
||||||
|
:border-radius 4})
|
||||||
|
|
||||||
|
(def codeblock-text-style
|
||||||
|
{:color colors/white-persist})
|
||||||
|
|
||||||
|
(defn default-blockquote-style []
|
||||||
|
{:style {:border-left-width 2
|
||||||
|
:padding-left 3
|
||||||
|
:border-left-color colors/gray-transparent-40}})
|
||||||
|
|
||||||
|
(defn outgoing-blockquote-style []
|
||||||
|
(update (default-blockquote-style) :style
|
||||||
|
assoc
|
||||||
|
:border-left-color colors/white-transparent-70-persist))
|
||||||
|
|
||||||
|
(defn blockquote-style [outgoing]
|
||||||
|
(if outgoing
|
||||||
|
(outgoing-blockquote-style)
|
||||||
|
(default-blockquote-style)))
|
||||||
|
|
||||||
|
(defn default-blockquote-text-style []
|
||||||
|
(update (default-text-style) :style
|
||||||
|
assoc
|
||||||
|
:line-height 19
|
||||||
|
:font-size 14
|
||||||
|
:color colors/black-transparent-50))
|
||||||
|
|
||||||
|
(defn outgoing-blockquote-text-style []
|
||||||
|
(update (default-blockquote-text-style) :style
|
||||||
|
assoc
|
||||||
|
:color colors/white-transparent-70-persist))
|
||||||
|
|
||||||
|
(defn blockquote-text-style [outgoing]
|
||||||
|
(if outgoing
|
||||||
|
(outgoing-blockquote-text-style)
|
||||||
|
(default-blockquote-text-style)))
|
||||||
|
|
||||||
|
(defn image-message
|
||||||
|
[{:keys [outgoing width height]}]
|
||||||
|
{:overflow :hidden
|
||||||
|
:border-top-left-radius 16
|
||||||
|
:border-top-right-radius 16
|
||||||
|
:border-bottom-left-radius (if outgoing 16 4)
|
||||||
|
:border-bottom-right-radius (if outgoing 4 16)
|
||||||
|
:width width
|
||||||
|
:height height})
|
||||||
|
|
||||||
|
(defn image-message-border [opts]
|
||||||
|
(merge (image-message opts)
|
||||||
|
{:opacity (:opacity opts)
|
||||||
|
:border-width 1
|
||||||
|
:top 0
|
||||||
|
:left 0
|
||||||
|
:position :absolute
|
||||||
|
:background-color :transparent
|
||||||
|
:border-color colors/black-transparent}))
|
||||||
|
|
||||||
|
(defn community-verified []
|
||||||
|
{:border-right-width 1
|
||||||
|
:border-left-width 1
|
||||||
|
:border-top-width 1
|
||||||
|
:border-left-color colors/gray-lighter
|
||||||
|
:border-right-color colors/gray-lighter
|
||||||
|
:border-top-left-radius 10
|
||||||
|
:border-top-right-radius 10
|
||||||
|
:padding-vertical 8
|
||||||
|
:padding-horizontal 15
|
||||||
|
:border-top-color colors/gray-lighter})
|
||||||
|
|
||||||
|
(defn community-message [verified]
|
||||||
|
{:flex-direction :row
|
||||||
|
:padding-vertical 12
|
||||||
|
:border-top-left-radius (when-not verified 10)
|
||||||
|
:border-top-right-radius (when-not verified 10)
|
||||||
|
:border-right-width 1
|
||||||
|
:border-left-width 1
|
||||||
|
:border-top-width 1
|
||||||
|
:border-color colors/gray-lighter})
|
||||||
|
|
||||||
|
(defn community-view-button []
|
||||||
|
{:border-width 1
|
||||||
|
:padding-vertical 8
|
||||||
|
:border-bottom-left-radius 10
|
||||||
|
:border-bottom-right-radius 10
|
||||||
|
:border-color colors/gray-lighter})
|
||||||
|
|
||||||
|
(defn contact-request-status-label [state]
|
||||||
|
{:width 136
|
||||||
|
:border-radius 8
|
||||||
|
:flex 1
|
||||||
|
:justify-content :center
|
||||||
|
:align-items :center
|
||||||
|
:background-color (when (= :retry state)
|
||||||
|
colors/blue-light)
|
||||||
|
:border-width 1
|
||||||
|
:border-color (case state
|
||||||
|
constants/contact-request-message-state-accepted colors/green-transparent-10
|
||||||
|
constants/contact-request-message-state-declined colors/red-light
|
||||||
|
constants/contact-request-message-state-pending colors/gray-lighter)
|
||||||
|
:padding-vertical 10
|
||||||
|
:padding-horizontal 16})
|
||||||
|
|
||||||
|
(defn content-type-contact-request [outgoing]
|
||||||
|
{:width 168
|
||||||
|
:min-height 224.71
|
||||||
|
:border-radius 8
|
||||||
|
:border-width 1
|
||||||
|
:border-color colors/gray-lighter
|
||||||
|
:align-items :center
|
||||||
|
:padding-bottom 10
|
||||||
|
:margin-vertical 4
|
||||||
|
:align-self (if outgoing :flex-end :flex-start)
|
||||||
|
:margin-right (if outgoing 8 0)
|
||||||
|
:margin-left (if outgoing 0 8)})
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
(def ^:private reply-symbol "↪ ")
|
(def ^:private reply-symbol "↪ ")
|
||||||
|
|
||||||
(defn format-author
|
(defn format-author-old
|
||||||
([contact] (format-author contact nil))
|
([contact] (format-author-old contact nil))
|
||||||
([{:keys [names] :as contact} {:keys [modal profile? you?]}]
|
([{:keys [names] :as contact} {:keys [modal profile? you?]}]
|
||||||
(let [{:keys [nickname ens-name]} names
|
(let [{:keys [nickname ens-name]} names
|
||||||
[first-name second-name] (multiaccounts/contact-two-names contact false)]
|
[first-name second-name] (multiaccounts/contact-two-names contact false)]
|
||||||
|
@ -31,6 +31,32 @@
|
||||||
:font-weight "400"}}
|
:font-weight "400"}}
|
||||||
first-name]))))
|
first-name]))))
|
||||||
|
|
||||||
|
(defn format-author
|
||||||
|
([contact] (format-author contact nil))
|
||||||
|
([{:keys [names] :as contact} {:keys [modal profile? you?]}]
|
||||||
|
(let [{:keys [nickname ens-name]} names
|
||||||
|
[first-name second-name] (multiaccounts/contact-two-names contact false)]
|
||||||
|
(if (or nickname ens-name)
|
||||||
|
[react/nested-text {:number-of-lines 2
|
||||||
|
:style {:color (if modal colors/white-persist colors/black)
|
||||||
|
:font-size (if profile? 15 13)
|
||||||
|
:line-height (if profile? 22 18)
|
||||||
|
:letter-spacing -0.2
|
||||||
|
:font-weight "600"}}
|
||||||
|
(subs first-name 0 81)
|
||||||
|
(when you?
|
||||||
|
[{:style {:color colors/black-light :font-weight "500" :font-size 13}}
|
||||||
|
(str " " (i18n/label :t/You))])
|
||||||
|
(when nickname
|
||||||
|
[{:style {:color colors/black-light :font-weight "500"}}
|
||||||
|
(str " " (subs second-name 0 81))])]
|
||||||
|
[react/text {:style {:color (if modal colors/white-persist colors/black)
|
||||||
|
:font-size (if profile? 15 13)
|
||||||
|
:line-height (if profile? 22 18)
|
||||||
|
:font-weight "600"
|
||||||
|
:letter-spacing -0.2}}
|
||||||
|
first-name]))))
|
||||||
|
|
||||||
(defn format-reply-author [from username current-public-key style outgoing]
|
(defn format-reply-author [from username current-public-key style outgoing]
|
||||||
(let [contact-name (str reply-symbol username)]
|
(let [contact-name (str reply-symbol username)]
|
||||||
(or (and (= from current-public-key)
|
(or (and (= from current-public-key)
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
[quo.react-native :as rn]
|
[quo.react-native :as rn]
|
||||||
[status-im.ui.screens.chat.audio-message.views :as audio-message]
|
[status-im.ui.screens.chat.audio-message.views :as audio-message]
|
||||||
[quo.react :as quo.react]
|
[quo.react :as quo.react]
|
||||||
|
[status-im.ui.screens.chat.message.message-old :as message-old]
|
||||||
[status-im.ui.screens.chat.message.message :as message]
|
[status-im.ui.screens.chat.message.message :as message]
|
||||||
[status-im.ui.screens.chat.stickers.views :as stickers]
|
[status-im.ui.screens.chat.stickers.views :as stickers]
|
||||||
[status-im.ui.screens.chat.styles.main :as style]
|
[status-im.ui.screens.chat.styles.main :as style]
|
||||||
|
@ -27,6 +28,7 @@
|
||||||
[status-im.ui.screens.chat.message.gap :as gap]
|
[status-im.ui.screens.chat.message.gap :as gap]
|
||||||
[status-im.ui.screens.chat.components.accessory :as accessory]
|
[status-im.ui.screens.chat.components.accessory :as accessory]
|
||||||
[status-im.ui.screens.chat.components.input :as components]
|
[status-im.ui.screens.chat.components.input :as components]
|
||||||
|
[status-im.ui.screens.chat.message.datemark-old :as message-datemark-old]
|
||||||
[status-im.ui.screens.chat.message.datemark :as message-datemark]
|
[status-im.ui.screens.chat.message.datemark :as message-datemark]
|
||||||
[status-im.ui.components.toolbar :as toolbar]
|
[status-im.ui.components.toolbar :as toolbar]
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
|
@ -37,7 +39,10 @@
|
||||||
[status-im.ui.screens.chat.sheets :as sheets]
|
[status-im.ui.screens.chat.sheets :as sheets]
|
||||||
[status-im.utils.debounce :as debounce]
|
[status-im.utils.debounce :as debounce]
|
||||||
[status-im.navigation.state :as navigation.state]
|
[status-im.navigation.state :as navigation.state]
|
||||||
[status-im.react-native.resources :as resources]))
|
[status-im.react-native.resources :as resources]
|
||||||
|
[status-im.ui.components.topbar :as topbar]
|
||||||
|
[quo2.foundations.colors :as quo2.colors]
|
||||||
|
[quo2.components.button :as quo2.button]))
|
||||||
|
|
||||||
(defn invitation-requests [chat-id admins]
|
(defn invitation-requests [chat-id admins]
|
||||||
(let [current-pk @(re-frame/subscribe [:multiaccount/public-key])
|
(let [current-pk @(re-frame/subscribe [:multiaccount/public-key])
|
||||||
|
@ -53,6 +58,18 @@
|
||||||
(i18n/label :t/group-membership-request)]]])))))
|
(i18n/label :t/group-membership-request)]]])))))
|
||||||
|
|
||||||
(defn add-contact-bar [public-key]
|
(defn add-contact-bar [public-key]
|
||||||
|
(when-not (or @(re-frame/subscribe [:contacts/contact-added? public-key])
|
||||||
|
@(re-frame/subscribe [:contacts/contact-blocked? public-key]))
|
||||||
|
[react/touchable-highlight
|
||||||
|
{:on-press
|
||||||
|
#(re-frame/dispatch [:contact.ui/add-to-contact-pressed public-key])
|
||||||
|
:accessibility-label :add-to-contacts-button}
|
||||||
|
[react/view {:style (merge (style/add-contact) {:background-color (quo2.colors/theme-colors quo2.colors/white quo2.colors/divider-dark)})}
|
||||||
|
[icons/icon :main-icons/add
|
||||||
|
{:color colors/blue}]
|
||||||
|
[react/i18n-text {:style style/add-contact-text :key :add-to-contacts}]]]))
|
||||||
|
|
||||||
|
(defn add-contact-bar-old [public-key]
|
||||||
(when-not (or @(re-frame/subscribe [:contacts/contact-added? public-key])
|
(when-not (or @(re-frame/subscribe [:contacts/contact-added? public-key])
|
||||||
@(re-frame/subscribe [:contacts/contact-blocked? public-key]))
|
@(re-frame/subscribe [:contacts/contact-blocked? public-key]))
|
||||||
[react/touchable-highlight
|
[react/touchable-highlight
|
||||||
|
@ -286,6 +303,29 @@
|
||||||
[react/view {:style (when platform/android? {:scaleY -1})}
|
[react/view {:style (when platform/android? {:scaleY -1})}
|
||||||
[chat.group/group-chat-footer chat-id invitation-admin]]))
|
[chat.group/group-chat-footer chat-id invitation-admin]]))
|
||||||
|
|
||||||
|
(defn render-fn-old [{:keys [outgoing type] :as message}
|
||||||
|
idx
|
||||||
|
_
|
||||||
|
{:keys [group-chat public? community? current-public-key space-keeper
|
||||||
|
chat-id show-input? message-pin-enabled edit-enabled in-pinned-view?]}]
|
||||||
|
[react/view {:style (when (and platform/android? (not in-pinned-view?)) {:scaleY -1})}
|
||||||
|
(if (= type :datemark)
|
||||||
|
[message-datemark-old/chat-datemark (:value message)]
|
||||||
|
(if (= type :gap)
|
||||||
|
[gap/gap message idx messages-list-ref false chat-id]
|
||||||
|
; message content
|
||||||
|
[message-old/chat-message
|
||||||
|
(assoc message
|
||||||
|
:incoming-group (and group-chat (not outgoing))
|
||||||
|
:group-chat group-chat
|
||||||
|
:public? public?
|
||||||
|
:community? community?
|
||||||
|
:current-public-key current-public-key
|
||||||
|
:show-input? show-input?
|
||||||
|
:message-pin-enabled message-pin-enabled
|
||||||
|
:edit-enabled edit-enabled)
|
||||||
|
space-keeper]))])
|
||||||
|
|
||||||
(defn render-fn [{:keys [outgoing type] :as message}
|
(defn render-fn [{:keys [outgoing type] :as message}
|
||||||
idx
|
idx
|
||||||
_
|
_
|
||||||
|
@ -342,6 +382,57 @@
|
||||||
:edit-enabled edit-enabled
|
:edit-enabled edit-enabled
|
||||||
:in-pinned-view? in-pinned-view?}))
|
:in-pinned-view? in-pinned-view?}))
|
||||||
|
|
||||||
|
(defn messages-view-old [{:keys [chat
|
||||||
|
bottom-space
|
||||||
|
pan-responder
|
||||||
|
mutual-contact-requests-enabled?
|
||||||
|
space-keeper
|
||||||
|
show-input?]}]
|
||||||
|
(let [{:keys [group-chat chat-type chat-id public? community-id admins]} chat
|
||||||
|
|
||||||
|
messages @(re-frame/subscribe [:chats/raw-chat-messages-stream chat-id])
|
||||||
|
one-to-one? (= chat-type constants/one-to-one-chat-type)
|
||||||
|
contact-added? (when one-to-one? @(re-frame/subscribe [:contacts/contact-added? chat-id]))
|
||||||
|
should-send-contact-request?
|
||||||
|
(and
|
||||||
|
mutual-contact-requests-enabled?
|
||||||
|
one-to-one?
|
||||||
|
(not contact-added?))]
|
||||||
|
|
||||||
|
;;do not use anonymous functions for handlers
|
||||||
|
[list/flat-list
|
||||||
|
(merge
|
||||||
|
pan-responder
|
||||||
|
{:key-fn list-key-fn
|
||||||
|
:ref list-ref
|
||||||
|
:header [list-header chat]
|
||||||
|
:footer [list-footer chat]
|
||||||
|
:data (when-not should-send-contact-request?
|
||||||
|
messages)
|
||||||
|
:render-data (get-render-data {:group-chat group-chat
|
||||||
|
:chat-id chat-id
|
||||||
|
:public? public?
|
||||||
|
:community-id community-id
|
||||||
|
:admins admins
|
||||||
|
:space-keeper space-keeper
|
||||||
|
:show-input? show-input?
|
||||||
|
:edit-enabled true
|
||||||
|
:in-pinned-view? false})
|
||||||
|
:render-fn render-fn-old
|
||||||
|
:on-viewable-items-changed on-viewable-items-changed
|
||||||
|
:on-end-reached list-on-end-reached
|
||||||
|
:on-scroll-to-index-failed identity ;;don't remove this
|
||||||
|
:content-container-style {:padding-top (+ bottom-space 16)
|
||||||
|
:padding-bottom 16}
|
||||||
|
:scroll-indicator-insets {:top bottom-space} ;;ios only
|
||||||
|
:keyboard-dismiss-mode :interactive
|
||||||
|
:keyboard-should-persist-taps :handled
|
||||||
|
:onMomentumScrollBegin state/start-scrolling
|
||||||
|
:onMomentumScrollEnd state/stop-scrolling
|
||||||
|
;;TODO https://github.com/facebook/react-native/issues/30034
|
||||||
|
:inverted (when platform/ios? true)
|
||||||
|
:style (when platform/android? {:scaleY -1})})]))
|
||||||
|
|
||||||
(defn messages-view [{:keys [chat
|
(defn messages-view [{:keys [chat
|
||||||
bottom-space
|
bottom-space
|
||||||
pan-responder
|
pan-responder
|
||||||
|
@ -393,13 +484,29 @@
|
||||||
:inverted (when platform/ios? true)
|
:inverted (when platform/ios? true)
|
||||||
:style (when platform/android? {:scaleY -1})})]))
|
:style (when platform/android? {:scaleY -1})})]))
|
||||||
|
|
||||||
|
(defn back-button []
|
||||||
|
[quo2.button/button {:type :grey
|
||||||
|
:size 32
|
||||||
|
:width 32
|
||||||
|
:accessibility-label "back-button"
|
||||||
|
:on-press #(re-frame/dispatch [:navigate-back])}
|
||||||
|
[icons/icon :main-icons/arrow-left {:color (quo2.colors/theme-colors quo2.colors/black quo2.colors/white)}]])
|
||||||
|
|
||||||
|
(defn search-button []
|
||||||
|
[quo2.button/button {:type :grey
|
||||||
|
:size 32
|
||||||
|
:width 32
|
||||||
|
:accessibility-label "search-button"}
|
||||||
|
[icons/icon :main-icons/search {:color (quo2.colors/theme-colors quo2.colors/black quo2.colors/white)}]])
|
||||||
|
|
||||||
(defn topbar-content []
|
(defn topbar-content []
|
||||||
(let [window-width @(re-frame/subscribe [:dimensions/window-width])
|
(let [window-width @(re-frame/subscribe [:dimensions/window-width])
|
||||||
{:keys [group-chat chat-id] :as chat-info} @(re-frame/subscribe [:chats/current-chat])]
|
{:keys [group-chat chat-id] :as chat-info} @(re-frame/subscribe [:chats/current-chat])]
|
||||||
[react/touchable-highlight {:on-press #(when-not group-chat
|
[react/view {:flex-direction :row :align-items :center :height 56}
|
||||||
(debounce/dispatch-and-chill [:chat.ui/show-profile chat-id] 1000))
|
[react/touchable-highlight {:on-press #(when-not group-chat
|
||||||
:style {:flex 1 :width (- window-width 120)}}
|
(debounce/dispatch-and-chill [:chat.ui/show-profile chat-id] 1000))
|
||||||
[toolbar-content/toolbar-content-view-inner chat-info]]))
|
:style {:flex 1 :margin-left 12 :width (- window-width 120)}}
|
||||||
|
[toolbar-content/toolbar-content-view-inner chat-info]]]))
|
||||||
|
|
||||||
(defn navigate-back-handler []
|
(defn navigate-back-handler []
|
||||||
(when (and (not @navigation.state/curr-modal) (= (get @re-frame.db/app-db :view-id) :chat))
|
(when (and (not @navigation.state/curr-modal) (= (get @re-frame.db/app-db :view-id) :chat))
|
||||||
|
@ -407,7 +514,15 @@
|
||||||
(re-frame/dispatch [:close-chat])
|
(re-frame/dispatch [:close-chat])
|
||||||
(re-frame/dispatch [:navigate-back])))
|
(re-frame/dispatch [:navigate-back])))
|
||||||
|
|
||||||
(defn topbar []
|
(defn topbar-content-old []
|
||||||
|
(let [window-width @(re-frame/subscribe [:dimensions/window-width])
|
||||||
|
{:keys [group-chat chat-id] :as chat-info} @(re-frame/subscribe [:chats/current-chat])]
|
||||||
|
[react/touchable-highlight {:on-press #(when-not group-chat
|
||||||
|
(debounce/dispatch-and-chill [:chat.ui/show-profile chat-id] 1000))
|
||||||
|
:style {:flex 1 :width (- window-width 120)}}
|
||||||
|
[toolbar-content/toolbar-content-view-inner chat-info]]))
|
||||||
|
|
||||||
|
(defn topbar-old []
|
||||||
;;we don't use topbar component, because we want chat view as simple (fast) as possible
|
;;we don't use topbar component, because we want chat view as simple (fast) as possible
|
||||||
[react/view {:height 56}
|
[react/view {:height 56}
|
||||||
[react/touchable-highlight {:on-press-in navigate-back-handler
|
[react/touchable-highlight {:on-press-in navigate-back-handler
|
||||||
|
@ -416,7 +531,7 @@
|
||||||
:padding-left 16}}
|
:padding-left 16}}
|
||||||
[icons/icon :main-icons/arrow-left {:color colors/black}]]
|
[icons/icon :main-icons/arrow-left {:color colors/black}]]
|
||||||
[react/view {:flex 1 :left 52 :right 52 :top 0 :bottom 0 :position :absolute}
|
[react/view {:flex 1 :left 52 :right 52 :top 0 :bottom 0 :position :absolute}
|
||||||
[topbar-content]]
|
[topbar-content-old]]
|
||||||
[react/touchable-highlight {:on-press-in #(re-frame/dispatch [:bottom-sheet/show-sheet
|
[react/touchable-highlight {:on-press-in #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||||
{:content (fn []
|
{:content (fn []
|
||||||
[sheets/current-chat-actions])
|
[sheets/current-chat-actions])
|
||||||
|
@ -427,6 +542,64 @@
|
||||||
:padding-right 16}}
|
:padding-right 16}}
|
||||||
[icons/icon :main-icons/more {:color colors/black}]]])
|
[icons/icon :main-icons/more {:color colors/black}]]])
|
||||||
|
|
||||||
|
(defn chat-render-old []
|
||||||
|
(let [bottom-space (reagent/atom 0)
|
||||||
|
panel-space (reagent/atom 52)
|
||||||
|
active-panel (reagent/atom nil)
|
||||||
|
position-y (animated/value 0)
|
||||||
|
pan-state (animated/value 0)
|
||||||
|
text-input-ref (quo.react/create-ref)
|
||||||
|
on-update #(when-not (zero? %) (reset! panel-space %))
|
||||||
|
pan-responder (accessory/create-pan-responder position-y pan-state)
|
||||||
|
space-keeper (get-space-keeper-ios bottom-space panel-space active-panel text-input-ref)
|
||||||
|
set-active-panel (get-set-active-panel active-panel)
|
||||||
|
on-close #(set-active-panel nil)]
|
||||||
|
(fn []
|
||||||
|
(let [{:keys [chat-id show-input? group-chat admins invitation-admin] :as chat}
|
||||||
|
;;we want to react only on these fields, do not use full chat map here
|
||||||
|
@(re-frame/subscribe [:chats/current-chat-chat-view])
|
||||||
|
mutual-contact-requests-enabled? @(re-frame/subscribe [:mutual-contact-requests/enabled?])
|
||||||
|
max-bottom-space (max @bottom-space @panel-space)]
|
||||||
|
[:<>
|
||||||
|
[topbar-old]
|
||||||
|
[connectivity/loading-indicator]
|
||||||
|
(when chat-id
|
||||||
|
(if group-chat
|
||||||
|
[invitation-requests chat-id admins]
|
||||||
|
(when-not mutual-contact-requests-enabled? [add-contact-bar-old chat-id])))
|
||||||
|
;;MESSAGES LIST
|
||||||
|
[messages-view-old {:chat chat
|
||||||
|
:bottom-space max-bottom-space
|
||||||
|
:pan-responder pan-responder
|
||||||
|
:mutual-contact-requests-enabled? mutual-contact-requests-enabled?
|
||||||
|
:space-keeper space-keeper
|
||||||
|
:show-input? show-input?}]
|
||||||
|
(when (and group-chat invitation-admin)
|
||||||
|
[accessory/view {:y position-y
|
||||||
|
:on-update-inset on-update}
|
||||||
|
[invitation-bar chat-id]])
|
||||||
|
[components/autocomplete-mentions text-input-ref max-bottom-space]
|
||||||
|
(when show-input?
|
||||||
|
;; NOTE: this only accepts two children
|
||||||
|
[accessory/view {:y position-y
|
||||||
|
:pan-state pan-state
|
||||||
|
:has-panel (boolean @active-panel)
|
||||||
|
:on-close on-close
|
||||||
|
:on-update-inset on-update}
|
||||||
|
[react/view
|
||||||
|
[edit/edit-message-auto-focus-wrapper text-input-ref]
|
||||||
|
[reply/reply-message-auto-focus-wrapper text-input-ref]
|
||||||
|
;; We set the key so we can force a re-render as
|
||||||
|
;; it does not rely on ratom but just atoms
|
||||||
|
^{:key (str @components/chat-input-key "chat-input")}
|
||||||
|
[components/chat-toolbar
|
||||||
|
{:chat-id chat-id
|
||||||
|
:active-panel @active-panel
|
||||||
|
:set-active-panel set-active-panel
|
||||||
|
:text-input-ref text-input-ref}]
|
||||||
|
[contact-request/contact-request-message-auto-focus-wrapper text-input-ref]]
|
||||||
|
[bottom-sheet @active-panel]])]))))
|
||||||
|
|
||||||
(defn chat-render []
|
(defn chat-render []
|
||||||
(let [bottom-space (reagent/atom 0)
|
(let [bottom-space (reagent/atom 0)
|
||||||
panel-space (reagent/atom 52)
|
panel-space (reagent/atom 52)
|
||||||
|
@ -446,7 +619,15 @@
|
||||||
mutual-contact-requests-enabled? @(re-frame/subscribe [:mutual-contact-requests/enabled?])
|
mutual-contact-requests-enabled? @(re-frame/subscribe [:mutual-contact-requests/enabled?])
|
||||||
max-bottom-space (max @bottom-space @panel-space)]
|
max-bottom-space (max @bottom-space @panel-space)]
|
||||||
[:<>
|
[:<>
|
||||||
[topbar]
|
;; It is better to not use topbar component because of performance
|
||||||
|
[topbar/topbar {:navigation :none
|
||||||
|
:left-component [react/view {:flex-direction :row :margin-left 16}
|
||||||
|
[back-button]]
|
||||||
|
:title-component [topbar-content]
|
||||||
|
:right-component [react/view {:flex-direction :row :margin-right 16}
|
||||||
|
[search-button]]
|
||||||
|
:border-bottom false
|
||||||
|
:new-ui? true}]
|
||||||
[connectivity/loading-indicator]
|
[connectivity/loading-indicator]
|
||||||
(when chat-id
|
(when chat-id
|
||||||
(if group-chat
|
(if group-chat
|
||||||
|
@ -485,6 +666,14 @@
|
||||||
[contact-request/contact-request-message-auto-focus-wrapper text-input-ref]]
|
[contact-request/contact-request-message-auto-focus-wrapper text-input-ref]]
|
||||||
[bottom-sheet @active-panel]])]))))
|
[bottom-sheet @active-panel]])]))))
|
||||||
|
|
||||||
|
(defn chat-old []
|
||||||
|
(reagent/create-class
|
||||||
|
{:component-did-mount (fn []
|
||||||
|
(react/hw-back-remove-listener navigate-back-handler)
|
||||||
|
(react/hw-back-add-listener navigate-back-handler))
|
||||||
|
:component-will-unmount (fn [] (react/hw-back-remove-listener navigate-back-handler))
|
||||||
|
:reagent-render chat-render-old}))
|
||||||
|
|
||||||
(defn chat []
|
(defn chat []
|
||||||
(reagent/create-class
|
(reagent/create-class
|
||||||
{:component-did-mount (fn []
|
{:component-did-mount (fn []
|
||||||
|
|
|
@ -148,7 +148,7 @@
|
||||||
text]])
|
text]])
|
||||||
|
|
||||||
(defn community-chat-item [{:keys [chat-id] :as home-item} _ _ _]
|
(defn community-chat-item [{:keys [chat-id] :as home-item} _ _ _]
|
||||||
[inner-item/home-list-item
|
[inner-item/home-list-item-old
|
||||||
;; We want communities to behave as public chats when it comes to
|
;; We want communities to behave as public chats when it comes to
|
||||||
;; unread indicator
|
;; unread indicator
|
||||||
(assoc home-item :public? true)
|
(assoc home-item :public? true)
|
||||||
|
@ -271,7 +271,7 @@
|
||||||
[community-chat-list id categories false from-chat]
|
[community-chat-list id categories false from-chat]
|
||||||
[community-channel-preview-list id chats])
|
[community-channel-preview-list id chats])
|
||||||
(when admin
|
(when admin
|
||||||
[components.plus-button/plus-button
|
[components.plus-button/plus-button-old
|
||||||
{:on-press #(>evt [:bottom-sheet/show-sheet
|
{:on-press #(>evt [:bottom-sheet/show-sheet
|
||||||
{:content (fn []
|
{:content (fn []
|
||||||
[community-plus-actions community])}])
|
[community-plus-actions community])}])
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
[quo/checkbox {:value selected
|
[quo/checkbox {:value selected
|
||||||
:on-change on-change}]]
|
:on-change on-change}]]
|
||||||
[react/view {:flex 1}
|
[react/view {:flex 1}
|
||||||
[inner-item/home-list-item
|
[inner-item/home-list-item-old
|
||||||
(assoc home-item :public? true)
|
(assoc home-item :public? true)
|
||||||
{:on-press on-change}]]]))
|
{:on-press on-change}]]]))
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
{:title first-name
|
{:title first-name
|
||||||
:subtitle second-name
|
:subtitle second-name
|
||||||
:accessibility-label :member-item
|
:accessibility-label :member-item
|
||||||
:icon [chat-icon/profile-photo-plus-dot-view
|
:icon [chat-icon/profile-photo-plus-dot-view-old
|
||||||
{:public-key public-key
|
{:public-key public-key
|
||||||
:photo-path (multiaccounts/displayed-photo member)}]
|
:photo-path (multiaccounts/displayed-photo member)}]
|
||||||
:accessory (when (not= public-key my-public-key)
|
:accessory (when (not= public-key my-public-key)
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
:on-press #(show-delete-chat-confirmation community-id chat-id)}
|
:on-press #(show-delete-chat-confirmation community-id chat-id)}
|
||||||
[icons/icon :main-icons/delete-circle {:no-color true}]]
|
[icons/icon :main-icons/delete-circle {:no-color true}]]
|
||||||
[rn/view {:flex 1}
|
[rn/view {:flex 1}
|
||||||
[inner-item/home-list-item (assoc home-item :edit? true) {:active-opacity 1}]]
|
[inner-item/home-list-item-old (assoc home-item :edit? true) {:active-opacity 1}]]
|
||||||
[rn/touchable-opacity {:on-long-press drag
|
[rn/touchable-opacity {:on-long-press drag
|
||||||
:delay-long-press 100
|
:delay-long-press 100
|
||||||
:accessibility-label :chat-drag-handle
|
:accessibility-label :chat-drag-handle
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
[quo/list-item
|
[quo/list-item
|
||||||
{:title first-name
|
{:title first-name
|
||||||
:subtitle second-name
|
:subtitle second-name
|
||||||
:icon [chat-icon.screen/profile-photo-plus-dot-view
|
:icon [chat-icon.screen/profile-photo-plus-dot-view-old
|
||||||
{:public-key public-key
|
{:public-key public-key
|
||||||
:photo-path (multiaccounts/displayed-photo contact)}]
|
:photo-path (multiaccounts/displayed-photo contact)}]
|
||||||
:chevron true
|
:chevron true
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
[react/view {:flex 1}
|
[react/view {:flex 1}
|
||||||
[react/view {:padding-horizontal 16
|
[react/view {:padding-horizontal 16
|
||||||
:padding-vertical 10}
|
:padding-vertical 10}
|
||||||
[search-input/search-input
|
[search-input/search-input-old
|
||||||
{:search-active? search-active?
|
{:search-active? search-active?
|
||||||
:search-filter search-filter
|
:search-filter search-filter
|
||||||
:on-cancel #(re-frame/dispatch [:search/currency-filter-changed nil])
|
:on-cancel #(re-frame/dispatch [:search/currency-filter-changed nil])
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
[status-im.ui.components.topbar :as topbar]
|
[status-im.ui.components.topbar :as topbar]
|
||||||
[status-im.ui.screens.chat.utils :as chat.utils]
|
[status-im.ui.screens.chat.utils :as chat.utils]
|
||||||
[status-im.ui.components.toolbar :as toolbar]
|
[status-im.ui.components.toolbar :as toolbar]
|
||||||
[status-im.ui.screens.chat.message.message :as message]
|
[status-im.ui.screens.chat.message.message-old :as message]
|
||||||
[status-im.ui.screens.chat.photos :as photos]
|
[status-im.ui.screens.chat.photos :as photos]
|
||||||
[status-im.ui.screens.profile.components.views :as profile.components]
|
[status-im.ui.screens.profile.components.views :as profile.components]
|
||||||
[status-im.utils.debounce :as debounce]
|
[status-im.utils.debounce :as debounce]
|
||||||
|
@ -639,10 +639,10 @@
|
||||||
(views/defview my-name []
|
(views/defview my-name []
|
||||||
(views/letsubs [contact-name [:multiaccount/preferred-name]]
|
(views/letsubs [contact-name [:multiaccount/preferred-name]]
|
||||||
(when-not (string/blank? contact-name)
|
(when-not (string/blank? contact-name)
|
||||||
(chat.utils/format-author {:names {:ens-name
|
(chat.utils/format-author-old {:names {:ens-name
|
||||||
(str "@"
|
(str "@"
|
||||||
(or (stateofus/username contact-name)
|
(or (stateofus/username contact-name)
|
||||||
contact-name))}}))))
|
contact-name))}}))))
|
||||||
|
|
||||||
(views/defview registered [names {:keys [preferred-name] :as account} _ registrations]
|
(views/defview registered [names {:keys [preferred-name] :as account} _ registrations]
|
||||||
[react/view {:style {:flex 1}}
|
[react/view {:style {:flex 1}}
|
||||||
|
|
|
@ -149,8 +149,8 @@
|
||||||
(fn [{:keys [contacts no-contacts-label toggle-fn allow-new-users?]}]
|
(fn [{:keys [contacts no-contacts-label toggle-fn allow-new-users?]}]
|
||||||
[react/view {:style {:flex 1}}
|
[react/view {:style {:flex 1}}
|
||||||
[react/view {:style (styles/search-container)}
|
[react/view {:style (styles/search-container)}
|
||||||
[search/search-input {:on-cancel #(reset! search-value nil)
|
[search/search-input-old {:on-cancel #(reset! search-value nil)
|
||||||
:on-change #(reset! search-value %)}]]
|
:on-change #(reset! search-value %)}]]
|
||||||
[react/view {:style {:flex 1
|
[react/view {:style {:flex 1
|
||||||
:padding-vertical 8}}
|
:padding-vertical 8}}
|
||||||
(if (seq contacts)
|
(if (seq contacts)
|
||||||
|
|
|
@ -9,11 +9,10 @@
|
||||||
|
|
||||||
(def public-unread
|
(def public-unread
|
||||||
{:background-color colors/blue
|
{:background-color colors/blue
|
||||||
:border-radius 6
|
:border-radius 5
|
||||||
:margin-right 5
|
:margin-right 16
|
||||||
:margin-bottom 5
|
:width 10
|
||||||
:width 12
|
:height 10})
|
||||||
:height 12})
|
|
||||||
|
|
||||||
(def datetime-text
|
(def datetime-text
|
||||||
{:color colors/text-gray
|
{:color colors/text-gray
|
||||||
|
|
|
@ -18,13 +18,18 @@
|
||||||
[status-im.add-new.db :as db]
|
[status-im.add-new.db :as db]
|
||||||
[status-im.utils.debounce :as debounce]
|
[status-im.utils.debounce :as debounce]
|
||||||
[status-im.utils.utils :as utils]
|
[status-im.utils.utils :as utils]
|
||||||
[quo.components.safe-area :as safe-area]
|
|
||||||
[status-im.ui.components.topbar :as topbar]
|
[status-im.ui.components.topbar :as topbar]
|
||||||
[status-im.ui.components.plus-button :as components.plus-button]
|
[status-im.ui.components.plus-button :as components.plus-button]
|
||||||
[status-im.ui.screens.chat.sheets :as sheets]
|
[status-im.ui.screens.chat.sheets :as sheets]
|
||||||
[status-im.ui.components.tabbar.core :as tabbar]
|
[status-im.ui.components.tabbar.core :as tabbar]
|
||||||
[status-im.ui.components.invite.views :as invite]
|
[status-im.ui.components.invite.views :as invite]
|
||||||
[status-im.utils.config :as config])
|
[status-im.utils.config :as config]
|
||||||
|
[quo2.components.text :as quo2.text]
|
||||||
|
[status-im.qr-scanner.core :as qr-scanner]
|
||||||
|
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
|
||||||
|
[status-im.ui.components.chat-icon.styles :as chat-icon.styles]
|
||||||
|
[quo2.foundations.colors :as quo2.colors]
|
||||||
|
[quo2.components.button :as quo2.button])
|
||||||
(:require-macros [status-im.utils.views :as views]))
|
(:require-macros [status-im.utils.views :as views]))
|
||||||
|
|
||||||
(defn home-tooltip-view []
|
(defn home-tooltip-view []
|
||||||
|
@ -71,6 +76,26 @@
|
||||||
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
|
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
|
||||||
(debounce/debounce-and-dispatch [:new-chat/set-new-identity text] 300))}]])
|
(debounce/debounce-and-dispatch [:new-chat/set-new-identity text] 300))}]])
|
||||||
|
|
||||||
|
(defn search-input-wrapper-old [search-filter chats-empty]
|
||||||
|
[react/view {:padding-horizontal 16
|
||||||
|
:padding-vertical 10}
|
||||||
|
[search-input/search-input-old
|
||||||
|
{:search-active? search-active?
|
||||||
|
:search-filter search-filter
|
||||||
|
:on-cancel #(re-frame/dispatch [:search/home-filter-changed nil])
|
||||||
|
:on-blur (fn []
|
||||||
|
(when chats-empty
|
||||||
|
(re-frame/dispatch [:search/home-filter-changed nil]))
|
||||||
|
(re-frame/dispatch [::new-chat/clear-new-identity]))
|
||||||
|
:on-focus (fn [search-filter]
|
||||||
|
(when-not search-filter
|
||||||
|
(re-frame/dispatch [:search/home-filter-changed ""])
|
||||||
|
(re-frame/dispatch [::new-chat/clear-new-identity])))
|
||||||
|
:on-change (fn [text]
|
||||||
|
(re-frame/dispatch [:search/home-filter-changed text])
|
||||||
|
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
|
||||||
|
(debounce/debounce-and-dispatch [:new-chat/set-new-identity text] 300))}]])
|
||||||
|
|
||||||
(defn start-suggestion [search-value]
|
(defn start-suggestion [search-value]
|
||||||
(let [{:keys [state ens-name public-key]}
|
(let [{:keys [state ens-name public-key]}
|
||||||
@(re-frame/subscribe [:contacts/new-identity])
|
@(re-frame/subscribe [:contacts/new-identity])
|
||||||
|
@ -114,6 +139,23 @@
|
||||||
[sheets/actions home-item])}])}]
|
[sheets/actions home-item])}])}]
|
||||||
[communities.views/community-home-list-item home-item]))
|
[communities.views/community-home-list-item home-item]))
|
||||||
|
|
||||||
|
(defn render-fn-old [{:keys [chat-id] :as home-item}]
|
||||||
|
;; We use `chat-id` to distinguish communities from chats
|
||||||
|
(if chat-id
|
||||||
|
[inner-item/home-list-item-old
|
||||||
|
home-item
|
||||||
|
{:on-press (fn []
|
||||||
|
(re-frame/dispatch [:dismiss-keyboard])
|
||||||
|
(if (and @config/new-ui-enabled? platform/android?)
|
||||||
|
(re-frame/dispatch [:chat.ui/navigate-to-chat-nav2 chat-id])
|
||||||
|
(re-frame/dispatch [:chat.ui/navigate-to-chat chat-id]))
|
||||||
|
(re-frame/dispatch [:search/home-filter-changed nil])
|
||||||
|
(re-frame/dispatch [:accept-all-activity-center-notifications-from-chat chat-id]))
|
||||||
|
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||||
|
{:content (fn []
|
||||||
|
[sheets/actions home-item])}])}]
|
||||||
|
[communities.views/community-home-list-item home-item]))
|
||||||
|
|
||||||
(defn chat-list-key-fn [item]
|
(defn chat-list-key-fn [item]
|
||||||
(or (:chat-id item) (:id item)))
|
(or (:chat-id item) (:id item)))
|
||||||
|
|
||||||
|
@ -145,6 +187,31 @@
|
||||||
[home-tooltip-view]
|
[home-tooltip-view]
|
||||||
[react/view {:height 68}])}])))
|
[react/view {:height 68}])}])))
|
||||||
|
|
||||||
|
(views/defview communities-and-chats-old []
|
||||||
|
(views/letsubs [{:keys [items search-filter]} [:home-items]
|
||||||
|
hide-home-tooltip? [:hide-home-tooltip?]]
|
||||||
|
(if (and (empty? items)
|
||||||
|
(empty? search-filter)
|
||||||
|
hide-home-tooltip?
|
||||||
|
(not @search-active?))
|
||||||
|
[welcome-blank-page]
|
||||||
|
[list/flat-list
|
||||||
|
{:key-fn chat-list-key-fn
|
||||||
|
:getItemLayout get-item-layout
|
||||||
|
:on-end-reached #(re-frame/dispatch [:chat.ui/show-more-chats])
|
||||||
|
:keyboard-should-persist-taps :always
|
||||||
|
:data items
|
||||||
|
:render-fn render-fn-old
|
||||||
|
:header [:<>
|
||||||
|
(when (or (seq items) @search-active? (seq search-filter))
|
||||||
|
[search-input-wrapper-old search-filter (empty? items)])
|
||||||
|
(when (and (empty? items)
|
||||||
|
(or @search-active? (seq search-filter)))
|
||||||
|
[start-suggestion search-filter])]
|
||||||
|
:footer (if (and (not hide-home-tooltip?) (not @search-active?))
|
||||||
|
[home-tooltip-view]
|
||||||
|
[react/view {:height 68}])}])))
|
||||||
|
|
||||||
(views/defview chats-list []
|
(views/defview chats-list []
|
||||||
(views/letsubs [loading? [:chats/loading?]]
|
(views/letsubs [loading? [:chats/loading?]]
|
||||||
[:<>
|
[:<>
|
||||||
|
@ -154,6 +221,15 @@
|
||||||
[react/activity-indicator {:animating true}]]
|
[react/activity-indicator {:animating true}]]
|
||||||
[communities-and-chats])]))
|
[communities-and-chats])]))
|
||||||
|
|
||||||
|
(views/defview chats-list-old []
|
||||||
|
(views/letsubs [loading? [:chats/loading?]]
|
||||||
|
[:<>
|
||||||
|
[connectivity/loading-indicator]
|
||||||
|
(if loading?
|
||||||
|
[react/view {:flex 1 :align-items :center :justify-content :center}
|
||||||
|
[react/activity-indicator {:animating true}]]
|
||||||
|
[communities-and-chats-old])]))
|
||||||
|
|
||||||
(views/defview plus-button []
|
(views/defview plus-button []
|
||||||
(views/letsubs [logging-in? [:multiaccounts/login]]
|
(views/letsubs [logging-in? [:multiaccounts/login]]
|
||||||
[components.plus-button/plus-button
|
[components.plus-button/plus-button
|
||||||
|
@ -162,7 +238,33 @@
|
||||||
:loading logging-in?
|
:loading logging-in?
|
||||||
:accessibility-label :new-chat-button}]))
|
:accessibility-label :new-chat-button}]))
|
||||||
|
|
||||||
|
(views/defview plus-button-old []
|
||||||
|
(views/letsubs [logging-in? [:multiaccounts/login]]
|
||||||
|
[components.plus-button/plus-button-old
|
||||||
|
{:on-press (when-not logging-in?
|
||||||
|
#(re-frame/dispatch [:bottom-sheet/show-sheet :add-new {}]))
|
||||||
|
:loading logging-in?
|
||||||
|
:accessibility-label :new-chat-button}]))
|
||||||
|
|
||||||
(views/defview notifications-button []
|
(views/defview notifications-button []
|
||||||
|
(views/letsubs [notif-count [:activity.center/notifications-count]]
|
||||||
|
[react/view
|
||||||
|
[quo2.button/button {:type :grey
|
||||||
|
:size 32
|
||||||
|
:width 32
|
||||||
|
:style {:margin-left 12}
|
||||||
|
:accessibility-label :notifications-button
|
||||||
|
:on-press #(do
|
||||||
|
(re-frame/dispatch [:mark-all-activity-center-notifications-as-read])
|
||||||
|
(re-frame/dispatch [:navigate-to :notifications-center]))}
|
||||||
|
[icons/icon :main-icons/notification2 {:color (quo2.colors/theme-colors quo2.colors/black quo2.colors/white)}]]
|
||||||
|
(when (pos? notif-count)
|
||||||
|
[react/view {:style (merge (styles/counter-public-container) {:top 5 :right 5})
|
||||||
|
:pointer-events :none}
|
||||||
|
[react/view {:style styles/counter-public
|
||||||
|
:accessibility-label :notifications-unread-badge}]])]))
|
||||||
|
|
||||||
|
(views/defview notifications-button-old []
|
||||||
(views/letsubs [notif-count [:activity.center/notifications-count]]
|
(views/letsubs [notif-count [:activity.center/notifications-count]]
|
||||||
[react/view
|
[react/view
|
||||||
[quo/button {:type :icon
|
[quo/button {:type :icon
|
||||||
|
@ -179,19 +281,57 @@
|
||||||
[react/view {:style styles/counter-public
|
[react/view {:style styles/counter-public
|
||||||
:accessibility-label :notifications-unread-badge}]])]))
|
:accessibility-label :notifications-unread-badge}]])]))
|
||||||
|
|
||||||
|
(defn qr-button []
|
||||||
|
[quo2.button/button {:type :grey
|
||||||
|
:accessibility-label "qr-button"
|
||||||
|
:size 32
|
||||||
|
:width 32
|
||||||
|
:style {:margin-left 12}
|
||||||
|
:on-press #(do
|
||||||
|
(re-frame/dispatch [::qr-scanner/scan-code
|
||||||
|
{:handler ::qr-scanner/on-scan-success}]))}
|
||||||
|
[icons/icon :main-icons/qr2 {:color (quo2.colors/theme-colors quo2.colors/black quo2.colors/white)}]])
|
||||||
|
|
||||||
|
(defn scan-button []
|
||||||
|
[quo2.button/button {:type :grey
|
||||||
|
:size 32
|
||||||
|
:width 32
|
||||||
|
:accessibility-label "scan-button"
|
||||||
|
:on-press #(do
|
||||||
|
(re-frame/dispatch [::qr-scanner/scan-code
|
||||||
|
{:handler ::qr-scanner/on-scan-success}]))}
|
||||||
|
[icons/icon :main-icons/scan2 {:color (quo2.colors/theme-colors quo2.colors/black quo2.colors/white)}]])
|
||||||
|
|
||||||
|
(views/defview profile-button []
|
||||||
|
(views/letsubs [{:keys [public-key preferred-name emoji]} [:multiaccount]]
|
||||||
|
[react/view
|
||||||
|
[chat-icon.screen/emoji-chat-icon-view public-key false preferred-name emoji
|
||||||
|
{:size 28
|
||||||
|
:chat-icon chat-icon.styles/chat-icon-chat-list}]]))
|
||||||
|
|
||||||
(defn home []
|
(defn home []
|
||||||
[safe-area/consumer
|
[react/keyboard-avoiding-view {:style {:flex 1 :background-color (quo2.colors/theme-colors quo2.colors/neutral-5 quo2.colors/switcher-background)}
|
||||||
(fn [insets]
|
:ignore-offset true}
|
||||||
[react/keyboard-avoiding-view {:style {:flex 1 :padding-top (:top insets)}
|
[topbar/topbar {:navigation :none
|
||||||
:ignore-offset true}
|
:use-insets true
|
||||||
[topbar/topbar {:title (i18n/label :t/chat)
|
:background (quo2.colors/theme-colors quo2.colors/neutral-5 quo2.colors/switcher-background)
|
||||||
:navigation :none
|
:left-component [react/view {:flex-direction :row :margin-left 16}
|
||||||
:right-component [react/view {:flex-direction :row :margin-right 16}
|
[profile-button]]
|
||||||
[connectivity/connectivity-button]
|
:right-component [react/view {:flex-direction :row :margin-right 16}
|
||||||
[notifications-button]]}]
|
[scan-button]
|
||||||
[chats-list]
|
[qr-button]
|
||||||
[plus-button]
|
[notifications-button]]
|
||||||
[tabbar/tabs-counts-subscriptions]])])
|
:border-bottom false}]
|
||||||
|
[react/view {:flex-direction :row
|
||||||
|
:justify-content :space-between
|
||||||
|
:align-items :center
|
||||||
|
:margin-horizontal 16
|
||||||
|
:margin-top 15
|
||||||
|
:margin-bottom 8}
|
||||||
|
[quo2.text/text {:size :heading-1 :weight :semi-bold} (i18n/label :t/messages)]
|
||||||
|
[plus-button]]
|
||||||
|
[chats-list]
|
||||||
|
[tabbar/tabs-counts-subscriptions]])
|
||||||
|
|
||||||
(defn home-old []
|
(defn home-old []
|
||||||
[react/keyboard-avoiding-view {:style {:flex 1}
|
[react/keyboard-avoiding-view {:style {:flex 1}
|
||||||
|
@ -200,7 +340,7 @@
|
||||||
:navigation :none
|
:navigation :none
|
||||||
:right-component [react/view {:flex-direction :row :margin-right 16}
|
:right-component [react/view {:flex-direction :row :margin-right 16}
|
||||||
[connectivity/connectivity-button]
|
[connectivity/connectivity-button]
|
||||||
[notifications-button]]}]
|
[notifications-button-old]]}]
|
||||||
[chats-list]
|
[chats-list-old]
|
||||||
[plus-button]
|
[plus-button-old]
|
||||||
[tabbar/tabs-counts-subscriptions]])
|
[tabbar/tabs-counts-subscriptions]])
|
|
@ -12,7 +12,10 @@
|
||||||
[status-im.ui.components.icons.icons :as icons]
|
[status-im.ui.components.icons.icons :as icons]
|
||||||
[status-im.utils.core :as utils]
|
[status-im.utils.core :as utils]
|
||||||
[status-im.utils.datetime :as time]
|
[status-im.utils.datetime :as time]
|
||||||
[status-im.ui.components.chat-icon.styles :as chat-icon.styles]))
|
[status-im.ui.components.chat-icon.styles :as chat-icon.styles]
|
||||||
|
[quo2.components.text :as quo2.text]
|
||||||
|
[status-im.utils.utils :as utils.utils]
|
||||||
|
[quo2.foundations.colors :as quo2.colors]))
|
||||||
|
|
||||||
(defn preview-label [label-key label-fn]
|
(defn preview-label [label-key label-fn]
|
||||||
[react/text {:style styles/last-message-text
|
[react/text {:style styles/last-message-text
|
||||||
|
@ -116,6 +119,22 @@
|
||||||
(defn unviewed-indicator [{:keys [unviewed-mentions-count
|
(defn unviewed-indicator [{:keys [unviewed-mentions-count
|
||||||
unviewed-messages-count
|
unviewed-messages-count
|
||||||
public?]}]
|
public?]}]
|
||||||
|
(when (pos? unviewed-messages-count)
|
||||||
|
[react/view {:position :absolute :right 16}
|
||||||
|
(cond
|
||||||
|
(and public? (not (pos? unviewed-mentions-count)))
|
||||||
|
[react/view {:style styles/public-unread
|
||||||
|
:accessibility-label :unviewed-messages-public}]
|
||||||
|
|
||||||
|
(and public? (pos? unviewed-mentions-count))
|
||||||
|
[badge/message-counter unviewed-mentions-count]
|
||||||
|
|
||||||
|
:else
|
||||||
|
[badge/message-counter unviewed-messages-count])]))
|
||||||
|
|
||||||
|
(defn unviewed-indicator-old [{:keys [unviewed-mentions-count
|
||||||
|
unviewed-messages-count
|
||||||
|
public?]}]
|
||||||
(when (pos? unviewed-messages-count)
|
(when (pos? unviewed-messages-count)
|
||||||
[react/view {:position :absolute :right 16 :bottom 12}
|
[react/view {:position :absolute :right 16 :bottom 12}
|
||||||
(cond
|
(cond
|
||||||
|
@ -151,6 +170,23 @@
|
||||||
[icons/icon :main-icons/tiny-new-contact (icon-style)]))
|
[icons/icon :main-icons/tiny-new-contact (icon-style)]))
|
||||||
|
|
||||||
(defn chat-item-title [chat-id muted group-chat chat-name edit?]
|
(defn chat-item-title [chat-id muted group-chat chat-name edit?]
|
||||||
|
[quo2.text/text {:weight :semi-bold
|
||||||
|
:color (when muted :secondary)
|
||||||
|
:accessibility-label :chat-name-text
|
||||||
|
:ellipsize-mode :tail
|
||||||
|
:number-of-lines 1
|
||||||
|
:style {:position :absolute
|
||||||
|
:left 72
|
||||||
|
:top 10
|
||||||
|
:right (if edit? 50 90)}}
|
||||||
|
(if group-chat
|
||||||
|
(utils/truncate-str chat-name 30)
|
||||||
|
;; This looks a bit odd, but I would like only to subscribe
|
||||||
|
;; if it's a one-to-one. If wrapped in a component styling
|
||||||
|
;; won't be applied correctly.
|
||||||
|
(first @(re-frame/subscribe [:contacts/contact-two-names-by-identity chat-id])))])
|
||||||
|
|
||||||
|
(defn chat-item-title-old [chat-id muted group-chat chat-name edit?]
|
||||||
[quo/text {:weight :medium
|
[quo/text {:weight :medium
|
||||||
:color (when muted :secondary)
|
:color (when muted :secondary)
|
||||||
:accessibility-label :chat-name-text
|
:accessibility-label :chat-name-text
|
||||||
|
@ -168,12 +204,62 @@
|
||||||
(first @(re-frame/subscribe [:contacts/contact-two-names-by-identity chat-id])))])
|
(first @(re-frame/subscribe [:contacts/contact-two-names-by-identity chat-id])))])
|
||||||
|
|
||||||
(defn home-list-item [home-item opts]
|
(defn home-list-item [home-item opts]
|
||||||
|
(let [{:keys [chat-id chat-name color group-chat muted emoji highlight edit? public? unviewed-messages-count contacts]} home-item
|
||||||
|
background-color (when highlight (colors/get-color :interactive-02))]
|
||||||
|
[react/touchable-opacity (merge {:style {:height 64 :background-color background-color}} opts)
|
||||||
|
[:<>
|
||||||
|
(when (pos? unviewed-messages-count)
|
||||||
|
[react/view {:position :absolute :top 2 :left 8 :right 8 :bottom 2 :border-radius 16 :background-color quo2.colors/primary-50-opa-5}])
|
||||||
|
[chat-icon.screen/emoji-chat-icon-view chat-id group-chat chat-name emoji
|
||||||
|
{:container (assoc chat-icon.styles/container-chat-list
|
||||||
|
:top 12 :left 20 :position :absolute)
|
||||||
|
:size 32
|
||||||
|
:chat-icon chat-icon.styles/chat-icon-chat-list
|
||||||
|
:default-chat-icon (chat-icon.styles/default-chat-icon-chat-list color)
|
||||||
|
:default-chat-icon-text (if (string/blank? emoji)
|
||||||
|
(chat-icon.styles/default-chat-icon-text 40)
|
||||||
|
(chat-icon.styles/emoji-chat-icon-text 40))}]
|
||||||
|
[chat-item-title chat-id muted group-chat chat-name edit?]
|
||||||
|
(when-not edit?
|
||||||
|
[react/view {:height "100%" :justify-content :center}
|
||||||
|
[unviewed-indicator home-item]])
|
||||||
|
[react/view {:position :absolute :left 72 :top 32 :right 80}
|
||||||
|
(if public?
|
||||||
|
[quo2.text/text {:color :secondary
|
||||||
|
:number-of-lines 1
|
||||||
|
:ellipsize-mode :middle
|
||||||
|
:weight :medium
|
||||||
|
:style {:color (quo2.colors/theme-colors quo2.colors/neutral-50 quo2.colors/neutral-40)}}
|
||||||
|
(i18n/label :t/public)]
|
||||||
|
(if group-chat
|
||||||
|
[react/view {:flex-direction :row
|
||||||
|
:flex 1
|
||||||
|
:padding-right 16
|
||||||
|
:align-items :center}
|
||||||
|
[icons/icon :main-icons/tiny-group2
|
||||||
|
{:width 16
|
||||||
|
:height 16
|
||||||
|
:no-color true
|
||||||
|
:container-style {:width 16
|
||||||
|
:height 16
|
||||||
|
:margin-right 4}}]
|
||||||
|
[quo2.text/text {:weight :medium
|
||||||
|
:style {:color (quo2.colors/theme-colors quo2.colors/neutral-50 quo2.colors/neutral-40)}}
|
||||||
|
(i18n/label :t/members-count {:count (count contacts)})]]
|
||||||
|
[quo2.text/text {:monospace true
|
||||||
|
:weight :medium
|
||||||
|
:style {:color (quo2.colors/theme-colors quo2.colors/neutral-50 quo2.colors/neutral-40)}
|
||||||
|
:number-of-lines 1
|
||||||
|
:ellipsize-mode :middle}
|
||||||
|
(utils.utils/get-shortened-address chat-id)]))]]]))
|
||||||
|
|
||||||
|
(defn home-list-item-old [home-item opts]
|
||||||
(let [{:keys [chat-id chat-name color group-chat public? timestamp last-message muted emoji highlight edit?]} home-item
|
(let [{:keys [chat-id chat-name color group-chat public? timestamp last-message muted emoji highlight edit?]} home-item
|
||||||
background-color (when highlight (colors/get-color :interactive-02))]
|
background-color (when highlight (colors/get-color :interactive-02))]
|
||||||
[react/touchable-opacity (merge {:style {:height 64 :background-color background-color}} opts)
|
[react/touchable-opacity (merge {:style {:height 64 :background-color background-color}} opts)
|
||||||
[:<>
|
[:<>
|
||||||
[chat-item-icon muted (and group-chat (not public?)) (and group-chat public?)]
|
[chat-item-icon muted (and group-chat (not public?)) (and group-chat public?)]
|
||||||
[chat-icon.screen/emoji-chat-icon-view chat-id group-chat chat-name emoji
|
[chat-icon.screen/emoji-chat-icon-view-old chat-id group-chat chat-name emoji
|
||||||
{:container (assoc chat-icon.styles/container-chat-list
|
{:container (assoc chat-icon.styles/container-chat-list
|
||||||
:top 12 :left 16 :position :absolute)
|
:top 12 :left 16 :position :absolute)
|
||||||
:size 40
|
:size 40
|
||||||
|
@ -182,7 +268,7 @@
|
||||||
:default-chat-icon-text (if (string/blank? emoji)
|
:default-chat-icon-text (if (string/blank? emoji)
|
||||||
(chat-icon.styles/default-chat-icon-text 40)
|
(chat-icon.styles/default-chat-icon-text 40)
|
||||||
(chat-icon.styles/emoji-chat-icon-text 40))}]
|
(chat-icon.styles/emoji-chat-icon-text 40))}]
|
||||||
[chat-item-title chat-id muted group-chat chat-name edit?]
|
[chat-item-title-old chat-id muted group-chat chat-name edit?]
|
||||||
(when-not edit?
|
(when-not edit?
|
||||||
[:<>
|
[:<>
|
||||||
[react/text {:style styles/datetime-text
|
[react/text {:style styles/datetime-text
|
||||||
|
@ -192,5 +278,5 @@
|
||||||
(memo-timestamp (if (pos? (:whisper-timestamp last-message))
|
(memo-timestamp (if (pos? (:whisper-timestamp last-message))
|
||||||
(:whisper-timestamp last-message)
|
(:whisper-timestamp last-message)
|
||||||
timestamp))]
|
timestamp))]
|
||||||
[unviewed-indicator home-item]])
|
[unviewed-indicator-old home-item]])
|
||||||
[message-content-text (select-keys last-message [:content :content-type :community-id]) true]]]))
|
[message-content-text (select-keys last-message [:content :content-type :community-id]) true]]]))
|
|
@ -13,7 +13,7 @@
|
||||||
[status-im.ui.screens.profile.components.styles :as profile.components.styles]
|
[status-im.ui.screens.profile.components.styles :as profile.components.styles]
|
||||||
[status-im.ui.components.topbar :as topbar]
|
[status-im.ui.components.topbar :as topbar]
|
||||||
[status-im.ui.components.common.common :as components.common]
|
[status-im.ui.components.common.common :as components.common]
|
||||||
[status-im.ui.screens.chat.message.message :as message]
|
[status-im.ui.screens.chat.message.message-old :as message]
|
||||||
[status-im.ui.screens.chat.photos :as photos]
|
[status-im.ui.screens.chat.photos :as photos]
|
||||||
[status-im.ui.screens.chat.utils :as chat.utils]
|
[status-im.ui.screens.chat.utils :as chat.utils]
|
||||||
[status-im.utils.debounce :as debounce])
|
[status-im.utils.debounce :as debounce])
|
||||||
|
@ -109,7 +109,7 @@
|
||||||
:content-type constants/content-type-text}]
|
:content-type constants/content-type-text}]
|
||||||
[react/view {:margin-bottom 8 :margin-right 16}
|
[react/view {:margin-bottom 8 :margin-right 16}
|
||||||
[react/view {:padding-left 72}
|
[react/view {:padding-left 72}
|
||||||
(chat.utils/format-author contact)]
|
(chat.utils/format-author-old contact)]
|
||||||
[react/view {:flex-direction :row :align-items :flex-end}
|
[react/view {:flex-direction :row :align-items :flex-end}
|
||||||
[react/view {:padding-left 16 :padding-top 4}
|
[react/view {:padding-left 16 :padding-top 4}
|
||||||
[photos/photo (multiaccounts/displayed-photo contact) {:size 36}]]
|
[photos/photo (multiaccounts/displayed-photo contact) {:size 36}]]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
(ns status-im.ui.screens.profile.visibility-status.styles
|
(ns status-im.ui.screens.profile.visibility-status.styles
|
||||||
(:require [quo.design-system.colors :as colors]))
|
(:require [quo.design-system.colors :as colors]
|
||||||
|
[quo2.foundations.colors :as quo2.colors]))
|
||||||
|
|
||||||
(defn visibility-status-button-container []
|
(defn visibility-status-button-container []
|
||||||
{:background-color (:interactive-02 @colors/theme)
|
{:background-color (:interactive-02 @colors/theme)
|
||||||
|
@ -14,6 +15,14 @@
|
||||||
:padding-right 12})
|
:padding-right 12})
|
||||||
|
|
||||||
(defn visibility-status-dot [dot-color size]
|
(defn visibility-status-dot [dot-color size]
|
||||||
|
{:background-color dot-color
|
||||||
|
:width size
|
||||||
|
:height size
|
||||||
|
:border-radius (/ size 2)
|
||||||
|
:border-width 3.5
|
||||||
|
:border-color (quo2.colors/theme-colors quo2.colors/white quo2.colors/neutral-90)})
|
||||||
|
|
||||||
|
(defn visibility-status-dot-old [dot-color size]
|
||||||
{:background-color dot-color
|
{:background-color dot-color
|
||||||
:width size
|
:width size
|
||||||
:height size
|
:height size
|
||||||
|
@ -21,8 +30,8 @@
|
||||||
:border-width 1
|
:border-width 1
|
||||||
:border-color colors/white})
|
:border-color colors/white})
|
||||||
|
|
||||||
(defn visibility-status-profile-dot [color size border-width margin-left]
|
(defn visibility-status-profile-dot-old [color size border-width margin-left]
|
||||||
(merge (visibility-status-dot color size)
|
(merge (visibility-status-dot-old color size)
|
||||||
{:margin-right 6
|
{:margin-right 6
|
||||||
:margin-left margin-left
|
:margin-left margin-left
|
||||||
:border-width border-width}))
|
:border-width border-width}))
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
[status-im.utils.handlers :refer [<sub]]
|
[status-im.utils.handlers :refer [<sub]]
|
||||||
[status-im.utils.datetime :as datetime]
|
[status-im.utils.datetime :as datetime]
|
||||||
[quo.design-system.colors :as colors]
|
[quo.design-system.colors :as colors]
|
||||||
[clojure.string :as string]))
|
[clojure.string :as string]
|
||||||
|
[quo2.foundations.colors :as quo2.colors]))
|
||||||
|
|
||||||
;; Specs:
|
;; Specs:
|
||||||
;; :visibility-status-automatic
|
;; :visibility-status-automatic
|
||||||
|
@ -19,6 +20,26 @@
|
||||||
;; Display - Offline forever
|
;; Display - Offline forever
|
||||||
;; Note: Only send pings if the user interacted with the app in the last x minutes.
|
;; Note: Only send pings if the user interacted with the app in the last x minutes.
|
||||||
(def visibility-status-type-data
|
(def visibility-status-type-data
|
||||||
|
{constants/visibility-status-unknown
|
||||||
|
{:color colors/red
|
||||||
|
:title (i18n/label :t/error)}
|
||||||
|
constants/visibility-status-automatic
|
||||||
|
{:color quo2.colors/color-online
|
||||||
|
:title (i18n/label :t/status-automatic)
|
||||||
|
:subtitle (i18n/label :t/status-automatic-subtitle)}
|
||||||
|
constants/visibility-status-dnd
|
||||||
|
{:color colors/color-dnd
|
||||||
|
:title (i18n/label :t/status-dnd)
|
||||||
|
:subtitle (i18n/label :t/status-dnd-subtitle)}
|
||||||
|
constants/visibility-status-always-online
|
||||||
|
{:color quo2.colors/color-online
|
||||||
|
:title (i18n/label :t/status-always-online)}
|
||||||
|
constants/visibility-status-inactive
|
||||||
|
{:color colors/color-inactive
|
||||||
|
:title (i18n/label :t/status-inactive)
|
||||||
|
:subtitle (i18n/label :t/status-inactive-subtitle)}})
|
||||||
|
|
||||||
|
(def visibility-status-type-data-old
|
||||||
{constants/visibility-status-unknown
|
{constants/visibility-status-unknown
|
||||||
{:color colors/red
|
{:color colors/red
|
||||||
:title (i18n/label :t/error)}
|
:title (i18n/label :t/error)}
|
||||||
|
@ -63,11 +84,20 @@
|
||||||
[{:keys [status-type] :as visibility-status-update} my-icon?]
|
[{:keys [status-type] :as visibility-status-update} my-icon?]
|
||||||
(if my-icon?
|
(if my-icon?
|
||||||
(if (= status-type constants/visibility-status-inactive)
|
(if (= status-type constants/visibility-status-inactive)
|
||||||
colors/color-inactive colors/color-online)
|
colors/color-inactive quo2.colors/color-online)
|
||||||
(let [{:keys [real-status-type]}
|
(let [{:keys [real-status-type]}
|
||||||
(calculate-real-status-type-and-time-left visibility-status-update)]
|
(calculate-real-status-type-and-time-left visibility-status-update)]
|
||||||
(:color (get visibility-status-type-data real-status-type)))))
|
(:color (get visibility-status-type-data real-status-type)))))
|
||||||
|
|
||||||
|
(defn dot-color-old
|
||||||
|
[{:keys [status-type] :as visibility-status-update} my-icon?]
|
||||||
|
(if my-icon?
|
||||||
|
(if (= status-type constants/visibility-status-inactive)
|
||||||
|
colors/color-inactive colors/color-online)
|
||||||
|
(let [{:keys [real-status-type]}
|
||||||
|
(calculate-real-status-type-and-time-left visibility-status-update)]
|
||||||
|
(:color (get visibility-status-type-data-old real-status-type)))))
|
||||||
|
|
||||||
(defn my-icon? [public-key]
|
(defn my-icon? [public-key]
|
||||||
(or (string/blank? public-key)
|
(or (string/blank? public-key)
|
||||||
(= public-key (<sub [:multiaccount/public-key]))))
|
(= public-key (<sub [:multiaccount/public-key]))))
|
||||||
|
@ -77,16 +107,31 @@
|
||||||
(<sub [:multiaccount/current-user-visibility-status])
|
(<sub [:multiaccount/current-user-visibility-status])
|
||||||
(<sub [:visibility-status-updates/visibility-status-update public-key])))
|
(<sub [:visibility-status-updates/visibility-status-update public-key])))
|
||||||
|
|
||||||
(defn icon-visibility-status-dot [public-key container-size identicon?]
|
(defn icon-visibility-status-dot [public-key container-size _]
|
||||||
|
(let [my-icon? (my-icon? public-key)
|
||||||
|
visibility-status-update (visibility-status-update public-key my-icon?)
|
||||||
|
size (/ container-size 2.4)
|
||||||
|
margin -2
|
||||||
|
dot-color (dot-color visibility-status-update my-icon?)
|
||||||
|
accessibility-label (if (= dot-color quo2.colors/color-online)
|
||||||
|
:online-profile-photo-dot
|
||||||
|
:offline-profile-photo-dot)]
|
||||||
|
(merge (styles/visibility-status-dot dot-color size)
|
||||||
|
{:bottom margin
|
||||||
|
:right margin
|
||||||
|
:position :absolute
|
||||||
|
:accessibility-label accessibility-label})))
|
||||||
|
|
||||||
|
(defn icon-visibility-status-dot-old [public-key container-size identicon?]
|
||||||
(let [my-icon? (my-icon? public-key)
|
(let [my-icon? (my-icon? public-key)
|
||||||
visibility-status-update (visibility-status-update public-key my-icon?)
|
visibility-status-update (visibility-status-update public-key my-icon?)
|
||||||
size (/ container-size 4)
|
size (/ container-size 4)
|
||||||
margin (if identicon? (/ size 6) (/ size 7))
|
margin (if identicon? (/ size 6) (/ size 7))
|
||||||
dot-color (dot-color visibility-status-update my-icon?)
|
dot-color (dot-color-old visibility-status-update my-icon?)
|
||||||
accessibility-label (if (= dot-color colors/color-online)
|
accessibility-label (if (= dot-color colors/color-online)
|
||||||
:online-profile-photo-dot
|
:online-profile-photo-dot
|
||||||
:offline-profile-photo-dot)]
|
:offline-profile-photo-dot)]
|
||||||
(merge (styles/visibility-status-dot dot-color size)
|
(merge (styles/visibility-status-dot-old dot-color size)
|
||||||
{:bottom margin
|
{:bottom margin
|
||||||
:right margin
|
:right margin
|
||||||
:position :absolute
|
:position :absolute
|
||||||
|
|
|
@ -36,9 +36,9 @@
|
||||||
[border-width margin-left size] (if automatic? [1 -10 12] [0 6 10])]
|
[border-width margin-left size] (if automatic? [1 -10 12] [0 6 10])]
|
||||||
[:<>
|
[:<>
|
||||||
(when automatic?
|
(when automatic?
|
||||||
[rn/view {:style (styles/visibility-status-profile-dot
|
[rn/view {:style (styles/visibility-status-profile-dot-old
|
||||||
colors/color-inactive size border-width 6)}])
|
colors/color-inactive size border-width 6)}])
|
||||||
[rn/view {:style (styles/visibility-status-profile-dot
|
[rn/view {:style (styles/visibility-status-profile-dot-old
|
||||||
color size border-width margin-left)}]]))
|
color size border-width margin-left)}]]))
|
||||||
|
|
||||||
(defn visibility-status-button [on-press props]
|
(defn visibility-status-button [on-press props]
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
constants/visibility-status-automatic)
|
constants/visibility-status-automatic)
|
||||||
constants/visibility-status-automatic)
|
constants/visibility-status-automatic)
|
||||||
status-type)
|
status-type)
|
||||||
{:keys [color title]} (get utils/visibility-status-type-data status-type)]
|
{:keys [color title]} (get utils/visibility-status-type-data-old status-type)]
|
||||||
[rn/touchable-opacity
|
[rn/touchable-opacity
|
||||||
(merge
|
(merge
|
||||||
{:on-press on-press
|
{:on-press on-press
|
||||||
|
@ -97,7 +97,7 @@
|
||||||
|
|
||||||
(defn status-option [{:keys [request-close status-type]}]
|
(defn status-option [{:keys [request-close status-type]}]
|
||||||
(let [{:keys [color title subtitle]}
|
(let [{:keys [color title subtitle]}
|
||||||
(get utils/visibility-status-type-data status-type)]
|
(get utils/visibility-status-type-data-old status-type)]
|
||||||
[rn/touchable-opacity {:style {:padding 6}
|
[rn/touchable-opacity {:style {:padding 6}
|
||||||
:accessibility-label :visibility-status-option
|
:accessibility-label :visibility-status-option
|
||||||
:on-press #(status-option-pressed
|
:on-press #(status-option-pressed
|
||||||
|
|
|
@ -224,7 +224,7 @@
|
||||||
:hardwareBackButton {:dismissModalOnPress false
|
:hardwareBackButton {:dismissModalOnPress false
|
||||||
:popStackOnPress false}
|
:popStackOnPress false}
|
||||||
:topBar {:visible false}}
|
:topBar {:visible false}}
|
||||||
:component chat/chat}
|
:component chat/chat-old}
|
||||||
|
|
||||||
;Pinned messages
|
;Pinned messages
|
||||||
{:name :chat-pinned-messages
|
{:name :chat-pinned-messages
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
(ns status-im.ui.screens.status.views
|
(ns status-im.ui.screens.status.views
|
||||||
(:require [status-im.ui.screens.chat.message.message :as message]
|
(:require [status-im.ui.screens.chat.message.message-old :as message]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[quo.design-system.colors :as colors]
|
[quo.design-system.colors :as colors]
|
||||||
[status-im.utils.datetime :as datetime]
|
[status-im.utils.datetime :as datetime]
|
||||||
|
@ -210,5 +210,5 @@
|
||||||
:on-scroll-to-index-failed #()
|
:on-scroll-to-index-failed #()
|
||||||
:header [react/view {:height 8}]
|
:header [react/view {:height 8}]
|
||||||
:footer [react/view {:height 68}]}]))
|
:footer [react/view {:height 68}]}]))
|
||||||
[components.plus-button/plus-button
|
[components.plus-button/plus-button-old
|
||||||
{:on-press #(re-frame/dispatch [:open-modal :my-status])}]]))
|
{:on-press #(re-frame/dispatch [:open-modal :my-status])}]]))
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
(let [search-filter @(re-frame/subscribe [:search/recipient-filter])]
|
(let [search-filter @(re-frame/subscribe [:search/recipient-filter])]
|
||||||
[react/view {:padding-horizontal 16
|
[react/view {:padding-horizontal 16
|
||||||
:padding-vertical 10}
|
:padding-vertical 10}
|
||||||
[search-input/search-input
|
[search-input/search-input-old
|
||||||
{:search-active? search-active?
|
{:search-active? search-active?
|
||||||
:search-filter search-filter
|
:search-filter search-filter
|
||||||
:on-cancel #(re-frame/dispatch [:search/recipient-filter-changed nil])
|
:on-cancel #(re-frame/dispatch [:search/recipient-filter-changed nil])
|
||||||
|
|
|
@ -80,7 +80,7 @@
|
||||||
[react/view {:flex 1}
|
[react/view {:flex 1}
|
||||||
[react/view {:padding-horizontal 16
|
[react/view {:padding-horizontal 16
|
||||||
:padding-vertical 10}
|
:padding-vertical 10}
|
||||||
[search-input/search-input
|
[search-input/search-input-old
|
||||||
{:search-active? search-active?
|
{:search-active? search-active?
|
||||||
:search-filter search-filter
|
:search-filter search-filter
|
||||||
:on-cancel #(re-frame/dispatch [:search/token-filter-changed nil])
|
:on-cancel #(re-frame/dispatch [:search/token-filter-changed nil])
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
(i18n/label :t/select-token-to-receive))
|
(i18n/label :t/select-token-to-receive))
|
||||||
:modal? true}]
|
:modal? true}]
|
||||||
|
|
||||||
[search-input/search-input
|
[search-input/search-input-old
|
||||||
{:search-active? true}]
|
{:search-active? true}]
|
||||||
|
|
||||||
[react/scroll-view
|
[react/scroll-view
|
||||||
|
|
|
@ -1756,5 +1756,6 @@
|
||||||
"mutual-contact-requests": "Mutual contact requests",
|
"mutual-contact-requests": "Mutual contact requests",
|
||||||
"pending": "Pending",
|
"pending": "Pending",
|
||||||
"negative": "Negative",
|
"negative": "Negative",
|
||||||
"positive": "Positive"
|
"positive": "Positive",
|
||||||
|
"public": "Public"
|
||||||
}
|
}
|
||||||
|
|