From 267228a2e9f2f601e497ef1fb54e7c75f6576e80 Mon Sep 17 00:00:00 2001 From: Sean Hagstrom Date: Thu, 14 Mar 2024 19:08:31 +0000 Subject: [PATCH] wip: refactor image-uri helpers --- .../ui/components/chat_icon/screen.cljs | 9 +- .../components/avatars/user_avatar/view.cljs | 27 +++-- src/schema/quo.cljs | 50 +++++++- src/status_im/subs/contact.cljs | 54 +++++---- src/status_im/subs/profile.cljs | 104 ++++++++-------- src/utils/image_server.cljs | 114 +++++------------- 6 files changed, 180 insertions(+), 178 deletions(-) diff --git a/src/legacy/status_im/ui/components/chat_icon/screen.cljs b/src/legacy/status_im/ui/components/chat_icon/screen.cljs index f1cc9efcd876..30dc5df34a8e 100644 --- a/src/legacy/status_im/ui/components/chat_icon/screen.cljs +++ b/src/legacy/status_im/ui/components/chat_icon/screen.cljs @@ -12,7 +12,8 @@ [re-frame.core :as re-frame.core] [react-native.core :as rn] [status-im.contexts.profile.utils :as profile.utils] - [utils.ens.core :as utils.ens])) + [utils.ens.core :as utils.ens] + [utils.image-server :as image-server])) ;;TODO REWORK THIS NAMESPACE @@ -156,9 +157,11 @@ (styles/default-chat-icon-text size) (styles/emoji-chat-icon-text size))} override-styles) - photo-path (if (:fn photo-path) + img-config (:config photo-path) + photo-path (if img-config ;; temp support new media server avatar for old component - {:uri ((:fn photo-path) + {:uri (image-server/get-image-uri + img-config {:size size :full-name name :font-size (get-in styles [:default-chat-icon-text :font-size]) diff --git a/src/quo/components/avatars/user_avatar/view.cljs b/src/quo/components/avatars/user_avatar/view.cljs index 877e6177a5d4..b15d01c4f4e3 100644 --- a/src/quo/components/avatars/user_avatar/view.cljs +++ b/src/quo/components/avatars/user_avatar/view.cljs @@ -8,6 +8,7 @@ [react-native.core :as rn] [react-native.fast-image :as fast-image] [schema.core :as schema] + [utils.image-server :as image-server] utils.string)) (defn initials-avatar @@ -38,22 +39,21 @@ ring? true customization-color :blue} :as props}] - (let [full-name (or full-name "Your Name") + (let [picture-config (:config profile-picture) + full-name (or full-name "Your Name") ;; image generated with `profile-picture-fn` is round cropped ;; no need to add border-radius for them - outer-styles (style/outer size (not (:fn profile-picture))) + outer-styles (style/outer size (not picture-config)) ;; Once image is loaded, fast image re-renders view with the help of reagent atom, ;; But dynamic updates don't work when user-avatar is used inside hole-view ;; https://github.com/status-im/status-mobile/issues/15553 - image-view (if static? no-flicker-image/image fast-image/fast-image) - font-size (get-in style/sizes [size :font-size]) - amount-initials (if (#{:xs :xxs :xxxs} size) 1 2) - sizes (get style/sizes size) - indicator-color (get style/indicator-color (if online? :online :offline)) - profile-picture-fn (:fn profile-picture)] - + image-view (if static? no-flicker-image/image fast-image/fast-image) + font-size (get-in style/sizes [size :font-size]) + amount-initials (if (#{:xs :xxs :xxxs} size) 1 2) + sizes (get style/sizes size) + indicator-color (get style/indicator-color (if online? :online :offline))] [rn/view {:style outer-styles :accessibility-label :user-avatar} - (if (and full-name (not (or profile-picture-fn profile-picture))) + (if (and full-name (not (or picture-config profile-picture))) ;; this is for things that's not user-avatar ;; but are currently using user-avatar to render the initials ;; e.g. community avatar @@ -62,8 +62,9 @@ {:accessibility-label :profile-picture :style outer-styles :source - (cond profile-picture-fn - {:uri (profile-picture-fn + (cond picture-config + {:uri (image-server/get-image-uri + picture-config {:length amount-initials :full-name full-name :font-size (:font-size (text/text-style {:size @@ -75,7 +76,7 @@ :indicator-center-to-edge (when status-indicator? (:status-indicator-center-to-edge sizes)) :indicator-color indicator-color - :override-theme theme + :theme theme :background-color (style/customization-color customization-color theme) :color (:color style/initials-avatar-text) :size (:width outer-styles) diff --git a/src/schema/quo.cljs b/src/schema/quo.cljs index d72993e61f82..8e926ca0c20b 100644 --- a/src/schema/quo.cljs +++ b/src/schema/quo.cljs @@ -2,7 +2,7 @@ (:require [schema.registry :as registry])) -(def ^:private ?profile-picture-fn-params +(def ^:private ?profile-picture-options [:map [:length :int] [:full-name :string] @@ -10,19 +10,63 @@ [:indicator-size {:optional true} [:maybe :int]] [:indicator-color {:optional true} [:maybe :string]] [:indicator-center-to-edge {:optional true} [:maybe :int]] - [:override-theme :schema.common/theme] + [:theme {:optional true} [:maybe :schema.common/theme]] [:background-color :string] [:color :string] [:size :int] [:ring? :boolean] [:ring-width :int]]) +(def ^:private ?account-image-uri-opts + [:map + [:port :int] + [:ratio :double] + [:key-uid :string] + [:image-name :string] + [:theme :schema.common/theme] + [:override-ring? [:maybe :boolean]]]) + +(def ^:private ?initials-image-uri-opts + [:map + [:port :int] + [:ratio :double] + [:uppercase-ratio :double] + [:font-file :string] + [:theme :schema.common/theme] + [:key-uid {:optional true} [:maybe :string]] + [:public-key {:optional true} [:maybe :string]] + [:override-ring? {:optional true} [:maybe :boolean]]]) + +(def ^:private ?contact-image-uri-opts + [:map + [:port :int] + [:clock :int] + [:ratio :double] + [:image-name :string] + [:public-key :string] + [:theme :schema.common/theme] + [:override-ring? [:maybe :boolean]]]) + +(def ?image-uri-config + [:or + [:map + [:kind [:enum :contact]] + [:options ?contact-image-uri-opts]] + [:map + [:kind [:enum :account]] + [:options ?account-image-uri-opts]] + [:map + [:kind [:enum :initials]] + [:options ?initials-image-uri-opts]]]) + (def ^:private ?profile-picture-source [:or :schema.common/image-source [:map - [:fn [:=> [:cat ?profile-picture-fn-params] :string]]]]) + [:config ?image-uri-config]]]) (defn register-schemas [] + (registry/register ::profile-picture-options ?profile-picture-options) + (registry/register ::image-uri-config ?image-uri-config) (registry/register ::profile-picture-source ?profile-picture-source)) diff --git a/src/status_im/subs/contact.cljs b/src/status_im/subs/contact.cljs index 29a97fc5ec64..7255f597f946 100644 --- a/src/status_im/subs/contact.cljs +++ b/src/status_im/subs/contact.cljs @@ -10,8 +10,7 @@ [status-im.contexts.profile.utils :as profile.utils] [utils.address :as address] [utils.collection] - [utils.i18n :as i18n] - [utils.image-server :as image-server])) + [utils.i18n :as i18n])) (re-frame/reg-sub ::query-current-chat-contacts @@ -40,36 +39,39 @@ (reduce (fn [acc image] (let [image-name (:type image) clock (:clock image) - uri (image-server/get-contact-image-uri-fn - {:port port - :ratio pixel-ratio/ratio - :public-key - public-key - :image-name - image-name - ; We pass the clock so that we reload the - ; image if the image is updated - :clock - clock - :theme - theme - :override-ring? - (when ens-name false)})] - (assoc-in acc [(keyword image-name) :fn] uri))) + options {:port port + :ratio pixel-ratio/ratio + :public-key + public-key + :image-name + image-name + ; We pass the clock so that we reload the + ; image if the image is updated + :clock + clock + :theme + theme + :override-ring? + (when ens-name false)}] + (assoc-in acc + [(keyword image-name) :config] + {:kind :contact + :options options}))) images (vals images)) images (if (seq images) images {:thumbnail - {:fn (image-server/get-initials-avatar-uri-fn - {:port port - :ratio pixel-ratio/ratio - :public-key public-key - :override-ring? (when ens-name false) - :uppercase-ratio (:uppercase-ratio constants/initials-avatar-font-conf) - :theme theme - :font-file font-file})}})] + {:config {:kind :initials + :options {:port port + :ratio pixel-ratio/ratio + :public-key public-key + :override-ring? (when ens-name false) + :uppercase-ratio (:uppercase-ratio + constants/initials-avatar-font-conf) + :theme theme + :font-file font-file}}}})] (assoc contact :images images))) diff --git a/src/status_im/subs/profile.cljs b/src/status_im/subs/profile.cljs index e40d800a9dd2..d9be2015ca5e 100644 --- a/src/status_im/subs/profile.cljs +++ b/src/status_im/subs/profile.cljs @@ -11,7 +11,6 @@ [status-im.constants :as constants] [status-im.contexts.profile.utils :as profile.utils] [utils.address :as address] - [utils.image-server :as image-server] [utils.security.core :as security])) (re-frame/reg-sub @@ -38,22 +37,24 @@ :<- [:mediaserver/port] :<- [:initials-avatar-font-file] (fn [[port font-file] [_ profile-pic]] - {:fn + {:config (if profile-pic - (image-server/get-account-image-uri-fn {:port port - :ratio pixel-ratio/ratio - :image-name profile-pic - :override-ring? false - :uppercase-ratio (:uppercase-ratio - constants/initials-avatar-font-conf) - :theme (theme/get-theme)}) - (image-server/get-initials-avatar-uri-fn {:port port - :ratio pixel-ratio/ratio - :theme (theme/get-theme) - :override-ring? false - :uppercase-ratio (:uppercase-ratio - constants/initials-avatar-font-conf) - :font-file font-file}))})) + {:kind :account + :options {:port port + :ratio pixel-ratio/ratio + :image-name profile-pic + :override-ring? false + :uppercase-ratio (:uppercase-ratio + constants/initials-avatar-font-conf) + :theme (theme/get-theme)}} + {:kind :initials + :options {:port port + :ratio pixel-ratio/ratio + :theme (theme/get-theme) + :override-ring? false + :uppercase-ratio (:uppercase-ratio + constants/initials-avatar-font-conf) + :font-file font-file}})})) (re-frame/reg-sub :profile/login-profiles-picture @@ -65,22 +66,23 @@ image-name (-> images first :type) override-ring? (when ens-name? false)] (when profile - {:fn + {:config (if image-name - (image-server/get-account-image-uri-fn {:port port - :ratio pixel-ratio/ratio - :image-name image-name - :key-uid target-key-uid - :theme (theme/get-theme) - :override-ring? override-ring?}) - (image-server/get-initials-avatar-uri-fn - {:port port - :ratio pixel-ratio/ratio - :key-uid target-key-uid - :theme (theme/get-theme) - :uppercase-ratio (:uppercase-ratio constants/initials-avatar-font-conf) - :override-ring? override-ring? - :font-file font-file}))})))) + {:kind :account + :options {:port port + :ratio pixel-ratio/ratio + :image-name image-name + :key-uid target-key-uid + :theme (theme/get-theme) + :override-ring? override-ring?}} + {:kind :initials + :options {:port port + :ratio pixel-ratio/ratio + :key-uid target-key-uid + :theme (theme/get-theme) + :uppercase-ratio (:uppercase-ratio constants/initials-avatar-font-conf) + :override-ring? override-ring? + :font-file font-file}})})))) ;; DEPRECATED ;; use `:profile/public-key` instead @@ -324,28 +326,30 @@ theme (theme/get-theme) avatar-opts (assoc avatar-opts :override-ring? (when ens-name? false)) images-with-uri (mapv (fn [{key-uid :keyUid image-name :type :as image}] - (let [uri-fn (image-server/get-account-image-uri-fn - (merge - {:port port - :ratio pixel-ratio/ratio - :image-name image-name - :key-uid key-uid - :theme theme} - avatar-opts))] - (assoc image :fn uri-fn))) + (assoc image + :config + {:kind :account + :options (merge + {:port port + :ratio pixel-ratio/ratio + :image-name image-name + :key-uid key-uid + :theme theme} + avatar-opts)})) images) new-images (if (seq images-with-uri) images-with-uri - [{:fn (image-server/get-initials-avatar-uri-fn - (merge {:port port - :ratio pixel-ratio/ratio - :uppercase-ratio - (:uppercase-ratio - constants/initials-avatar-font-conf) - :key-uid key-uid - :theme theme - :font-file font-file} - avatar-opts))}])] + [{:config {:kind :initials + :options (merge + {:port port + :ratio pixel-ratio/ratio + :uppercase-ratio + (:uppercase-ratio + constants/initials-avatar-font-conf) + :key-uid key-uid + :theme theme + :font-file font-file} + avatar-opts)}}])] (assoc profile :images new-images))) (re-frame/reg-sub diff --git a/src/utils/image_server.cljs b/src/utils/image_server.cljs index 33f44901ecac..720bfc829488 100644 --- a/src/utils/image_server.cljs +++ b/src/utils/image_server.cljs @@ -3,6 +3,7 @@ [react-native.fs :as utils.fs] [react-native.platform :as platform] [schema.core :as schema] + [schema.quo] [utils.datetime :as datetime])) (def ^:const image-server-uri-prefix "https://localhost:") @@ -53,8 +54,7 @@ 4)) (defn get-account-image-uri - "fn to get the avatar uri when multiaccount has custom image set - not directly called, check `get-account-image-uri-fn` + "fn to get the avatar uri when multiaccount has custom image set. color formats (for all color options): #RRGGBB @@ -66,7 +66,8 @@ placeholder-avatar: pass image file path as `image-name` `indicator-size` is outer indicator radius - `indicator-size` - `indicator-border` is inner indicator radius" + `indicator-size` - `indicator-border` is inner indicator radius + `ring?` shows or hides ring for account with ens name" [{:keys [port public-key image-name key-uid size theme indicator-size indicator-border indicator-center-to-edge indicator-color ring? ring-width ratio]}] @@ -99,38 +100,8 @@ "&ringWidth=" (* ring-width ratio))) -(defn get-account-image-uri-fn - "pass the result fn to user-avatar component as `:profile-picture` - - use this fn in subs to set multiaccount `:images` as [{:fn ...}] - pass the image to user-avatar - user-avatar can fill the rest style related options - - set `override-ring?` to a non-nil value to override `ring?`, mainly used to - hide ring for account with ens name - - check `get-account-image-uri` for color formats" - [{:keys [port public-key key-uid image-name theme override-ring? ratio]}] - (fn [{:keys [size indicator-size indicator-border indicator-center-to-edge - indicator-color ring? ring-width override-theme]}] - (get-account-image-uri - {:port port - :image-name image-name - :size size - :public-key public-key - :ratio ratio - :key-uid key-uid - :theme (if (nil? override-theme) theme override-theme) - :indicator-size indicator-size - :indicator-border indicator-border - :indicator-center-to-edge indicator-center-to-edge - :indicator-color indicator-color - :ring? (if (nil? override-ring?) ring? override-ring?) - :ring-width ring-width}))) - (defn get-initials-avatar-uri "fn to get the avatar uri when account/contact/placeholder has no custom pic set - not directly called, check `get-account-initials-uri-fn` multiaccount: at least one of `key-uid`, `public-key` is required to render the ring contact: `public-key` is required to render the ring @@ -138,6 +109,7 @@ check `get-account-image-uri` for color formats check `get-font-file-ready` for `font-file` + `ring?` shows or hides ring for account with ens name `uppercase-ratio` is the uppercase-height/line-height for `font-file`" [{:keys [port public-key key-uid theme ring? length size background-color color font-size font-file uppercase-ratio indicator-size indicator-border @@ -196,40 +168,13 @@ [:font-file string?]]] [:string]]) -(defn get-initials-avatar-uri-fn - "return a fn that calls `get-account-initials-uri` - pass the fn to user-avatar component to fill the style related options - - check `get-account-image-uri` for color formats +(defn get-contact-image-uri + "check `get-account-image-uri` for color formats check `get-font-file-ready` for `font-file` - check `get-account-image-uri-fn` for `override-ring?`" - [{:keys [port public-key key-uid theme override-ring? font-file ratio uppercase-ratio]}] - (fn [{:keys [full-name length size background-color font-size color - indicator-size indicator-border indicator-color indicator-center-to-edge - ring? ring-width override-theme]}] - (get-initials-avatar-uri - {:port port - :public-key public-key - :ratio ratio - :key-uid key-uid - :full-name full-name - :length length - :size size - :background-color background-color - :theme (if (nil? override-theme) theme override-theme) - :ring? (if (nil? override-ring?) ring? override-ring?) - :ring-width ring-width - :font-size font-size - :color color - :font-file font-file - :uppercase-ratio uppercase-ratio - :indicator-size indicator-size - :indicator-border indicator-border - :indicator-center-to-edge indicator-center-to-edge - :indicator-color indicator-color}))) - -(defn get-contact-image-uri + `public-key` is required to render the ring + `ring?` shows or hides ring for account with ens name + `uppercase-ratio` is the uppercase-height/line-height for `font-file`" [{:keys [port public-key image-name clock theme indicator-size indicator-border indicator-center-to-edge indicator-color size ring? ring-width ratio]}] (str @@ -259,24 +204,6 @@ "&ringWidth=" (* ring-width ratio))) -(defn get-contact-image-uri-fn - [{:keys [port public-key image-name theme override-ring? clock ratio]}] - (fn [{:keys [size indicator-size indicator-border indicator-center-to-edge - indicator-color ring? ring-width override-theme]}] - (get-contact-image-uri {:port port - :ratio ratio - :image-name image-name - :public-key public-key - :size size - :theme (if (nil? override-theme) theme override-theme) - :clock clock - :indicator-size indicator-size - :indicator-border indicator-border - :indicator-center-to-edge indicator-center-to-edge - :indicator-color indicator-color - :ring? (if (nil? override-ring?) ring? override-ring?) - :ring-width ring-width}))) - (defn get-qr-image-uri-for-any-url [{:keys [url port qr-size error-level]}] (let [qr-url-base64 (js/btoa url) @@ -294,3 +221,24 @@ "&size=" qr-size)] media-server-url)) + +(defn get-image-uri + [{:keys [kind options]} + profile-picture-options] + ((case kind + :account get-account-image-uri + :contact get-contact-image-uri + :initials get-initials-avatar-uri + str) + (-> (merge options profile-picture-options) + (assoc :ring? + (if (nil? (:override-ring? options)) + (:ring? profile-picture-options) + (:override-ring? options)))))) + +(schema/=> get-image-uri + [:=> + [:cat + :schema.quo/image-uri-config + :schema.quo/profile-picture-options] + :string])