diff --git a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java index 157f8f3442fa..80da780158f5 100644 --- a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java +++ b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java @@ -1324,7 +1324,6 @@ public void run() { StatusThreadPoolExecutor.getInstance().execute(r); } - @ReactMethod public void getNodesFromContract(final String rpcEndpoint, final String contractAddress, final Callback callback) { Log.d(TAG, "getNodesFromContract"); diff --git a/resources/images/ui/unfurl-dark@2x.png b/resources/images/ui/unfurl-dark@2x.png new file mode 100644 index 000000000000..580b7268a2ad Binary files /dev/null and b/resources/images/ui/unfurl-dark@2x.png differ diff --git a/resources/images/ui/unfurl-dark@3x.png b/resources/images/ui/unfurl-dark@3x.png new file mode 100644 index 000000000000..e8cbce6b5499 Binary files /dev/null and b/resources/images/ui/unfurl-dark@3x.png differ diff --git a/resources/images/ui/unfurl@2x.png b/resources/images/ui/unfurl@2x.png new file mode 100644 index 000000000000..11eafa17e44e Binary files /dev/null and b/resources/images/ui/unfurl@2x.png differ diff --git a/resources/images/ui/unfurl@3x.png b/resources/images/ui/unfurl@3x.png new file mode 100644 index 000000000000..5d0b87deada1 Binary files /dev/null and b/resources/images/ui/unfurl@3x.png differ diff --git a/src/status_im/chat/models/link_preview.cljs b/src/status_im/chat/models/link_preview.cljs new file mode 100644 index 000000000000..2cddb7f057f7 --- /dev/null +++ b/src/status_im/chat/models/link_preview.cljs @@ -0,0 +1,58 @@ +(ns status-im.chat.models.link-preview + (:require [re-frame.core :as re-frame] + [status-im.utils.fx :as fx] + [status-im.multiaccounts.update.core :as multiaccounts.update] + [status-im.ethereum.json-rpc :as json-rpc] + [taoensso.timbre :as log])) + +(fx/defn enable + {:events [::enable]} + [{{:keys [multiaccount]} :db :as cofx} site enabled?] + (fx/merge cofx + (multiaccounts.update/multiaccount-update + :link-previews-enabled-sites + (if enabled? + (conj (get multiaccount :link-previews-enabled-sites #{}) site) + (disj (get multiaccount :link-previews-enabled-sites #{}) site)) + {}))) + +(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 #(log/error "Can't get preview data for " link)}]})) + +(fx/defn cache-link-preview-data + {:events [::cache-link-preview-data]} + [{{:keys [multiaccount]} :db :as cofx} site {:keys [error] :as data}] + (when-not error + (multiaccounts.update/optimistic + cofx + :link-previews-cache + (assoc (get multiaccount :link-previews-cache {}) site data)))) + +(fx/defn should-suggest-link-preview + {:events [::should-suggest-link-preview]} + [{:keys [db] :as cofx} enabled?] + (multiaccounts.update/multiaccount-update + cofx + :link-preview-request-enabled (boolean enabled?) + {})) + +(fx/defn request-link-preview-whitelist + [_] + {::json-rpc/call [{:method (json-rpc/call-ext-method "getLinkPreviewWhitelist") + :params [] + :on-success #(re-frame/dispatch [::link-preview-whitelist-received %]) + :on-error #(log/error "Failed to get link preview whitelist")}]}) + +(fx/defn save-link-preview-whitelist + {:events [::link-preview-whitelist-received]} + [cofx whitelist] + (fx/merge cofx + (multiaccounts.update/multiaccount-update + :link-previews-whitelist whitelist {}))) + diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index 3ef4c4ecb0c6..9b255fdcafc5 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -124,7 +124,9 @@ :currency :usd :appearance 0 :log-level config/log-level - :webview-allow-permission-requests? false}) + :webview-allow-permission-requests? false + :link-previews-enabled-sites #{} + :link-preview-request-enabled true}) (defn default-visible-tokens [chain] (get-in default-multiaccount [:wallet/visible-tokens chain])) diff --git a/src/status_im/data_store/messages.cljs b/src/status_im/data_store/messages.cljs index 36b2483f6d19..00f33512c1e3 100644 --- a/src/status_im/data_store/messages.cljs +++ b/src/status_im/data_store/messages.cljs @@ -37,10 +37,11 @@ :ens-name (:ensName message) :line-count (:lineCount message) :parsed-text (:parsedText message) + :links (:links message) :rtl? (:rtl message) :response-to (:responseTo message)} :outgoing (boolean (:outgoingStatus message))) - (dissoc :ensName :chatId :text :rtl :responseTo :image :sticker :lineCount :parsedText))) + (dissoc :ensName :chatId :text :rtl :responseTo :image :sticker :lineCount :parsedText :links))) (defn update-outgoing-status-rpc [message-id status] {::json-rpc/call [{:method (json-rpc/call-ext-method "updateMessageOutgoingStatus") diff --git a/src/status_im/data_store/settings.cljs b/src/status_im/data_store/settings.cljs index 20ae9d6f639d..fc8783952953 100644 --- a/src/status_im/data_store/settings.cljs +++ b/src/status_im/data_store/settings.cljs @@ -40,6 +40,7 @@ (update :pinned-mailservers rpc->pinned-mailservers) (update :stickers/packs-installed rpc->stickers-packs) (update :stickers/packs-pending set) + (update :link-previews-enabled-sites set) (update :custom-bootnodes rpc->custom-bootnodes) (update :custom-bootnodes-enabled? rpc->custom-bootnodes) (update :currency keyword))) diff --git a/src/status_im/ethereum/json_rpc.cljs b/src/status_im/ethereum/json_rpc.cljs index 0996ebcdd4e6..b5552050cdb5 100644 --- a/src/status_im/ethereum/json_rpc.cljs +++ b/src/status_im/ethereum/json_rpc.cljs @@ -81,6 +81,8 @@ "wakuext_sendEmojiReaction" {} "wakuext_sendEmojiReactionRetraction" {} "wakuext_emojiReactionsByChatID" {} + "wakuext_getLinkPreviewWhitelist" {} + "wakuext_getLinkPreviewData" {} ;;TODO not used anywhere? "wakuext_deleteChat" {} "wakuext_saveContact" {} diff --git a/src/status_im/multiaccounts/login/core.cljs b/src/status_im/multiaccounts/login/core.cljs index a81d2ae6093f..8ca932862974 100644 --- a/src/status_im/multiaccounts/login/core.cljs +++ b/src/status_im/multiaccounts/login/core.cljs @@ -29,7 +29,8 @@ [status-im.wallet.prices :as prices] [status-im.acquisition.core :as acquisition] [taoensso.timbre :as log] - [status-im.data-store.invitations :as data-store.invitations])) + [status-im.data-store.invitations :as data-store.invitations] + [status-im.chat.models.link-preview :as link-preview])) (re-frame/reg-fx ::login @@ -210,7 +211,8 @@ (mobile-network/on-network-status-change) (get-group-chat-invitations) (logging/set-log-level (:log-level multiaccount)) - (multiaccounts/switch-preview-privacy-mode-flag)))) + (multiaccounts/switch-preview-privacy-mode-flag) + (link-preview/request-link-preview-whitelist)))) (defn get-new-auth-method [auth-method save-password?] (when save-password? @@ -274,6 +276,7 @@ :mailserver-topics {} :default-mailserver true}) (multiaccounts/switch-preview-privacy-mode-flag) + (link-preview/request-link-preview-whitelist) (logging/set-log-level (:log-level multiaccount))))) (defn- keycard-setup? [cofx] diff --git a/src/status_im/native_module/core.cljs b/src/status_im/native_module/core.cljs index 9ecb1b476dfa..8b6677e6cc5c 100644 --- a/src/status_im/native_module/core.cljs +++ b/src/status_im/native_module/core.cljs @@ -385,6 +385,17 @@ (log/debug "[native-module] deactivateKeepAwake") (.deactivateKeepAwake ^js (status))) +(defn link-preview-whitelist + "Get link preview whitelist" + [callback] + (.getLinkPreviewWhitelist ^js (status) #(callback (types/json->clj %)))) + +(defn link-preview-data + "Get link preview data" + [link callback] + (log/debug "[native-module] link-preview-data") + (.getLinkPreviewData ^js (status) link #(callback (types/json->clj %)))) + (defn reset-keyboard-input [input selection] (log/debug "[native-module] resetKeyboardInput") (when platform/android? diff --git a/src/status_im/react_native/resources.cljs b/src/status_im/react_native/resources.cljs index 5431cc745194..7fd06e60ab1f 100644 --- a/src/status_im/react_native/resources.cljs +++ b/src/status_im/react_native/resources.cljs @@ -34,6 +34,8 @@ :dapp-store (js/require "../resources/images/ui/dapp-store.png") :ens-header (js/require "../resources/images/ui/ens-header.png") :ens-header-dark (js/require "../resources/images/ui/ens-header-dark.png") + :unfurl (js/require "../resources/images/ui/unfurl.png") + :unfurl-dark (js/require "../resources/images/ui/unfurl-dark.png") :new-chat-header (js/require "../resources/images/ui/new-chat-header.png") :onboarding-phone (js/require "../resources/images/ui/onboarding-phone.png") :theme-dark (js/require "../resources/images/ui/theme-dark.png") diff --git a/src/status_im/subs.cljs b/src/status_im/subs.cljs index 7e6aa2bb61a7..f20c68b77c25 100644 --- a/src/status_im/subs.cljs +++ b/src/status_im/subs.cljs @@ -2337,3 +2337,29 @@ :<- [:networks/manage] (fn [manage] (not-any? :error (vals manage)))) + +;; LINK PREVIEW ======================================================================================================== + +(re-frame/reg-sub + :link-preview/whitelist + :<- [:multiaccount] + (fn [multiaccount] + (get multiaccount :link-previews-whitelist))) + +(re-frame/reg-sub + :link-preview/cache + :<- [:multiaccount] + (fn [multiaccount] + (get multiaccount :link-previews-cache))) + +(re-frame/reg-sub + :link-preview/enabled-sites + :<- [:multiaccount] + (fn [multiaccount] + (get multiaccount :link-previews-enabled-sites))) + +(re-frame/reg-sub + :link-preview/link-preview-request-enabled + :<- [:multiaccount] + (fn [multiaccount] + (get multiaccount :link-preview-request-enabled))) \ No newline at end of file diff --git a/src/status_im/ui/screens/chat/message/link_preview.cljs b/src/status_im/ui/screens/chat/message/link_preview.cljs new file mode 100644 index 000000000000..6b6746ebd048 --- /dev/null +++ b/src/status_im/ui/screens/chat/message/link_preview.cljs @@ -0,0 +1,97 @@ +(ns status-im.ui.screens.chat.message.link-preview + (:require [re-frame.core :as re-frame] + [clojure.string :as string] + [status-im.ui.components.react :as react] + [quo.core :as quo] + [status-im.utils.security :as security] + [status-im.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]) + (:require-macros [status-im.utils.views :refer [defview letsubs]])) + +(defn link-belongs-to-domain [link domain] + (cond + (string/starts-with? link (str "https://" domain)) true + (string/starts-with? link (str "https://www." domain)) true + :else false)) + +(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})) + +(defn previewable-link [links whitelist enabled-list] + (->> links + (map #(link-extended-info % whitelist enabled-list)) + (filter #(:whitelisted %)) + (first))) + +(defview link-preview-enable-request [] + [react/view styles/link-preview-request-wrapper + [react/view {:margin 12} + [react/image {:source (resources/get-theme-image :unfurl) + :style styles/link-preview-request-image}] + [quo/text {:size :small + :align :center + :style {:margin-top 6}} + (i18n/label :t/enable-link-previews)] + [quo/text {:size :small + :color :secondary + :align :center + :style {:margin-top 2}} + (i18n/label :t/once-enabled-share-metadata)]] + [quo/separator] + [quo/button {:on-press #(re-frame/dispatch [:navigate-to :link-preview-settings]) + :type :secondary} + (i18n/label :enable)] + [quo/separator] + [quo/button {:on-press #(re-frame/dispatch + [::link-preview/should-suggest-link-preview false]) + :type :secondary} + (i18n/label :t/dont-ask)]]) + +(defview link-preview-loader [link outgoing] + (letsubs [cache [:link-preview/cache]] + (let [{:keys [site title thumbnailUrl] :as preview-data} (get cache link)] + (if (not preview-data) + (do + (re-frame/dispatch + [::link-preview/load-link-preview-data link]) + nil) + + [react/touchable-highlight + {:on-press #(when (and (security/safe-link? link)) + (re-frame/dispatch + [:browser.ui/message-link-pressed link]))} + + [react/view (styles/link-preview-wrapper outgoing) + [react/image {:source {:uri thumbnailUrl} + :style (styles/link-preview-image outgoing) + :accessibility-label :member-photo}] + [quo/text {:size :small + :style styles/link-preview-title} + title] + [quo/text {:size :small + :color :secondary + :style styles/link-preview-site} + site]]])))) + +(defview link-preview-wrapper [links outgoing] + (letsubs + [ask-user? [:link-preview/link-preview-request-enabled] + whitelist [:link-preview/whitelist] + enabled-sites [:link-preview/enabled-sites]] + (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] + (when ask-user? + [link-preview-enable-request])))))) \ No newline at end of file diff --git a/src/status_im/ui/screens/chat/message/message.cljs b/src/status_im/ui/screens/chat/message/message.cljs index b1628aeebefb..9f3ec741e28d 100644 --- a/src/status_im/ui/screens/chat/message/message.cljs +++ b/src/status_im/ui/screens/chat/message/message.cljs @@ -17,7 +17,8 @@ [status-im.ui.screens.chat.message.reactions :as reactions] [quo.core :as quo] [reagent.core :as reagent] - [status-im.ui.screens.chat.components.reply :as components.reply]) + [status-im.ui.screens.chat.components.reply :as components.reply] + [status-im.ui.screens.chat.message.link-preview :as link-preview]) (:require-macros [status-im.utils.views :refer [defview letsubs]])) (defview mention-element [from] @@ -213,7 +214,8 @@ [message-author-name from modal]]) ;;MESSAGE CONTENT [react/view - content]]] + content] + [link-preview/link-preview-wrapper (:links (:content message)) outgoing]]] ; delivery status [react/view (style/delivery-status outgoing) [message-delivery-status message]]]) diff --git a/src/status_im/ui/screens/chat/message/styles.cljs b/src/status_im/ui/screens/chat/message/styles.cljs index d1e867f8a69b..e2e82aafd6a3 100644 --- a/src/status_im/ui/screens/chat/message/styles.cljs +++ b/src/status_im/ui/screens/chat/message/styles.cljs @@ -1,6 +1,7 @@ (ns status-im.ui.screens.chat.message.styles (:require [quo.design-system.colors :as colors] - [status-im.ui.screens.chat.styles.photos :as photos])) + [status-im.ui.screens.chat.styles.photos :as photos] + [status-im.ui.components.colors :as components.colors])) (defn picker-wrapper-style [{:keys [display-photo? outgoing]}] (merge {:flex-direction :row @@ -84,3 +85,41 @@ {:background-color (:interactive-02 @colors/theme) ;; FIXME: Use broder color here :border-color "rgba(67, 96, 223, 0.2)"}))) + +(def link-preview-request-wrapper + {:border-radius 16 + :border-width 1 + :border-color components.colors/gray-lighter + :margin-vertical 4}) + +(def link-preview-request-image + {:width 132 + :height 94 + :align-self :center}) + +(defn link-preview-wrapper [outgoing] + {: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) + :border-width 1 + :border-color components.colors/gray-lighter + :margin-vertical 4}) + +(defn link-preview-image [outgoing] + {:height 170 + :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)}) + +(def link-preview-title + {:margin-horizontal 12 + :margin-top 10}) + +(def link-preview-site + {:margin-horizontal 12 + :margin-top 2 + :margin-bottom 10}) \ No newline at end of file diff --git a/src/status_im/ui/screens/link_previews_settings/styles.cljs b/src/status_im/ui/screens/link_previews_settings/styles.cljs new file mode 100644 index 000000000000..175cc5efd7c8 --- /dev/null +++ b/src/status_im/ui/screens/link_previews_settings/styles.cljs @@ -0,0 +1,13 @@ +(ns status-im.ui.screens.link-previews-settings.styles) + +(def link-preview-settings-image + {:height 100 + :align-self :center + :margin-top 16}) + +(def whitelist-container + {:flex-direction :row + :justify-content :space-between}) + +(def enable-all + {:align-self :flex-end}) \ No newline at end of file diff --git a/src/status_im/ui/screens/link_previews_settings/views.cljs b/src/status_im/ui/screens/link_previews_settings/views.cljs new file mode 100644 index 000000000000..4e2677ef9a9e --- /dev/null +++ b/src/status_im/ui/screens/link_previews_settings/views.cljs @@ -0,0 +1,50 @@ +(ns status-im.ui.screens.link-previews-settings.views + (:require-macros [status-im.utils.views :as views]) + (:require [re-frame.core :as re-frame] + [status-im.i18n :as i18n] + [status-im.ui.components.react :as react] + [status-im.ui.components.list.views :as list] + [quo.core :as quo] + [status-im.react-native.resources :as resources] + [status-im.ui.components.topbar :as topbar] + [status-im.ui.screens.link-previews-settings.styles :as styles] + [status-im.chat.models.link-preview :as link-preview])) + +(defn prepare-urls-items-data [link-previews-enabled-sites] + (fn [{:keys [title address]}] + (let [enabled? (contains? link-previews-enabled-sites title)] + {:title title + :subtitle address + :size :small + :accessory :switch + :active (contains? link-previews-enabled-sites title) + :on-press #(re-frame/dispatch + [::link-preview/enable title ((complement boolean) enabled?)])}))) + +(views/defview link-previews-settings [] + (views/letsubs [{:keys [link-previews-whitelist link-previews-enabled-sites]} [:multiaccount]] + [react/view {:flex 1} + [topbar/topbar {:title (i18n/label :t/chat-link-previews)}] + [react/image {:source (resources/get-theme-image :unfurl) + :style styles/link-preview-settings-image}] + [quo/text {:style {:margin 16}} + (i18n/label :t/you-can-choose-preview-websites)] + [quo/separator {:style {:margin-vertical 8}}] + + [react/view styles/whitelist-container + [quo/list-header (i18n/label :t/websites)] + + (when (> (count link-previews-whitelist) 1) + [quo/button {:on-press #(doseq [site (map :title link-previews-whitelist)] + (re-frame/dispatch + [::link-preview/enable site true])) + :type :secondary + :style styles/enable-all} + (i18n/label :t/enable-all)])] + + [list/flat-list + {:data (vec (map (prepare-urls-items-data link-previews-enabled-sites) link-previews-whitelist)) + :key-fn (fn [_ i] (str i)) + :render-fn quo/list-item + :footer [quo/text {:color :secondary + :style {:margin 16}} (i18n/label :t/previewing-may-share-metadata)]}]])) diff --git a/src/status_im/ui/screens/privacy_and_security_settings/views.cljs b/src/status_im/ui/screens/privacy_and_security_settings/views.cljs index c82698b369a6..afc4854bba67 100644 --- a/src/status_im/ui/screens/privacy_and_security_settings/views.cljs +++ b/src/status_im/ui/screens/privacy_and_security_settings/views.cljs @@ -63,6 +63,11 @@ :on-press #(re-frame/dispatch [:multiaccounts.ui/preview-privacy-mode-switched ((complement boolean) preview-privacy?)])}] + [quo/list-item {:size :small + :title (i18n/label :t/chat-link-previews) + :chevron true + :on-press #(re-frame/dispatch [:navigate-to :link-previews-settings]) + :accessibility-label :chat-link-previews}] (when platform/android? [quo/list-item {:size :small :title (i18n/label :t/webview-camera-permission-requests) diff --git a/src/status_im/ui/screens/routing/main.cljs b/src/status_im/ui/screens/routing/main.cljs index 92c2866fa009..fb48e6066182 100644 --- a/src/status_im/ui/screens/routing/main.cljs +++ b/src/status_im/ui/screens/routing/main.cljs @@ -24,7 +24,8 @@ [status-im.ui.screens.chat.image.preview.views :as image-preview] [status-im.ui.screens.profile.contact.views :as contact] [status-im.ui.screens.notifications-settings.views :as notifications-settings] - [status-im.ui.screens.wallet.send.views :as wallet])) + [status-im.ui.screens.wallet.send.views :as wallet] + [status-im.ui.screens.link-previews-settings.views :as link-previews])) (defonce main-stack (navigation/create-stack)) (defonce bottom-tabs (navigation/create-bottom-tabs)) @@ -78,6 +79,9 @@ :on-focus [::new-chat.events/new-chat-focus] :transition :presentation-ios :component new-chat/new-contact} + {:name :link-preview-settings + :transition :presentation-ios + :component link-previews/link-previews-settings} {:name :new-public-chat :transition :presentation-ios :insets {:bottom true} diff --git a/src/status_im/ui/screens/routing/profile_stack.cljs b/src/status_im/ui/screens/routing/profile_stack.cljs index 5a4a38e851fc..c084fe71be5c 100644 --- a/src/status_im/ui/screens/routing/profile_stack.cljs +++ b/src/status_im/ui/screens/routing/profile_stack.cljs @@ -15,6 +15,7 @@ :as offline-messaging-settings] [status-im.ui.screens.dapps-permissions.views :as dapps-permissions] + [status-im.ui.screens.link-previews-settings.views :as link-previews-settings] [status-im.ui.screens.privacy-and-security-settings.views :as privacy-and-security] [status-im.ui.screens.sync-settings.views :as sync-settings] [status-im.ui.screens.advanced-settings.views :as advanced-settings] @@ -80,6 +81,8 @@ :component edit-mailserver/edit-mailserver} {:name :dapps-permissions :component dapps-permissions/dapps-permissions} + {:name :link-previews-settings + :component link-previews-settings/link-previews-settings} {:name :privacy-and-security :component privacy-and-security/privacy-and-security} {:name :appearance diff --git a/status-go-version.json b/status-go-version.json index 326f80e56356..e5be7486ee75 100644 --- a/status-go-version.json +++ b/status-go-version.json @@ -2,7 +2,7 @@ "_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh ' instead", "owner": "status-im", "repo": "status-go", - "version": "v0.62.13", - "commit-sha1": "7467ca7b103f685dd64d73485555f90c181a4484", - "src-sha256": "0gv9jxn5c5arnxdr33rfw2zkly9c2nyss59vbdyf444140bd6y6y" + "version": "v0.62.15", + "commit-sha1": "3e446eed8cf36b1af8f6426c828bc078e105a476", + "src-sha256": "03ddmnf36dkabwml0c0g1c4pn0wi081jzlrkb1lqz6hca2wispv0" } diff --git a/translations/en.json b/translations/en.json index 3467155e1bb1..15dd78e00c62 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1279,6 +1279,15 @@ "address-or-ens-name": "Address or ENS name", "name-optional": "Name (optional)", "mute": "Mute", + "chat-link-previews": "Chat link previews", + "you-can-choose-preview-websites" : "You can choose which of the following websites can preview link of descriptions and pictures in chats", + "previewing-may-share-metadata" : "Previewing links from these websites may share your metadata with their owners", + "websites" : "Websites", + "enable-all" : "Enable all", + "warning-sending-to-contract-descr": "The address you entered is a smart contract, sending funds to this address may result in loss of funds. To interact with a DApp, open the DApp in the Status DApp Browser.", + "dont-ask": "Don't ask me again", + "enable-link-previews": "Enable link previews in chat?", + "once-enabled-share-metadata": "Once enabled, links posted in the chat may share your metadata with the site", "scan-tokens": "Scan tokens", "warning-sending-to-contract-descr": "The address you entered is a smart contract, sending funds to this address may result in loss of funds. To interact with a DApp, open the DApp in the Status DApp Browser.", "cant-open-public-chat": "Can't open public chat",