community links unfurling

Signed-off-by: Volodymyr Kozieiev <vkjr.sp@gmail.com>
This commit is contained in:
Volodymyr Kozieiev 2021-04-19 15:12:53 +03:00
parent fab241f6ac
commit b29912f7f7
No known key found for this signature in database
GPG Key ID: 82B04968DF4C0535
11 changed files with 166 additions and 72 deletions

View File

@ -27,16 +27,23 @@
#{})
{})))
(fx/defn resolve-community-info
{:events [::resolve-community-info]}
[cofx community-id]
{::json-rpc/call [{:method (json-rpc/call-ext-method "requestCommunityInfoFromMailserver")
:params [community-id]
:on-success #()
:on-error #(log/error "Failed to request community info from mailserver")}]})
(fx/defn load-link-preview-data
{:events [::load-link-preview-data]}
[cofx link]
(fx/merge cofx
{::json-rpc/call [{:method (json-rpc/call-ext-method "getLinkPreviewData")
:params [link]
:on-success #(re-frame/dispatch [::cache-link-preview-data link %])
:on-error #(re-frame/dispatch [::cache-link-preview-data
link
{:error (str "Can't get preview data for " link)}])}]}))
{::json-rpc/call [{:method (json-rpc/call-ext-method "getLinkPreviewData")
:params [link]
:on-success #(re-frame/dispatch [::cache-link-preview-data link %])
:on-error #(re-frame/dispatch [::cache-link-preview-data
link
{:error (str "Can't get preview data for " link)}])}]})
(fx/defn cache-link-preview-data
{:events [::cache-link-preview-data]}
@ -46,6 +53,15 @@
:link-previews-cache
(assoc (get multiaccount :link-previews-cache {}) site data)))
(defn community-link [id]
(str "https://join.status.im/c/" id))
(defn cache-community-preview-data
[{:keys [id] :as community}]
(re-frame/dispatch [::cache-link-preview-data
(community-link id)
community]))
(fx/defn should-suggest-link-preview
{:events [::should-suggest-link-preview]}
[{:keys [db] :as cofx} enabled?]

View File

@ -115,6 +115,7 @@
(def regx-italic #"~[^~]+~")
(def regx-backquote #"`[^`]+`")
(def regx-universal-link #"((^https?://join.status.im/)|(^status-im://))[\x00-\x7F]+$")
(def regx-community-universal-link #"((^https?://join.status.im/)|(^status-im://))c/([\x00-\x7F]+)$")
(def regx-deep-link #"((^ethereum:.*)|(^status-im://[\x00-\x7F]+$))")
(def ^:const dapp-permission-contact-code "contact-code")

View File

@ -84,6 +84,7 @@
"wakuext_emojiReactionsByChatID" {}
"wakuext_getLinkPreviewWhitelist" {}
"wakuext_getLinkPreviewData" {}
"wakuext_requestCommunityInfoFromMailserver" {}
;;TODO not used anywhere?
"wakuext_deleteChat" {}
"wakuext_saveContact" {}

View File

@ -43,7 +43,8 @@
"b/" browser-extractor
"browser/" browser-extractor
["p/" :chat-id] :private-chat
["cr/" :community-id] :community-requests
["cr/" :community-id] :community-requests
["c/" :community-id] :community
"g/" group-chat-extractor
["wallet/" :account] :wallet-account
["u/" :user-id] :user
@ -205,6 +206,9 @@
(= handler :community-requests)
(cb {:type handler :community-id (:community-id route-params)})
(= handler :community)
(cb {:type handler :community-id (:community-id route-params)})
(= handler :referrals)
(cb (match-referral route-params))

View File

@ -8,6 +8,7 @@
[status-im.transport.message.core :as transport.message]
[status-im.notifications.local :as local-notifications]
[status-im.chat.models.message :as models.message]
[status-im.chat.models.link-preview :as link.preview]
[status-im.utils.fx :as fx]
[taoensso.timbre :as log]))
@ -69,4 +70,5 @@
"messages.new" (transport.message/sanitize-messages-and-process-response cofx event-js true)
"wallet" (ethereum.subscriptions/new-wallet-event cofx (js->clj event-js :keywordize-keys true))
"local-notifications" (local-notifications/process cofx (js->clj event-js :keywordize-keys true))
"community.found" (link.preview/cache-community-preview-data (js->clj event-js :keywordize-keys true))
(log/debug "Event " type " not handled"))))

View File

@ -7,7 +7,9 @@
[status-im.i18n.i18n :as i18n]
[status-im.ui.screens.chat.message.styles :as styles]
[status-im.react-native.resources :as resources]
[status-im.chat.models.link-preview :as link-preview])
[status-im.chat.models.link-preview :as link-preview]
[status-im.ui.screens.communities.icon :as communities.icon]
[status-im.constants :as constants])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
(defn link-belongs-to-domain [link domain]
@ -16,16 +18,25 @@
(string/starts-with? link (str "https://www." domain)) true
:else false))
(defn community-id-from-link [link]
(nth (re-find constants/regx-community-universal-link link) 4))
(defn domain-info-if-whitelisted [link whitelist]
(first (filter
#(link-belongs-to-domain link (:address %))
whitelist)))
(defn link-extended-info [link whitelist enabled-list]
(let [domain-info (domain-info-if-whitelisted link whitelist)]
{:whitelisted (not (nil? domain-info))
:enabled (contains? enabled-list (:title domain-info))
:link link}))
(let [domain-info (domain-info-if-whitelisted link whitelist)
community-id (community-id-from-link link)]
(if-not community-id
{:whitelisted (not (nil? domain-info))
:enabled (contains? enabled-list (:title domain-info))
:link link}
{:whitelisted true
:enabled true
:link link
:community true})))
(defn previewable-link [links whitelist enabled-list]
(->> links
@ -88,6 +99,45 @@
:style styles/link-preview-site}
site]])]])))))
(defview community-preview [community outgoing timeline]
(let [{:keys [name members description verified]} community
members-count (count members)]
[react/view (styles/link-preview-wrapper outgoing timeline)
(if verified [quo/text {:size :small
:color :link
:style styles/community-preview-header}
(i18n/label :t/verified-community)]
[quo/text {:size :small
:color :secondary
:style styles/community-preview-header}
(i18n/label :t/community)])
[quo/separator]
[react/view {:flex-direction :row :align-self :flex-start :margin 12}
[communities.icon/community-icon community]
[react/view {:flex 1 :flex-direction :column :margin-left 12}
[quo/text {:weight :bold :size :large} name]
[quo/text description]
[quo/text {:size :small
:color :secondary}
(i18n/label-pluralize members-count :t/community-members {:count members-count})]]]
[quo/separator]
[quo/button {:on-press #(re-frame/dispatch [:navigate-to
:community
{:community-id (:id community)}])
:type :secondary}
(i18n/label :t/view)]]))
(defview community-preview-loader [community-link outgoing timeline]
(letsubs [cache [:link-preview/cache]]
{:component-did-mount (fn []
(let [community (get cache community-link)
community-id (community-id-from-link community-link)]
(when-not community
(re-frame/dispatch
[::link-preview/resolve-community-info community-id]))))}
(when-let [community (get cache community-link)]
[community-preview community outgoing timeline])))
(defview link-preview-wrapper [links outgoing timeline]
(letsubs
[ask-user? [:link-preview/link-preview-request-enabled]
@ -95,9 +145,9 @@
enabled-sites [:link-preview/enabled-sites]]
(when links
(let [link-info (previewable-link links whitelist enabled-sites)
{:keys [link whitelisted enabled]} link-info]
(when (and link whitelisted)
(if enabled
[link-preview-loader link outgoing timeline]
(when ask-user?
[link-preview-enable-request])))))))
{:keys [link whitelisted enabled community]} link-info
link-whitelisted (and link whitelisted)]
(cond
community [community-preview-loader link outgoing timeline]
(and link-whitelisted enabled) [link-preview-loader link outgoing timeline]
(and link-whitelisted ask-user?) [link-preview-enable-request])))))

