feat: Add internal link preview for communities (#18484)
This commit is contained in:
parent
103c4b4653
commit
2009199c25
|
@ -33,6 +33,7 @@
|
|||
:outgoing-status nil
|
||||
:command-parameters nil
|
||||
:link-previews []
|
||||
:status-link-previews []
|
||||
:content {:sticker nil
|
||||
:rtl? nil
|
||||
:ens-name nil
|
||||
|
@ -49,6 +50,7 @@
|
|||
:outgoing-status nil
|
||||
:command-parameters nil
|
||||
:link-previews []
|
||||
:status-link-previews []
|
||||
:content {:sticker nil
|
||||
:rtl? nil
|
||||
:ens-name nil
|
||||
|
|
|
@ -16,13 +16,41 @@
|
|||
:community-id :communityId
|
||||
:clock-value :clock})))
|
||||
|
||||
(defn- <-status-link-previews-rpc
|
||||
[preview]
|
||||
(-> preview
|
||||
(update :community
|
||||
set/rename-keys
|
||||
{:communityId :community-id
|
||||
:displayName :display-name
|
||||
:membersCount :members-count
|
||||
:activeMembersCount :active-members-count})
|
||||
(update-in [:community :banner] set/rename-keys {:dataUri :data-uri})
|
||||
(update-in [:community :icon] set/rename-keys {:dataUri :data-uri})))
|
||||
|
||||
(defn ->status-link-previews-rpc
|
||||
[preview]
|
||||
(-> preview
|
||||
(update :community
|
||||
set/rename-keys
|
||||
{:community-id :communityId
|
||||
:display-name :displayName
|
||||
:members-count :membersCount
|
||||
:active-members-count :activeMembersCount})
|
||||
(update-in [:community :banner] set/rename-keys {:data-uri :dataUri})
|
||||
(update-in [:community :icon] set/rename-keys {:data-uri :dataUri})))
|
||||
|
||||
(defn- <-link-preview-rpc
|
||||
[preview]
|
||||
(update preview :thumbnail set/rename-keys {:dataUri :data-uri}))
|
||||
(-> preview
|
||||
(update :thumbnail set/rename-keys {:dataUri :data-uri})
|
||||
(update :favicon set/rename-keys {:dataUri :data-uri})))
|
||||
|
||||
(defn ->link-preview-rpc
|
||||
[preview]
|
||||
(update preview :thumbnail set/rename-keys {:data-uri :dataUri}))
|
||||
(-> preview
|
||||
(update :thumbnail set/rename-keys {:data-uri :dataUri})
|
||||
(update :favicon set/rename-keys {:data-uri :dataUri})))
|
||||
|
||||
(defn <-rpc
|
||||
[message]
|
||||
|
@ -53,8 +81,10 @@
|
|||
:new :new?
|
||||
:albumImagesCount :album-images-count
|
||||
:displayName :display-name
|
||||
:linkPreviews :link-previews})
|
||||
:linkPreviews :link-previews
|
||||
:statusLinkPreviews :status-link-previews})
|
||||
(update :link-previews #(map <-link-preview-rpc %))
|
||||
(update :status-link-previews #(map <-status-link-previews-rpc %))
|
||||
(update :quoted-message
|
||||
set/rename-keys
|
||||
{:parsedText :parsed-text
|
||||
|
|
|
@ -37,7 +37,19 @@
|
|||
:compressed-key "c"
|
||||
:timestamp 3
|
||||
:link-previews [{:thumbnail {:url "http://localhost"
|
||||
:data-uri "data:image/png"}}]}
|
||||
:data-uri "data:image/png"}
|
||||
:favicon nil}]
|
||||
:status-link-previews [{:url "http://localhost"
|
||||
:community {:community-id "0x01"
|
||||
:display-name "Test Comm"
|
||||
:members-count 12
|
||||
:active-members-count 12
|
||||
:banner
|
||||
{:data-uri
|
||||
"data:image/png"}
|
||||
:icon
|
||||
{:data-uri
|
||||
"data:image/png"}}}]}
|
||||
message {:id message-id
|
||||
:whisperTimestamp 1
|
||||
:parsedText "parsed-text"
|
||||
|
@ -61,5 +73,17 @@
|
|||
:timestamp 3
|
||||
:outgoingStatus "sending"
|
||||
:linkPreviews [{:thumbnail {:url "http://localhost"
|
||||
:dataUri "data:image/png"}}]}]
|
||||
:dataUri "data:image/png"}
|
||||
:favicon nil}]
|
||||
:statusLinkPreviews [{:url "http://localhost"
|
||||
:community {:communityId "0x01"
|
||||
:displayName "Test Comm"
|
||||
:membersCount 12
|
||||
:activeMembersCount 12
|
||||
:banner
|
||||
{:dataUri
|
||||
"data:image/png"}
|
||||
:icon
|
||||
{:dataUri
|
||||
"data:image/png"}}}]}]
|
||||
(is (= expected (m/<-rpc message))))))
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
;;; Link previews
|
||||
(reg-root-key-sub :link-previews-whitelist :link-previews-whitelist)
|
||||
(reg-root-key-sub :chat/link-previews :chat/link-previews)
|
||||
(reg-root-key-sub :chat/status-link-previews :chat/status-link-previews)
|
||||
|
||||
;;commands
|
||||
(reg-root-key-sub :commands/select-account :commands/select-account)
|
||||
|
|
|
@ -85,9 +85,7 @@
|
|||
:accessibility-label :share-community-link
|
||||
:type :secondary
|
||||
:on-press #(debounce/throttle-and-dispatch
|
||||
[(if can-invite?
|
||||
::communities/invite-people-confirmation-pressed
|
||||
::communities/share-community-confirmation-pressed) @user-pk
|
||||
[::communities/share-community-confirmation-pressed @user-pk
|
||||
selected]
|
||||
3000)}
|
||||
(i18n/label (if can-invite? :t/invite :t/share))]}]]))))
|
||||
|
|
|
@ -60,8 +60,8 @@
|
|||
:padding-horizontal 12
|
||||
:padding-top 10
|
||||
:padding-bottom 12
|
||||
:height (if (= :message size) 245 266)
|
||||
:width (if (= :message size) 295 335)})
|
||||
:width (if (= :message size) 295 335)
|
||||
:flex 1})
|
||||
|
||||
(def header-container
|
||||
{:flex-direction :row
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
{:title "Some title"
|
||||
:description "Some description"
|
||||
:link "status.im"
|
||||
:logo "data:image/png,logo-x"
|
||||
:thumbnail "data:image/png,whatever"})
|
||||
|
||||
(h/describe "Links - Link Preview"
|
||||
|
@ -21,17 +20,12 @@
|
|||
(h/is-truthy (h/query-by-text (:title props)))
|
||||
(h/is-truthy (h/query-by-text (:description props)))
|
||||
(h/is-truthy (h/query-by-text (:link props)))
|
||||
(h/is-truthy (h/query-by-label-text :logo))
|
||||
(h/is-truthy (h/query-by-label-text :thumbnail)))
|
||||
|
||||
(h/test "does not render thumbnail if prop is not present"
|
||||
(h/render [view/view (dissoc props :thumbnail)])
|
||||
(h/is-null (h/query-by-label-text :thumbnail)))
|
||||
|
||||
(h/test "does not render logo if prop is not present"
|
||||
(h/render [view/view (dissoc props :logo)])
|
||||
(h/is-null (h/query-by-label-text :logo)))
|
||||
|
||||
(h/test "shows button to enable preview when preview is disabled"
|
||||
(h/render [view/view
|
||||
(assoc props
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
(ns quo.components.links.link-preview.view
|
||||
(:require
|
||||
["react-native-blob-util" :default ReactNativeBlobUtil]
|
||||
[oops.core :as oops]
|
||||
[quo.components.buttons.button.view :as button]
|
||||
[quo.components.links.link-preview.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.svg :as svg]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn- button-disabled
|
||||
[disabled-text on-enable]
|
||||
|
@ -51,14 +56,30 @@
|
|||
thumbnail)
|
||||
:accessibility-label :thumbnail}])
|
||||
|
||||
(defn- get-image-data
|
||||
[logo set-is-svg on-success]
|
||||
(-> (.config ReactNativeBlobUtil (clj->js {:trusty platform/ios?}))
|
||||
(.fetch "GET" logo)
|
||||
(.then (fn [imgObj]
|
||||
(set-is-svg (= "image/svg"
|
||||
(oops/oget imgObj
|
||||
["respInfo" "headers" "Content-Type"])))
|
||||
(on-success (oops/oget imgObj "data"))))
|
||||
(.catch #(log/error "could not fetch favicon " logo))))
|
||||
|
||||
(defn- logo-comp
|
||||
[logo]
|
||||
(let [[image-data set-image-data] (rn/use-state nil)
|
||||
[is-svg? set-is-svg] (rn/use-state nil)
|
||||
on-success (fn [data-uri]
|
||||
(set-image-data data-uri))
|
||||
_get-image-data (get-image-data logo set-is-svg on-success)]
|
||||
(if is-svg?
|
||||
[svg/svg-xml (merge style/logo {:xml image-data})]
|
||||
[rn/image
|
||||
{:accessibility-label :logo
|
||||
:source (if (string? logo)
|
||||
{:uri logo}
|
||||
logo)
|
||||
:style style/logo}])
|
||||
:source {:uri (str "data:image/png;base64," image-data)}
|
||||
:style style/logo}])))
|
||||
|
||||
(defn view
|
||||
[{:keys [title logo description link thumbnail
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
:border-radius 12
|
||||
:border-style :dashed
|
||||
:align-items :center
|
||||
:flex-direction :row
|
||||
:justify-content :center
|
||||
:align-self :stretch
|
||||
:padding horizontal-padding
|
||||
|
|
|
@ -1,19 +1,31 @@
|
|||
(ns quo.components.links.url-preview.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.components.icon :as icon]
|
||||
[quo.components.links.url-preview.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[react-native.svg :as svg]))
|
||||
|
||||
(def base64-svg-prefix "data:image/svg;base64,")
|
||||
|
||||
(defn- logo-comp
|
||||
[{:keys [logo]}]
|
||||
(if (and (string? logo)
|
||||
(string/starts-with? logo base64-svg-prefix))
|
||||
[svg/svg-xml
|
||||
(merge style/logo
|
||||
{:xml (-> logo
|
||||
(string/replace base64-svg-prefix "")
|
||||
js/atob)})]
|
||||
[rn/image
|
||||
{:accessibility-label :logo
|
||||
:source (if (string? logo)
|
||||
{:uri logo}
|
||||
logo)
|
||||
:style style/logo}])
|
||||
:style style/logo
|
||||
:resize-mode :cover}]))
|
||||
|
||||
(defn- content
|
||||
[{:keys [title body]}]
|
||||
|
@ -50,6 +62,10 @@
|
|||
[rn/view
|
||||
{:accessibility-label :url-preview-loading
|
||||
:style (merge (style/loading-container) container-style)}
|
||||
[icon/icon :i/loading
|
||||
{:size 12
|
||||
:color (colors/theme-colors colors/neutral-50 colors/neutral-40)
|
||||
:container-style {:margin-right 8}}]
|
||||
[rn/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
|
@ -60,6 +76,9 @@
|
|||
{:accessibility-label :url-preview
|
||||
:style (merge (style/container) container-style)}
|
||||
(when logo
|
||||
[logo-comp {:logo logo}])
|
||||
[logo-comp
|
||||
{:logo (if (map? logo)
|
||||
(:data-uri logo)
|
||||
logo)}])
|
||||
[content {:title title :body body}]
|
||||
[clear-button {:on-press on-clear}]]))
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
[rn/view {:style style/url-preview-separator}])
|
||||
|
||||
(defn- item-component
|
||||
[{:keys [title body loading? logo]} _ _
|
||||
[{:keys [title body loading? logo url]} _ _
|
||||
{:keys [width on-clear loading-message container-style]}]
|
||||
[url-preview/view
|
||||
{:logo logo
|
||||
|
@ -41,7 +41,8 @@
|
|||
:loading? loading?
|
||||
:loading-message loading-message
|
||||
:on-clear on-clear
|
||||
:container-style (merge container-style {:width width})}])
|
||||
:container-style (merge container-style {:width width})
|
||||
:url url}])
|
||||
|
||||
(defn- f-view
|
||||
[]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
(ns status-im.common.biometric.events-test
|
||||
(:require [cljs.test :refer [deftest testing is]]
|
||||
(:require [cljs.test :refer [deftest is testing]]
|
||||
matcher-combinators.test
|
||||
[status-im.common.biometric.events :as sut]
|
||||
[status-im.constants :as constants]
|
||||
|
|
|
@ -467,3 +467,5 @@
|
|||
(def ^:const bridge-name-erc-721-transfer "ERC721Transfer")
|
||||
|
||||
(def ^:const alert-banner-height 40)
|
||||
|
||||
(def ^:const status-hostname "status.app")
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
(ns status-im.contexts.chat.messenger.composer.events
|
||||
(:require [clojure.string :as string]
|
||||
[legacy.status-im.chat.models.mentions :as mentions]
|
||||
[legacy.status-im.data-store.messages :as data-store-messages]
|
||||
[legacy.status-im.data-store.messages :as data-store.messages]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.chat.messenger.composer.link-preview.events :as link-preview]
|
||||
[status-im.contexts.chat.messenger.messages.transport.events :as messages.transport]
|
||||
|
@ -132,6 +132,37 @@
|
|||
:response-to message-id})
|
||||
images)))
|
||||
|
||||
(defn- build-status-link-previews
|
||||
[status-link-previews]
|
||||
(map (fn [{{:keys [community-id color description display-name
|
||||
members-count active-members-count icon banner]}
|
||||
:community
|
||||
url :url}]
|
||||
{:url url
|
||||
:community
|
||||
{:community-id community-id
|
||||
:color color
|
||||
:description description
|
||||
:display-name display-name
|
||||
:members-count members-count
|
||||
:active-members-count active-members-count
|
||||
:icon {:data-uri (:data-uri icon)
|
||||
:width (:width icon)
|
||||
:height (:height icon)}
|
||||
:banner {:data-uri (:data-uri banner)
|
||||
:width (:width banner)
|
||||
:height (:height banner)}}})
|
||||
status-link-previews))
|
||||
|
||||
(defn- build-link-previews
|
||||
[link-previews]
|
||||
(->> link-previews
|
||||
(map #(select-keys %
|
||||
[:url :title :description :thumbnail
|
||||
:status-link-preview? :favicon]))
|
||||
(filter (fn [{:keys [status-link-preview?]}]
|
||||
(not status-link-preview?)))))
|
||||
|
||||
(defn build-text-message
|
||||
[{:keys [db]} input-text current-chat-id]
|
||||
(when-not (string/blank? input-text)
|
||||
|
@ -147,8 +178,9 @@
|
|||
:text input-text
|
||||
:response-to message-id
|
||||
:ens-name preferred-name
|
||||
:link-previews (map #(select-keys % [:url :title :description :thumbnail])
|
||||
(get-in db [:chat/link-previews :unfurled]))})))
|
||||
:link-previews (build-link-previews (get-in db [:chat/link-previews :unfurled]))
|
||||
:status-link-previews (build-status-link-previews
|
||||
(get-in db [:chat/status-link-previews :unfurled]))})))
|
||||
|
||||
(rf/defn send-messages
|
||||
[{:keys [db] :as cofx} input-text current-chat-id]
|
||||
|
@ -181,12 +213,23 @@
|
|||
(when message-id
|
||||
{:response-to message-id}))])))))
|
||||
|
||||
(defn- process-link-previews
|
||||
[link-previews]
|
||||
(->> link-previews
|
||||
(map #(select-keys %
|
||||
[:url :title :description :thumbnail
|
||||
:status-link-preview? :favicon]))
|
||||
(map data-store.messages/->link-preview-rpc)
|
||||
(filter (fn [{:keys [status-link-preview?]}]
|
||||
(not status-link-preview?)))))
|
||||
|
||||
(rf/defn send-edited-message
|
||||
[{:keys [db]
|
||||
:as cofx} text {:keys [message-id quoted-message chat-id]}]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:json-rpc/call [{:method "wakuext_editMessage"
|
||||
{:json-rpc/call
|
||||
[{:method "wakuext_editMessage"
|
||||
:params [{:id message-id
|
||||
:text text
|
||||
:content-type (if (emoji-only-content?
|
||||
|
@ -194,11 +237,12 @@
|
|||
:response-to quoted-message})
|
||||
constants/content-type-emoji
|
||||
constants/content-type-text)
|
||||
:linkPreviews (map #(-> %
|
||||
(select-keys [:url :title :description
|
||||
:thumbnail])
|
||||
data-store-messages/->link-preview-rpc)
|
||||
(get-in db [:chat/link-previews :unfurled]))}]
|
||||
:linkPreviews (process-link-previews (get-in db
|
||||
[:chat/link-previews :unfurled]))
|
||||
:statusLinkPreviews (map data-store.messages/->status-link-previews-rpc
|
||||
(get-in db
|
||||
[:chat/status-link-previews
|
||||
:unfurled]))}]
|
||||
:js-response true
|
||||
:on-error #(log/error "failed to edit message " %)
|
||||
:on-success (fn [result]
|
||||
|
|
|
@ -80,24 +80,51 @@
|
|||
[]
|
||||
curr-previews))
|
||||
|
||||
(defn- merge-preview-types
|
||||
[new-previews new-status-link-previews]
|
||||
(-> (map
|
||||
(fn [{{:keys [display-name members-count banner icon
|
||||
description]} :community
|
||||
url :url}]
|
||||
;; Other types of previews need to be done here too
|
||||
;; Like User link preview and Channel link preview
|
||||
{:url url
|
||||
:display-name display-name
|
||||
:members-count members-count
|
||||
:banner banner
|
||||
:icon icon
|
||||
:description description
|
||||
;; Need to set status-link-preview?
|
||||
;; to true to not send status-link-previews
|
||||
;; with normal link-previews
|
||||
:status-link-preview? true})
|
||||
new-status-link-previews)
|
||||
(concat new-previews)))
|
||||
|
||||
(rf/defn unfurl-parsed-urls-success
|
||||
{:events [:link-preview/unfurl-parsed-urls-success]}
|
||||
[{:keys [db]} request-id {new-previews :linkPreviews}]
|
||||
[{:keys [db]} request-id {new-previews :linkPreviews status-link-previews :statusLinkPreviews}]
|
||||
(when (= request-id (get-in db [:chat/link-previews :request-id]))
|
||||
(let [new-previews (map data-store.messages/<-link-preview-rpc new-previews)
|
||||
new-status-link-previews (map data-store.messages/<-status-link-previews-rpc
|
||||
status-link-previews)
|
||||
merged-preview-types (merge-preview-types new-previews new-status-link-previews)
|
||||
curr-previews (get-in db [:chat/link-previews :unfurled])
|
||||
indexed-new-previews (utils.collection/index-by :url new-previews)]
|
||||
indexed-new-previews (utils.collection/index-by :url merged-preview-types)]
|
||||
(log/debug "URLs unfurled"
|
||||
:chat/link-previews
|
||||
{:event :link-preview/unfurl-parsed-urls-success
|
||||
:previews (map #(update % :thumbnail dissoc :data-uri) new-previews)
|
||||
:previews (map #(update % :thumbnail dissoc :data-uri) merged-preview-types)
|
||||
:request-id request-id})
|
||||
{:db (-> db
|
||||
(assoc-in [:chat/status-link-previews :unfurled] new-status-link-previews)
|
||||
(update-in [:chat/link-previews :unfurled] reconcile-unfurled indexed-new-previews)
|
||||
(update-in [:chat/link-previews :cache]
|
||||
merge
|
||||
indexed-new-previews
|
||||
(utils.collection/index-by :url
|
||||
(failed-previews curr-previews new-previews))))})))
|
||||
(failed-previews curr-previews
|
||||
merged-preview-types))))})))
|
||||
|
||||
(rf/defn unfurl-parsed-urls-error
|
||||
{:events [:link-preview/unfurl-parsed-urls-error]}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
(def url-github "https://github.com")
|
||||
(def url-gitlab "https://gitlab.com")
|
||||
(def url-community
|
||||
"https://status.app/c/iyKACkQKB0Rvb2RsZXMSJ0NvbG9yaW5nIHRoZSB3b3JsZCB3aXRoIGpveSDigKIg4bSXIOKAohiYohsiByMxMzFEMkYqAwEhMwM=#zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11")
|
||||
(def preview-github {:url url-github :thumbnail nil})
|
||||
(def preview-gitlab {:url url-gitlab :thumbnail nil})
|
||||
(def request-id "abc123")
|
||||
|
@ -31,7 +33,15 @@
|
|||
(is (match? {:json-rpc/call [{:method "wakuext_getTextURLs"
|
||||
:params [url-github]}]}
|
||||
(remove-rpc-callbacks
|
||||
(events/unfurl-urls cofx url-github)))))))
|
||||
(events/unfurl-urls cofx url-github))))))
|
||||
(testing "fetches status community URLs"
|
||||
(let [cofx {:db {:chat/link-previews {:unfurled {}
|
||||
:cache {}
|
||||
:request-id "123"}}}]
|
||||
(is (match? {:json-rpc/call [{:method "wakuext_getTextURLs"
|
||||
:params [url-community]}]}
|
||||
(remove-rpc-callbacks
|
||||
(events/unfurl-urls cofx url-community)))))))
|
||||
|
||||
(deftest unfurl-parsed-urls-test
|
||||
(with-redefs [events/new-request-id (constantly request-id)]
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
(ns status-im.contexts.chat.messenger.composer.link-preview.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.constants]
|
||||
[status-im.contexts.chat.messenger.composer.constants :as constants]
|
||||
[status-im.contexts.chat.messenger.composer.link-preview.events]
|
||||
[status-im.contexts.chat.messenger.composer.link-preview.style :as style]
|
||||
|
@ -33,9 +36,14 @@
|
|||
:horizontal-spacing style/padding-horizontal
|
||||
:loading-message (i18n/label :t/link-preview-loading-message)
|
||||
:on-clear #(rf/dispatch [:link-preview/clear])
|
||||
:data (map (fn [{:keys [title thumbnail hostname loading? url]}]
|
||||
{:title title
|
||||
:body hostname
|
||||
:data (map
|
||||
(fn [{:keys [title display-name thumbnail hostname loading? url favicon]}]
|
||||
{:title (or display-name title)
|
||||
:body (or (when-not display-name hostname)
|
||||
status-im.constants/status-hostname)
|
||||
:logo (if (string/starts-with? url "https://status.app")
|
||||
(resources/get-mock-image :status-logo)
|
||||
favicon)
|
||||
:loading? loading?
|
||||
:thumbnail (:data-uri thumbnail)
|
||||
:url url})
|
||||
|
|
|
@ -16,12 +16,13 @@
|
|||
(let [previews (rf/sub [:chats/message-link-previews chat-id message-id])]
|
||||
(when (seq previews)
|
||||
[:<>
|
||||
(for [{:keys [url title description thumbnail hostname]} previews]
|
||||
(for [{:keys [url title description thumbnail hostname favicon]} previews]
|
||||
^{:key url}
|
||||
[quo/link-preview
|
||||
{:title title
|
||||
:description description
|
||||
:link hostname
|
||||
:logo (:url favicon)
|
||||
:thumbnail (:url thumbnail)
|
||||
:thumbnail-size (when (nearly-square? thumbnail) :large)
|
||||
:container-style {:margin-top 8}}])])))
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
(ns status-im.contexts.chat.messenger.messages.content.status-link-preview.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[{:keys [chat-id message-id]}]
|
||||
(let [status-link-previews (rf/sub [:chats/message-status-link-previews chat-id message-id])
|
||||
link-previews? (rf/sub [:chats/message-link-previews? chat-id message-id])]
|
||||
(when (seq status-link-previews)
|
||||
[rn/view {:style {:margin-top (when link-previews? 8)}}
|
||||
(for [{:keys [url community]} status-link-previews]
|
||||
(when community
|
||||
(let [{community-description :description
|
||||
community-icon :icon
|
||||
community-banner :banner
|
||||
community-name :display-name
|
||||
members-count :members-count} community]
|
||||
^{:key url}
|
||||
[quo/internal-link-card
|
||||
{:type :community
|
||||
:size :message
|
||||
:description community-description
|
||||
:members-count members-count
|
||||
:title community-name
|
||||
:banner (:url community-banner)
|
||||
:icon (:url community-icon)
|
||||
:on-press #(rf/dispatch [:universal-links/handle-url url])}])))])))
|
|
@ -5,6 +5,7 @@
|
|||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.contexts.chat.messenger.messages.content.link-preview.view :as link-preview]
|
||||
[status-im.contexts.chat.messenger.messages.content.status-link-preview.view :as status-link-preview]
|
||||
[status-im.contexts.chat.messenger.messages.content.text.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
@ -165,4 +166,5 @@
|
|||
[message-data]
|
||||
[:<>
|
||||
[render-parsed-text message-data]
|
||||
[link-preview/view message-data]])
|
||||
[link-preview/view message-data]
|
||||
[status-link-preview/view message-data]])
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
[legacy.status-im.data-store.chats :as data-store.chats]
|
||||
[legacy.status-im.data-store.communities :as data-store.communities]
|
||||
[legacy.status-im.data-store.invitations :as data-store.invitations]
|
||||
[legacy.status-im.data-store.messages :as data-store.messages]
|
||||
[legacy.status-im.group-chats.core :as models.group]
|
||||
[legacy.status-im.multiaccounts.update.core :as update.core]
|
||||
[legacy.status-im.pairing.core :as models.pairing]
|
||||
|
@ -356,17 +357,19 @@
|
|||
(conj set-hash-fxs
|
||||
#(sanitize-messages-and-process-response % response-js false)))))
|
||||
|
||||
(defn- image->rpc [image] (set/rename-keys image {:data-uri :dataUri}))
|
||||
|
||||
(defn- link-preview->rpc
|
||||
[preview]
|
||||
(update preview
|
||||
:thumbnail
|
||||
(fn [thumbnail]
|
||||
(set/rename-keys thumbnail {:data-uri :dataUri}))))
|
||||
(-> preview
|
||||
(update :thumbnail image->rpc)
|
||||
(update :favicon image->rpc)))
|
||||
|
||||
(defn build-message
|
||||
[msg]
|
||||
(-> msg
|
||||
(update :link-previews #(map link-preview->rpc %))
|
||||
(update :status-link-previews #(set (map data-store.messages/->status-link-previews-rpc %)))
|
||||
(set/rename-keys
|
||||
{:album-id :albumId
|
||||
:audio-duration-ms :audioDurationMs
|
||||
|
@ -379,6 +382,7 @@
|
|||
:image-path :imagePath
|
||||
:image-width :imageWidth
|
||||
:link-previews :linkPreviews
|
||||
:status-link-previews :statusLinkPreviews
|
||||
:response-to :responseTo
|
||||
:sticker :sticker
|
||||
:text :text})))
|
||||
|
|
|
@ -423,11 +423,19 @@
|
|||
(fn [previews]
|
||||
(get previews :unfurled)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/status-link-previews-unfurled
|
||||
:<- [:chat/status-link-previews]
|
||||
(fn [previews]
|
||||
(:unfurled previews)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/link-previews?
|
||||
:<- [:chats/link-previews-unfurled]
|
||||
(fn [previews]
|
||||
(boolean (seq previews))))
|
||||
:<- [:chats/status-link-previews-unfurled]
|
||||
(fn [previews status-link-previews]
|
||||
(boolean (or (seq status-link-previews)
|
||||
(seq previews)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chat/check-channel-muted?
|
||||
|
|
|
@ -102,6 +102,21 @@
|
|||
(fn [messages [_ chat-id message-id]]
|
||||
(get-in messages [chat-id message-id :link-previews])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/message-link-previews?
|
||||
:<- [:messages/messages]
|
||||
(fn [messages [_ chat-id message-id]]
|
||||
(-> messages
|
||||
(get-in [chat-id message-id :link-previews])
|
||||
count
|
||||
pos?)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/message-status-link-previews
|
||||
:<- [:messages/messages]
|
||||
(fn [messages [_ chat-id message-id]]
|
||||
(get-in messages [chat-id message-id :status-link-previews])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/pinned
|
||||
:<- [:messages/pin-messages]
|
||||
|
|
|
@ -159,3 +159,19 @@
|
|||
:pinned-at nil
|
||||
:pinned-by :test-user}]
|
||||
(rf/sub [sub-name :0xChat])))))
|
||||
|
||||
(def message-with-link-previews
|
||||
{:0xChat {:0x01 {:content {:response-to nil}
|
||||
:quoted-message nil
|
||||
:message-id "0x1"
|
||||
:from :xyz
|
||||
:timestamp-str "14:00"
|
||||
:content-type constants/content-type-text
|
||||
:chat-id :0xChat
|
||||
:link-previews [{:dummy-link-preview 1}]}}})
|
||||
|
||||
(h/deftest-sub :chats/message-link-previews?
|
||||
[sub-name]
|
||||
(testing "It returns true if link previews exists in a message"
|
||||
(swap! rf-db/app-db assoc :messages message-with-link-previews)
|
||||
(is (rf/sub [sub-name :0xChat :0x01]))))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
(ns tests.integration-test.standard-auth-test
|
||||
(:require
|
||||
[cljs.test :refer [deftest testing is]]
|
||||
[cljs.test :refer [deftest is testing]]
|
||||
[day8.re-frame.test :as rf-test]
|
||||
re-frame.core
|
||||
[test-helpers.integration :as h]
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "v0.176.6",
|
||||
"commit-sha1": "200d5f054096518848adabca82d56105af97086f",
|
||||
"src-sha256": "02c04j7dd29wd0sxbk97yfwq8gj3hwjvlrj07b188cqkq08p920f"
|
||||
"version": "v0.176.8",
|
||||
"commit-sha1": "8c0e24dc260031a822604f7a2771f22daea79aa4",
|
||||
"src-sha256": "1c6r5gizcvixawl1c0lxd022wg54m5qxw8rr1q1i9221pzbfmmsl"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue