Compare commits
18
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
262faf83fb | ||
|
|
21da153086 | ||
|
|
840471c0c6 | ||
|
|
4c17b7c0bf | ||
|
|
050912d56f | ||
|
|
e201ca9641 | ||
|
|
bea0ae57df | ||
|
|
868c6d0814 | ||
|
|
a9cfbc7dbf | ||
|
|
ba8a471931 | ||
|
|
a6dbc14298 | ||
|
|
e782e4ff15 | ||
|
|
08b17a1dfd | ||
|
|
80913c40a7 | ||
|
|
2378f08ad5 | ||
|
|
92947d7acf | ||
|
|
89f040ea34 | ||
|
|
f9b13158eb |
@@ -0,0 +1,52 @@
|
||||
(ns status-im.ui.components.image-with-loader
|
||||
(:require [reagent.core :as reagent]
|
||||
[quo.design-system.colors :as colors]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.utils.contenthash :as contenthash]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn- placeholder [props child]
|
||||
(let [{:keys [accessibility-label style]} props]
|
||||
[react/view {:accessibility-label accessibility-label
|
||||
:style (merge style
|
||||
{:align-items :center
|
||||
:justify-content :center
|
||||
:background-color colors/gray-lighter})}
|
||||
child]))
|
||||
|
||||
(defn source [props]
|
||||
(let [{:keys [source style accessibility-labels]} props
|
||||
loaded? (reagent/atom false)
|
||||
error? (reagent/atom false)
|
||||
current-source (reagent/atom (if (seq? source)
|
||||
source
|
||||
[source]))]
|
||||
(fn []
|
||||
[react/view
|
||||
(when @error?
|
||||
[placeholder {:accessibility-label (:error accessibility-labels)
|
||||
:style style}
|
||||
[icons/icon :main-icons/cancel]])
|
||||
(when-not (or @loaded? @error?)
|
||||
[placeholder {:accessibility-label (:loading accessibility-labels)
|
||||
:style style}
|
||||
[react/activity-indicator {:animating true}]])
|
||||
(when (not @error?)
|
||||
(log/info "loaded" @loaded?)
|
||||
(log/info "style" style)
|
||||
[react/fast-image {:accessibility-label (:success accessibility-labels)
|
||||
:onError #(if (empty? (rest @current-source))
|
||||
(reset! error? true)
|
||||
(reset! current-source
|
||||
(rest @current-source)))
|
||||
:onLoad #(reset! loaded? true)
|
||||
:style (if @loaded? style {})
|
||||
:source (first @current-source)
|
||||
:resize-mode :contain}])])))
|
||||
|
||||
(defn ipfs [props]
|
||||
(let [{:keys [hash]} props]
|
||||
[source (merge (dissoc props :hash)
|
||||
{:source (map (fn [u] {:uri u})
|
||||
(contenthash/alternatives hash))})]))
|
||||
@@ -14,7 +14,6 @@
|
||||
[status-im.ui.screens.chat.message.gap :as message.gap]
|
||||
[status-im.ui.screens.chat.styles.message.message :as style]
|
||||
[status-im.ui.screens.chat.utils :as chat.utils]
|
||||
[status-im.utils.contenthash :as contenthash]
|
||||
[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]
|
||||
@@ -25,7 +24,8 @@
|
||||
[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.pin-message :as models.pin-message])
|
||||
[status-im.chat.models.pin-message :as models.pin-message]
|
||||
[status-im.ui.components.image-with-loader :as image-with-loader])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
|
||||
(defn message-timestamp-anim
|
||||
@@ -567,9 +567,9 @@
|
||||
[{:on-press #(when pack
|
||||
(re-frame/dispatch [:chat.ui/show-profile from]))
|
||||
:label (i18n/label :t/view-details)}])))})
|
||||
[react/fast-image {:style {:margin 10 :width 140 :height 140}
|
||||
;;TODO (perf) move to event
|
||||
:source {:uri (contenthash/url (-> content :sticker :hash))}}]]
|
||||
[image-with-loader/ipfs {:style {:margin 10 :width 140 :height 140 :border-radius 16}
|
||||
;;TODO (perf) move to event
|
||||
:hash (-> content :sticker :hash)}]]
|
||||
reaction-picker]))
|
||||
|
||||
(defmethod ->message constants/content-type-image [{:keys [content in-popover?] :as message} {:keys [on-long-press modal]
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.screens.chat.stickers.styles :as styles]
|
||||
[status-im.utils.contenthash :as contenthash]
|
||||
[status-im.utils.debounce :as debounce]))
|
||||
[status-im.utils.debounce :as debounce]
|
||||
[status-im.ui.components.image-with-loader :as image-with-loader]))
|
||||
|
||||
(def icon-size 28)
|
||||
(def icon-horizontal-margin 8)
|
||||
@@ -39,9 +39,11 @@
|
||||
^{:key (str hash)}
|
||||
[react/touchable-highlight {:style {:height 75 :width 75 :margin 5}
|
||||
:on-press #(debounce/dispatch-and-chill [:chat/send-sticker sticker] 1000)}
|
||||
[react/fast-image {:style {:width "100%" :height "100%"}
|
||||
:accessibility-label :sticker-icon
|
||||
:source {:uri (contenthash/url (str "0x" hash))}}]])]]])
|
||||
[image-with-loader/ipfs {:style {:width "100%" :height "100%" :border-radius 8}
|
||||
:accessibility-labels {:success :sticker-icon
|
||||
:loading :sticker-icon-loading
|
||||
:error :sticker-icon-error}
|
||||
:hash (str "0x" hash)}]])]]])
|
||||
|
||||
(defview recent-stickers-panel [window-width]
|
||||
(letsubs [stickers [:stickers/recent]]
|
||||
@@ -143,6 +145,6 @@
|
||||
^{:key id}
|
||||
[pack-icon {:id id
|
||||
:background-color colors/white}
|
||||
[react/fast-image {:style {:width icon-size :height icon-size :border-radius (/ icon-size 2)}
|
||||
:source {:uri (contenthash/url thumbnail)}}]])]
|
||||
[image-with-loader/ipfs {:style {:width icon-size :height icon-size :border-radius (/ icon-size 2)}
|
||||
:hash thumbnail}]])]
|
||||
[scroll-indicator]]]]]))
|
||||
|
||||
@@ -24,4 +24,4 @@
|
||||
:border-radius 14
|
||||
:background-color colors/green
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
:justify-content :center})
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
[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.image-with-loader :as image-with-loader]
|
||||
[status-im.ui.screens.stickers.styles :as styles]
|
||||
[status-im.utils.contenthash :as contenthash]
|
||||
[status-im.utils.money :as money])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
|
||||
(defn- thumbnail-icon [uri size]
|
||||
[react/fast-image {:style {:width size :height size :border-radius (/ size 2)}
|
||||
:source {:uri uri}}])
|
||||
(defn- thumbnail-icon [hash size]
|
||||
[image-with-loader/ipfs {:style {:width size :height size :border-radius (/ size 2)}
|
||||
:hash hash}])
|
||||
|
||||
(defn- installed-icon []
|
||||
[react/view styles/installed-icon
|
||||
@@ -43,9 +43,9 @@
|
||||
(defn pack-badge [{:keys [name author price thumbnail preview id installed owned pending]}]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :stickers-pack {:id id}])}
|
||||
[react/view {:margin-bottom 27}
|
||||
[react/fast-image {:style {:height 200 :border-radius 20} :source {:uri (contenthash/url preview)}}]
|
||||
[image-with-loader/ipfs {:style {:height 200 :border-radius 20} :hash preview}]
|
||||
[react/view {:height 64 :align-items :center :flex-direction :row}
|
||||
[thumbnail-icon (contenthash/url thumbnail) 40]
|
||||
[thumbnail-icon thumbnail 40]
|
||||
[react/view {:padding-horizontal 16 :flex 1}
|
||||
[react/text {:accessibility-label :sticker-pack-name} name]
|
||||
[react/text {:style {:color colors/gray :margin-top 6}
|
||||
@@ -74,11 +74,11 @@
|
||||
stickers installed owned pending]
|
||||
:as pack}
|
||||
[:stickers/get-current-pack]]
|
||||
[react/keyboard-avoiding-view {:flex 1}
|
||||
[react/keyboard-avoiding-view {:flex 1 :margin-top 18}
|
||||
(if pack
|
||||
[react/view {:flex 1}
|
||||
[react/view {:height 74 :align-items :center :flex-direction :row :padding-horizontal 16}
|
||||
[thumbnail-icon (contenthash/url thumbnail) 64]
|
||||
[thumbnail-icon thumbnail 64]
|
||||
[react/view {:padding-horizontal 16 :flex 1}
|
||||
[react/text {:style {:typography :header}} name]
|
||||
[react/text {:style {:color colors/gray :margin-top 6}} author]]
|
||||
@@ -90,8 +90,8 @@
|
||||
[react/view {:flex-direction :row :flex-wrap :wrap}
|
||||
(for [{:keys [hash]} stickers]
|
||||
^{:key hash}
|
||||
[react/fast-image {:style (styles/sticker-image sticker-icon-size)
|
||||
:source {:uri (contenthash/url hash)}}])]]]]
|
||||
[image-with-loader/ipfs {:style (styles/sticker-image sticker-icon-size)
|
||||
:hash hash}])]]]]
|
||||
[react/view {:flex 1 :align-items :center :justify-content :center}
|
||||
[react/activity-indicator {:animating true}]])]))
|
||||
|
||||
|
||||
@@ -46,3 +46,16 @@
|
||||
"")))
|
||||
|
||||
(def url (memoize url-fn))
|
||||
|
||||
(defn ipfs-alternatives [hash]
|
||||
[(str "https://" hash ".ipfs.cf-ipfs.com")
|
||||
(str "https://" hash ".ipfs.dweb.link")
|
||||
(str "https://ipfs.io/ipfs/" hash)])
|
||||
|
||||
(defn alternatives-fn [hex]
|
||||
(let [{:keys [namespace hash]} (decode (ethereum/normalized-hex hex))]
|
||||
(case namespace
|
||||
:ipfs (ipfs-alternatives hash)
|
||||
"")))
|
||||
|
||||
(def alternatives (memoize alternatives-fn))
|
||||
|
||||
Reference in New Issue
Block a user