View File

@ -103,6 +103,9 @@
:height 94
:align-self :center})
(def community-preview-header
{:margin 8 :margin-left 12})
(defn link-preview-wrapper [outgoing timeline]
{:overflow :hidden
:border-top-left-radius 16

View File

@ -117,11 +117,11 @@
:icon :main-icons/objects
:on-press #(hide-sheet-and-dispatch [::communities/export-pressed id])}])]))
(defn welcome-blank-page []
(defn blank-page [text]
[rn/view {:style {:padding 16 :flex 1 :flex-direction :row :align-items :center :justify-content :center}}
[quo/text {:align :center
:color :secondary}
(i18n/label :t/welcome-community-blank-message)]])
text]])
(defn community-chat-item [{:keys [chat-id] :as home-item}]
[inner-item/home-list-item
@ -136,7 +136,7 @@
(defn community-chat-list [chats]
(if (empty? chats)
[welcome-blank-page]
[blank-page (i18n/label :t/welcome-community-blank-message)]
[list/flat-list
{:key-fn :chat-id
:content-container-style {:padding-vertical 8}
@ -188,59 +188,66 @@
:data chats
:render-fn channel-preview-item}]))
(defn unknown-community []
[rn/view {:style {:flex 1}}
[topbar/topbar {:title (i18n/label :t/not-found)}]
[blank-page (i18n/label :t/community-info-not-found)]])
(defn community [route]
(let [{:keys [community-id]} (get-in route [:route :params])
{:keys [id chats name images members permissions color joined can-request-access?
can-join? requested-to-join-at admin]
:as community} (<sub [:communities/community community-id])]
[rn/view {:style {:flex 1}}
[topbar/topbar
{:content
[toolbar-content
id
name
color
images
(not= (:access permissions) constants/community-no-membership-access)
(count members)]
:right-accessories
(when (or admin joined)
[{:icon :main-icons/more
:accessibility-label :community-menu-button
:on-press #(>evt [:bottom-sheet/show-sheet
(if community
[rn/view {:style {:flex 1}}
[topbar/topbar
{:content
[toolbar-content
id
name
color
images
(not= (:access permissions) constants/community-no-membership-access)
(count members)]
:right-accessories
(when (or admin joined)
[{:icon :main-icons/more
:accessibility-label :community-menu-button
:on-press #(>evt [:bottom-sheet/show-sheet
{:content (fn []
[community-actions community])}])}])}]
(if joined
[community-channel-list id]
[community-channel-preview-list id chats])
(when admin
[components.plus-button/plus-button
{:on-press #(>evt [:bottom-sheet/show-sheet
{:content (fn []
[community-actions community])}])}])}]
(if joined
[community-channel-list id]
[community-channel-preview-list id chats])
(when admin
[components.plus-button/plus-button
{:on-press #(>evt [:bottom-sheet/show-sheet
{:content (fn []
[community-plus-actions community])}])
:accessibility-label :new-chat-button}])
(when-not joined
(cond
can-join?
[toolbar/toolbar
{:show-border? true
:center [quo/button {:on-press #(>evt [::communities/join id])
:type :secondary}
(i18n/label :t/join)]}]
can-request-access?
(if (and (pos? requested-to-join-at)
(not (can-request-access-again? requested-to-join-at)))
[community-plus-actions community])}])
:accessibility-label :new-chat-button}])
(when-not joined
(cond
can-join?
[toolbar/toolbar
{:show-border? true
:left [quo/text {:color :secondary} (i18n/label :t/membership-request-pending)]}]
[toolbar/toolbar
{:show-border? true
:center [quo/button {:on-press #(>evt [::communities/request-to-join id])
:center [quo/button {:on-press #(>evt [::communities/join id])
:type :secondary}
(i18n/label :t/request-access)]}])
:else
[toolbar/toolbar
{:show-border? true
:center [quo/button {:on-press #(>evt [::communities/join id])
:type :secondary}
(i18n/label :t/follow)]}]))]))
(i18n/label :t/join)]}]
can-request-access?
(if (and (pos? requested-to-join-at)
(not (can-request-access-again? requested-to-join-at)))
[toolbar/toolbar
{:show-border? true
:left [quo/text {:color :secondary} (i18n/label :t/membership-request-pending)]}]
[toolbar/toolbar
{:show-border? true
:center [quo/button {:on-press #(>evt [::communities/request-to-join id])
:type :secondary}
(i18n/label :t/request-access)]}])
:else
[toolbar/toolbar
{:show-border? true
:center [quo/button {:on-press #(>evt [::communities/join id])
:type :secondary}
(i18n/label :t/follow)]}]))]
[unknown-community])))

