clean old namespaces (#15980)
This commit is contained in:
parent
6975d6ac48
commit
86d5a3c4e6
|
@ -1,93 +0,0 @@
|
|||
(ns status-im.ui.screens.chat.image.preview.views
|
||||
(:require ["react-native-image-viewing" :default image-viewing]
|
||||
[quo.design-system.colors :as colors]
|
||||
[quo.platform :as platform]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.chat.models.images :as images]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.utils.share :as share]
|
||||
[taoensso.timbre :as log]
|
||||
[react-native.safe-area :as safe-area]))
|
||||
|
||||
(defn share
|
||||
[path]
|
||||
(share/open {:url (str (when platform/android? "file://") path)
|
||||
:type "image/jpeg"}
|
||||
#(log/debug "image shared successfully")
|
||||
#(log/error "could not share image")))
|
||||
|
||||
(defn header-options
|
||||
[]
|
||||
(fn [{:keys [message on-close]}]
|
||||
;; FIXME(Ferossgp): Bottom sheet doesn't work on Android because of
|
||||
;; https://github.com/software-mansion/react-native-gesture-handler/issues/139
|
||||
[react/view
|
||||
{:style {:flex-direction :row
|
||||
:background-color colors/black-transparent-86
|
||||
:border-radius 44
|
||||
:padding-vertical 8
|
||||
:padding-horizontal 12
|
||||
:position :absolute
|
||||
:right 0}}
|
||||
[react/touchable-opacity
|
||||
{:on-press (fn []
|
||||
(on-close)
|
||||
(re-frame/dispatch [:chat.ui/save-image-to-gallery
|
||||
(get-in message [:content :image])]))
|
||||
:style {:margin-right 10}
|
||||
:accessibility-label :save-button}
|
||||
[icons/icon :main-icons/download
|
||||
{:container-style {:width 24
|
||||
:height 24}
|
||||
:color colors/white-persist}]]
|
||||
[react/touchable-opacity
|
||||
{:on-press #(images/download-image-http (get-in message [:content :image]) share)
|
||||
:style {:margin-left 10}
|
||||
:accessibility-label :share-button}
|
||||
[icons/icon :main-icons/share-default
|
||||
{:container-style {:width 24
|
||||
:height 24}
|
||||
:color colors/white-persist}]]]))
|
||||
|
||||
(defn header
|
||||
[{:keys [on-close] :as props}]
|
||||
[react/view
|
||||
{:style {:padding-horizontal 15
|
||||
:padding-top (+ (safe-area/get-bottom) 50)}}
|
||||
[react/view {:style {:justify-content :center}}
|
||||
[react/touchable-opacity
|
||||
{:on-press on-close
|
||||
:style {:padding-vertical 11
|
||||
:border-radius 44}
|
||||
:accessibility-label :close-button}
|
||||
[react/view
|
||||
{:style {:background-color colors/black-transparent-86
|
||||
:border-radius 20
|
||||
:width 40
|
||||
:height 40
|
||||
:justify-content :center
|
||||
:align-items :center}}
|
||||
[icons/icon :main-icons/close
|
||||
{:container-style {:width 24
|
||||
:height 24}
|
||||
:color colors/white-persist}]]]
|
||||
[header-options props]]])
|
||||
|
||||
(defn preview-image
|
||||
[{{:keys [content] :as message} :message
|
||||
visible :visible
|
||||
on-close :on-close}]
|
||||
[:> image-viewing
|
||||
{:images #js [#js {:uri (:image content)}]
|
||||
:on-request-close on-close
|
||||
:hide-header-on-zoom false
|
||||
:hide-footer-on-zoom false
|
||||
:swipe-to-close-enabled platform/ios?
|
||||
:presentation-style "overFullScreen"
|
||||
:HeaderComponent #(reagent/as-element [header
|
||||
{:on-close on-close
|
||||
:message message}])
|
||||
:FooterComponent #(reagent/as-element [:<>])
|
||||
:visible visible}])
|
|
@ -1,262 +0,0 @@
|
|||
(ns status-im.ui.screens.chat.message.audio
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require ["react-native-blob-util" :default ReactNativeBlobUtil]
|
||||
[goog.string :as gstring]
|
||||
[quo.design-system.colors :as colors]
|
||||
[reagent.core :as reagent]
|
||||
[react-native.audio-toolkit :as audio]
|
||||
[status-im.ui.components.animation :as anim]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.slider :as slider]
|
||||
[status-im.ui.screens.chat.styles.message.audio :as style]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.utils.utils :as utils]
|
||||
[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 on-press]
|
||||
(let [color colors/blue]
|
||||
(if (= (:general @state-ref) :preparing)
|
||||
[react/view {:style (style/play-pause-container 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 false)
|
||||
:accessibility-label :play-pause-audio-message-button
|
||||
:color color}]])))
|
||||
|
||||
(defview message-content
|
||||
[{:keys [audio audio-duration-ms message-id]}]
|
||||
(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 #(play-pause base-params audio)]
|
||||
[react/view style/slider-container
|
||||
[slider/animated-slider
|
||||
(merge (style/slider)
|
||||
{: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)}
|
||||
(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,45 +0,0 @@
|
|||
(ns status-im.ui.screens.chat.styles.message.audio
|
||||
(:require [quo.design-system.colors :as colors]
|
||||
[status-im.ui.screens.chat.styles.message.message :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
|
||||
[]
|
||||
{:style (merge {:margin-left 12
|
||||
:height 34}
|
||||
(when platform/ios? {:margin-bottom 4}))
|
||||
:thumb-tint-color colors/white
|
||||
:minimum-track-tint-color colors/white
|
||||
:maximum-track-tint-color colors/white-transparent})
|
||||
|
||||
(defn play-pause-container
|
||||
[loading?]
|
||||
{:background-color colors/white-persist
|
||||
:width 28
|
||||
:height 28
|
||||
:padding (if loading? 4 2)
|
||||
:border-radius 15})
|
||||
|
||||
(def times-container
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between})
|
||||
|
||||
(defn timestamp
|
||||
[]
|
||||
(merge (message.style/audio-message-timestamp-text)
|
||||
{:margin-left 40}))
|
|
@ -3,7 +3,6 @@
|
|||
[quo2.foundations.colors :as quo2.colors]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.screens.chat.styles.photos :as photos]
|
||||
[quo2.foundations.typography :as typography]))
|
||||
|
||||
(defn style-message-text
|
||||
|
@ -34,13 +33,6 @@
|
|||
[]
|
||||
(merge message-timestamp {:opacity 0 :color "rgba(0,0,0,0)"}))
|
||||
|
||||
(defn message-timestamp-wrapper
|
||||
[]
|
||||
{:justify-content :center
|
||||
:margin-left 12 ;; horizontal margin is only required at the adjust side of the message.
|
||||
:margin-top 0
|
||||
:opacity 0})
|
||||
|
||||
(defn message-timestamp-text
|
||||
[]
|
||||
(merge message-timestamp
|
||||
|
@ -75,11 +67,6 @@
|
|||
:align-items :flex-start
|
||||
:margin-left 4})
|
||||
|
||||
(defn delivery-status
|
||||
[]
|
||||
{:align-self :flex-start
|
||||
:padding-left 8})
|
||||
|
||||
(defn pin-indicator
|
||||
[]
|
||||
(merge {:flex-direction :row}))
|
||||
|
@ -114,13 +101,6 @@
|
|||
{:margin-left 0
|
||||
:flex-direction :row})
|
||||
|
||||
(defn message-author-userpic
|
||||
[]
|
||||
(merge
|
||||
{:width (+ 16 photos/default-size)} ;; 16 is for the padding
|
||||
{:padding-left 0
|
||||
:padding-right 8}))
|
||||
|
||||
(def delivery-text
|
||||
{:color colors/gray
|
||||
:margin-top 2
|
||||
|
@ -148,20 +128,6 @@
|
|||
:margin-right 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}})
|
||||
|
||||
(def message-view-wrapper
|
||||
{:align-self :flex-end
|
||||
:flex-direction :row-reverse})
|
||||
|
@ -269,13 +235,6 @@
|
|||
assoc
|
||||
:font-style :italic))
|
||||
|
||||
(defn outgoing-emph-text-style
|
||||
[]
|
||||
(update (emph-text-style)
|
||||
:style
|
||||
assoc
|
||||
:color colors/white-persist))
|
||||
|
||||
(defn emph-style
|
||||
[]
|
||||
(emph-text-style))
|
||||
|
@ -345,13 +304,6 @@
|
|||
: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
|
||||
[]
|
||||
(default-blockquote-style))
|
||||
|
|
|
@ -95,8 +95,7 @@
|
|||
[status-im.ui.screens.wallet.settings.views :as wallet-settings]
|
||||
[status-im.ui.screens.wallet.swap.views :as wallet.swap]
|
||||
[status-im.ui.screens.wallet.transactions.views :as wallet-transactions]
|
||||
[status-im2.contexts.chat.group-details.view :as group-details]
|
||||
[status-im.ui2.screens.chat.components.new-chat.view :as new-chat-aio]))
|
||||
[status-im2.contexts.chat.group-details.view :as group-details]))
|
||||
|
||||
(defn right-button-options
|
||||
[id icon]
|
||||
|
@ -193,9 +192,6 @@
|
|||
:component onboarding.phrase/wizard-recovery-success}
|
||||
|
||||
;;CHAT
|
||||
{:name :start-a-new-chat
|
||||
:options {:sheet? true}
|
||||
:component new-chat-aio/contact-selection-list}
|
||||
|
||||
{:name :group-chat-profile
|
||||
;;TODO animated-header
|
||||
|
@ -581,12 +577,6 @@
|
|||
:top? true}}
|
||||
:component contact/nickname-view}
|
||||
|
||||
{:name :new-chat-aio
|
||||
:on-focus [:contacts/new-chat-focus]
|
||||
;;TODO accessories
|
||||
:options {:insets {:top? true}}
|
||||
:component new-chat-aio/contact-selection-list}
|
||||
|
||||
;[Group chat] Add participants
|
||||
{:name :add-participants-toggle-list
|
||||
:on-focus [:group/add-participants-toggle-list]
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
(ns status-im.ui2.screens.chat.components.new-chat.styles)
|
||||
|
||||
(def contact-selection-heading
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:align-items :flex-end
|
||||
:padding-horizontal 20
|
||||
:margin-bottom 16}})
|
||||
|
||||
(def contact-selection-close
|
||||
{:width 32
|
||||
:height 32
|
||||
:border-radius 10
|
||||
:margin-left 20
|
||||
:margin-bottom 36
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:margin-top 40})
|
||||
|
||||
(def chat-button
|
||||
{:position :absolute
|
||||
:bottom 30
|
||||
:align-self :center})
|
|
@ -1,119 +0,0 @@
|
|||
(ns status-im.ui2.screens.chat.components.new-chat.view
|
||||
(:require [quo2.components.buttons.button :as button]
|
||||
[quo2.core :as quo2]
|
||||
[quo2.foundations.colors :as quo2.colors]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.gesture :as gesture]
|
||||
[status-im2.constants :as constants]
|
||||
[utils.i18n :as i18n]
|
||||
[react-native.core :as rn]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.common.contact-list.view :as contact-list]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[status-im.ui.components.invite.events :as invite.events]
|
||||
[status-im.ui2.screens.chat.components.new-chat.styles :as style]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im2.common.contact-list-item.view :as contact-list-item]))
|
||||
|
||||
(defn- no-contacts-view
|
||||
[]
|
||||
[rn/view
|
||||
{:style {:justify-content :center
|
||||
:align-items :center
|
||||
:margin-top 120}}
|
||||
[rn/image
|
||||
{:source (resources/get-image (if (quo2.colors/dark?) :no-contacts-dark :no-contacts))}]
|
||||
[text/text
|
||||
{:weight :semi-bold
|
||||
:size :paragraph-1
|
||||
:style {:margin-bottom 2
|
||||
:margin-top 20}}
|
||||
(i18n/label :t/you-have-no-contacts)]
|
||||
[text/text
|
||||
{:weight :regular
|
||||
:size :label
|
||||
:style {:margin-bottom 20}}
|
||||
(i18n/label :t/invite-friends-and-family)]
|
||||
[quo2/button
|
||||
{:type :primary
|
||||
:style {:margin-bottom 12}
|
||||
:on-press #(rf/dispatch [::invite.events/share-link nil])}
|
||||
(i18n/label :t/invite-friends)]
|
||||
[quo2/button
|
||||
{:type :grey
|
||||
:on-press #(rf/dispatch [:open-modal :new-contact])}
|
||||
(i18n/label :t/add-a-contact)]])
|
||||
|
||||
(defn contact-item-render
|
||||
[_]
|
||||
(fn [{:keys [public-key] :as item}]
|
||||
(let [user-selected? (rf/sub [:is-contact-selected? public-key])
|
||||
on-toggle #(if user-selected?
|
||||
(re-frame/dispatch [:deselect-contact public-key])
|
||||
(re-frame/dispatch [:select-contact public-key]))]
|
||||
[contact-list-item/contact-list-item
|
||||
{:on-press on-toggle
|
||||
:accessory {:type :checkbox
|
||||
:checked? user-selected?
|
||||
:on-check on-toggle}}
|
||||
item])))
|
||||
|
||||
(defn contact-selection-list
|
||||
[{:keys [scroll-enabled on-scroll]}]
|
||||
(let [contacts (rf/sub [:contacts/sorted-and-grouped-by-first-letter])
|
||||
selected-contacts-count (rf/sub [:selected-contacts-count])
|
||||
selected-contacts (rf/sub [:group/selected-contacts])
|
||||
one-contact-selected? (= selected-contacts-count 1)
|
||||
contacts-selected? (pos? selected-contacts-count)
|
||||
{:keys [primary-name public-key]} (when one-contact-selected?
|
||||
(rf/sub [:contacts/contact-by-identity
|
||||
(first selected-contacts)]))
|
||||
no-contacts? (empty? contacts)]
|
||||
[:<>
|
||||
[quo2/button
|
||||
{:type :grey
|
||||
:icon true
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:style style/contact-selection-close
|
||||
:override-background-color (quo2.colors/theme-colors quo2.colors/neutral-10
|
||||
quo2.colors/neutral-90)}
|
||||
:i/close]
|
||||
[rn/view style/contact-selection-heading
|
||||
[quo2/text
|
||||
{:weight :semi-bold
|
||||
:size :heading-1
|
||||
:style {:color (quo2.colors/theme-colors quo2.colors/neutral-100 quo2.colors/white)}}
|
||||
(i18n/label :t/new-chat)]
|
||||
(when-not no-contacts?
|
||||
[quo2/text
|
||||
{:size :paragraph-2
|
||||
:weight :regular
|
||||
:style {:color (quo2.colors/theme-colors quo2.colors/neutral-40 quo2.colors/neutral-50)}}
|
||||
(i18n/label :t/selected-count-from-max
|
||||
{:selected selected-contacts-count
|
||||
:max constants/max-group-chat-participants})])]
|
||||
[rn/view
|
||||
{:style {:flex 1}}
|
||||
(if no-contacts?
|
||||
[no-contacts-view]
|
||||
[gesture/section-list
|
||||
{:key-fn :title
|
||||
:sticky-section-headers-enabled false
|
||||
:sections (rf/sub [:contacts/filtered-active-sections])
|
||||
:render-section-header-fn contact-list/contacts-section-header
|
||||
:content-container-style {:padding-bottom 70}
|
||||
:render-fn contact-item-render
|
||||
:scroll-enabled @scroll-enabled
|
||||
:on-scroll on-scroll}])]
|
||||
(when contacts-selected?
|
||||
[button/button
|
||||
{:type :primary
|
||||
:style style/chat-button
|
||||
:accessibility-label :next-button
|
||||
:on-press (fn []
|
||||
(if one-contact-selected?
|
||||
(rf/dispatch [:chat.ui/start-chat public-key])
|
||||
(rf/dispatch [:navigate-to :new-group])))}
|
||||
(if one-contact-selected?
|
||||
(i18n/label :t/chat-with {:selected-user primary-name})
|
||||
(i18n/label :t/setup-group-chat))])]))
|
|
@ -2,14 +2,15 @@
|
|||
(:require [clojure.string :as string]
|
||||
[quo2.core :as quo]
|
||||
[react-native.gesture :as gesture]
|
||||
[status-im.ui2.screens.chat.messages.message :as old-message]
|
||||
[status-im2.contexts.chat.messages.content.legacy-view :as old-message]
|
||||
[status-im2.common.not-implemented :as not-implemented]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.activity-center.notification.common.view :as common]
|
||||
[status-im2.contexts.activity-center.notification.reply.style :as style]
|
||||
[utils.datetime :as datetime]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.contexts.chat.messages.content.image.view :as image]))
|
||||
|
||||
;; NOTE: Replies support text, image and stickers only.
|
||||
(defn- get-message-content
|
||||
|
@ -18,7 +19,7 @@
|
|||
constants/content-type-text [quo/text {:style style/tag-text}
|
||||
(get-in message [:content :text])]
|
||||
|
||||
constants/content-type-image [old-message/message-content-image message]
|
||||
constants/content-type-image [image/image-message 0 message nil]
|
||||
|
||||
constants/content-type-sticker [old-message/sticker message]
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
portrait? (and (= images-count rectangular-style-count) (= album-style :portrait))]
|
||||
(if (and albumize? (> images-count 1))
|
||||
[:<>
|
||||
[rn/view {:style {:margin-bottom 10}} [text/text-content first-image context]]
|
||||
[rn/view {:style {:margin-bottom 10}} [text/text-content first-image]]
|
||||
[rn/view
|
||||
{:style (style/album-container portrait?)
|
||||
:accessible true
|
||||
|
@ -75,5 +75,5 @@
|
|||
(map-indexed
|
||||
(fn [index item]
|
||||
[:<> {:key (:message-id item)}
|
||||
[image/image-message index item context #(on-long-press message context)]])
|
||||
[image/image-message index item #(on-long-press message context)]])
|
||||
(:album message))])))
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
{:width (min width max-width) :height (min height max-height)}))
|
||||
|
||||
(defn image-message
|
||||
[index {:keys [content image-width image-height message-id] :as message} context on-long-press]
|
||||
[index {:keys [content image-width image-height message-id] :as message} on-long-press]
|
||||
(let [insets (safe-area/get-insets)
|
||||
dimensions (calculate-dimensions (or image-width 1000) (or image-height 1000))
|
||||
shared-element-id (rf/sub [:shared-element-id])]
|
||||
[:<>
|
||||
(when (= index 0)
|
||||
[rn/view {:style {:margin-bottom 10}} [text/text-content message context]])
|
||||
[rn/view {:style {:margin-bottom 10}} [text/text-content message]])
|
||||
[rn/touchable-opacity
|
||||
{:active-opacity 1
|
||||
:style {:margin-top (when (pos? index) 10)}
|
||||
|
|
|
@ -1,31 +1,22 @@
|
|||
(ns status-im.ui2.screens.chat.messages.message
|
||||
(ns status-im2.contexts.chat.messages.content.legacy-view
|
||||
(:require
|
||||
[quo.design-system.colors :as quo.colors]
|
||||
[quo.react-native :as rn]
|
||||
[quo2.components.icon :as icons]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.foundations.typography :as typography]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.ui.components.fast-image :as fast-image]
|
||||
[status-im.ui.screens.chat.image.preview.views :as preview]
|
||||
[status-im.ui.screens.chat.message.audio :as message.audio]
|
||||
[status-im.ui.screens.chat.message.gap :as message.gap]
|
||||
[status-im.ui.screens.chat.sheets :as sheets]
|
||||
[status-im.ui.screens.chat.styles.message.message :as style]
|
||||
[status-im.ui.screens.chat.utils :as chat.utils]
|
||||
[status-im.ui.screens.communities.icon :as communities.icon]
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.chat.home.chat-list-item.view :as home.chat-list-item]
|
||||
[status-im2.contexts.chat.messages.delete-message-for-me.events]
|
||||
[status-im2.contexts.chat.messages.delete-message.events]
|
||||
[utils.datetime :as datetime]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf])
|
||||
[utils.re-frame :as rf]
|
||||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.foundations.typography :as typography])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
|
||||
(defn system-text?
|
||||
|
@ -142,89 +133,17 @@
|
|||
[:<>]
|
||||
(:parsed-text content))))
|
||||
|
||||
(defn quoted-message
|
||||
[_ pin?]
|
||||
[rn/view {:style (when-not pin? (style/quoted-message-container))}])
|
||||
|
||||
(defn message-not-sent-text
|
||||
[chat-id message-id]
|
||||
[rn/touchable-opacity
|
||||
{:on-press
|
||||
(fn []
|
||||
(re-frame/dispatch
|
||||
[:bottom-sheet/show-sheet-old
|
||||
{:content (sheets/options chat-id message-id)
|
||||
:content-height 200}])
|
||||
(rn/dismiss-keyboard!))}
|
||||
[rn/view style/not-sent-view
|
||||
[rn/text {:style style/not-sent-text}
|
||||
(i18n/label :t/status-not-sent-tap)]
|
||||
[rn/view style/not-sent-icon
|
||||
[icons/icon :i/warning {:color quo.colors/red}]]]])
|
||||
|
||||
;; TODO (Omar): a reminder to clean these defviews
|
||||
(defview message-author-name
|
||||
[from opts max-length]
|
||||
(letsubs [contact-with-names [:contacts/contact-by-identity from]]
|
||||
(chat.utils/format-author contact-with-names opts max-length)))
|
||||
|
||||
(defn display-name-view
|
||||
[display-name contact timestamp show-key?]
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
[text/text
|
||||
{:weight :semi-bold
|
||||
:size :paragraph-2
|
||||
:number-of-lines 1
|
||||
:style {:width "45%"}}
|
||||
display-name]
|
||||
[home.chat-list-item/verified-or-contact-icon contact]
|
||||
(when show-key?
|
||||
(let [props {:size :label
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}}]
|
||||
[rn/view
|
||||
{:style {:margin-left 8
|
||||
:margin-top 2
|
||||
:flex-direction :row}}
|
||||
[text/text
|
||||
(assoc props :accessibility-label :message-chat-key)
|
||||
(utils/get-shortened-address
|
||||
(or (:compressed-key contact)
|
||||
(:public-key contact)))]
|
||||
[text/text props " • "]
|
||||
[text/text
|
||||
(assoc props :accessibility-label :message-timestamp)
|
||||
(datetime/to-short-str timestamp)]]))])
|
||||
|
||||
(def image-max-width 260)
|
||||
(def image-max-height 192)
|
||||
|
||||
(defn image-set-size
|
||||
[dimensions]
|
||||
(fn [^js 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)))))
|
||||
|
||||
(defmulti ->message :content-type)
|
||||
|
||||
(defmethod ->message constants/content-type-gap
|
||||
[message]
|
||||
[message.gap/gap message])
|
||||
|
||||
(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 [:pin-message/show-pin-limit-modal chat-id]))
|
||||
(re-frame/dispatch [:pin-message/send-pin-message (assoc message :pinned (not pinned))]))))
|
||||
|
||||
;; STATUS ? whats that ?
|
||||
(defmethod ->message constants/content-type-status
|
||||
[{:keys [content content-type]}]
|
||||
|
@ -252,47 +171,6 @@
|
|||
{:style {:margin 10 :width 140 :height 140}
|
||||
:source {:uri (str (-> content :sticker :url) "&download=true")}}])
|
||||
|
||||
;;IMAGE
|
||||
(defn message-content-image
|
||||
[{:keys [content]}]
|
||||
(let [dimensions (reagent/atom {:width image-max-width :height image-max-height :loaded false})
|
||||
visible (reagent/atom false)
|
||||
uri (:image content)]
|
||||
(fn [message]
|
||||
(let [style-opts {:outgoing false
|
||||
: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))}]
|
||||
[rn/view
|
||||
{:style (style/image-message style-opts)
|
||||
:accessibility-label :image-message}
|
||||
(when (or (:error @dimensions) (not (:loaded @dimensions)))
|
||||
[rn/view
|
||||
(merge (dissoc style-opts :opacity)
|
||||
{:flex 1 :align-items :center :justify-content :center :position :absolute})
|
||||
(if (:error @dimensions)
|
||||
[icons/icon :i/cancel]
|
||||
[rn/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}}]
|
||||
[rn/view {:style (style/image-message-border style-opts)}]]]))))
|
||||
|
||||
;; AUDIO
|
||||
(defn audio
|
||||
[message]
|
||||
[rn/view {:style (style/message-view message) :accessibility-label :audio-message}
|
||||
[rn/view {:style (style/message-view-content)}
|
||||
[message.audio/message-content message]]])
|
||||
|
||||
(defn contact-request-status-pending
|
||||
[]
|
||||
[rn/view {:style {:flex-direction :row}}
|
|
@ -6,7 +6,7 @@
|
|||
[quo2.foundations.colors :as colors]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.i18n :as i18n]
|
||||
[status-im.ui2.screens.chat.messages.message :as old-message]
|
||||
[status-im2.contexts.chat.messages.content.legacy-view :as old-message]
|
||||
[status-im.ui.screens.chat.styles.message.message :as old-style]))
|
||||
|
||||
(defn pinned-by-view
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
(ns status-im2.contexts.chat.messages.content.system.text.view
|
||||
(:require [react-native.core :as rn]
|
||||
[status-im.ui2.screens.chat.messages.message :as old-message]))
|
||||
[status-im2.contexts.chat.messages.content.legacy-view :as old-message]))
|
||||
|
||||
(defn text-content
|
||||
[message-data]
|
||||
|
|
|
@ -133,7 +133,7 @@
|
|||
add-edited-tag))])
|
||||
|
||||
(defn text-content
|
||||
[message-data _]
|
||||
[message-data]
|
||||
[rn/view
|
||||
[render-parsed-text message-data]
|
||||
[link-preview/view message-data]])
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
[status-im2.contexts.chat.messages.content.audio.view :as audio]
|
||||
[quo2.core :as quo]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im.ui2.screens.chat.messages.message :as old-message]
|
||||
[status-im2.contexts.chat.messages.content.legacy-view :as old-message]
|
||||
[status-im2.contexts.chat.composer.reply.view :as reply]
|
||||
[status-im2.common.not-implemented :as not-implemented]
|
||||
[utils.datetime :as datetime]
|
||||
|
@ -122,7 +122,7 @@
|
|||
[author message-data]
|
||||
(case content-type
|
||||
|
||||
constants/content-type-text [content.text/text-content message-data context]
|
||||
constants/content-type-text [content.text/text-content message-data]
|
||||
|
||||
constants/content-type-emoji
|
||||
[not-implemented/not-implemented [old-message/emoji message-data]]
|
||||
|
@ -134,7 +134,7 @@
|
|||
[audio/audio-message message-data context]
|
||||
|
||||
constants/content-type-image
|
||||
[image/image-message 0 message-data context on-long-press]
|
||||
[image/image-message 0 message-data on-long-press]
|
||||
|
||||
constants/content-type-album
|
||||
[album/album-message message-data context on-long-press]
|
||||
|
|
Loading…
Reference in New Issue