View File

@ -27,6 +27,7 @@
(def links {:public-chat "%s/%s"
:private-chat "%s/p/%s"
:community-requests "%s/cr/%s"
:community "%s/c/%s"
:group-chat "%s/g/%s"
:user "%s/u/%s"
:browse "%s/b/%s"})
@ -64,6 +65,10 @@
(log/info "universal-links: handling community request " community-id)
(navigation/navigate-to-cofx cofx :community-requests-to-join {:community-id community-id}))
(fx/defn handle-community [cofx {:keys [community-id]}]
(log/info "universal-links: handling community" community-id)
(navigation/navigate-to-cofx cofx :community {:community-id community-id}))
(fx/defn handle-public-chat [cofx {:keys [topic]}]
(log/info "universal-links: handling public chat" topic)
(when (seq topic)
@ -122,6 +127,7 @@
:public-chat (handle-public-chat cofx data)
:private-chat (handle-private-chat cofx data)
:community-requests (handle-community-requests cofx data)
:community (handle-community cofx data)
:contact (handle-view-profile cofx data)
:browser (handle-browse cofx data)
:eip681 (handle-eip681 cofx data)

View File

@ -2,7 +2,7 @@
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
"owner": "status-im",
"repo": "status-go",
"version": "v0.76.0",
"commit-sha1": "c739f73f497b2cc1f22be0a176683193766d5193",
"src-sha256": "1db355sqsaj9g2hdzs9db29azrf8s1mzp0x62a6sny9gyiwwl5vd"
"version": "v0.76.3",
"commit-sha1": "0e048081b0cb9f8324f4b64b1b042185a6798141",
"src-sha256": "1p0y8af3pzyab3f0qphyy1sm0x5m8c7kg05n0qrfpxsydy7sh1v4"
}

View File

@ -1509,6 +1509,10 @@
"rpc-usage-copy": "Copy",
"community-message-preview": "Invitation to join {{community-name}}",
"non-contacts": "Non contacts",
"community": "Community",
"verified-community": "✓ Verified community",
"community-info-not-found": "Community information not found",
"not-found": "Not found",
"activity": "Activity",
"reject-and-delete": "Reject and delete",
"accept-and-add": "Accept and add"