Refactor image server uri helpers (#19271)

* tweak: refactor image-uri helpers

* fix: add `:primary` as customization color for profile images

primary is being used as the default color for accounts that were migrated without customization color to a default color
This commit is contained in:
Sean Hagstrom 2024-05-09 11:01:49 +01:00 committed by GitHub
parent 7f40f410e7
commit 3e5d758e92
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 174 additions and 186 deletions

View File

@ -12,7 +12,8 @@
[re-frame.core :as re-frame.core] [re-frame.core :as re-frame.core]
[react-native.core :as rn] [react-native.core :as rn]
[status-im.contexts.profile.utils :as profile.utils] [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 ;;TODO REWORK THIS NAMESPACE
@ -156,9 +157,11 @@
(styles/default-chat-icon-text size) (styles/default-chat-icon-text size)
(styles/emoji-chat-icon-text size))} (styles/emoji-chat-icon-text size))}
override-styles) 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 ;; temp support new media server avatar for old component
{:uri ((:fn photo-path) {:uri (image-server/get-image-uri
img-config
{:size size {:size size
:full-name name :full-name name
:font-size (get-in styles [:default-chat-icon-text :font-size]) :font-size (get-in styles [:default-chat-icon-text :font-size])

View File

@ -8,6 +8,7 @@
[react-native.core :as rn] [react-native.core :as rn]
[react-native.fast-image :as fast-image] [react-native.fast-image :as fast-image]
[schema.core :as schema] [schema.core :as schema]
[utils.image-server :as image-server]
utils.string)) utils.string))
(defn initials-avatar (defn initials-avatar
@ -38,23 +39,23 @@
online? true online? true
ring? true} ring? true}
:as props}] :as props}]
(let [theme (quo.theme/use-theme) (let [theme (quo.theme/use-theme)
full-name (or full-name "Your Name") picture-config (:config profile-picture)
full-name (or full-name "Your Name")
;; image generated with `profile-picture-fn` is round cropped ;; image generated with `profile-picture-fn` is round cropped
;; no need to add border-radius for them ;; 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, ;; 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 ;; But dynamic updates don't work when user-avatar is used inside hole-view
;; https://github.com/status-im/status-mobile/issues/15553 ;; https://github.com/status-im/status-mobile/issues/15553
image-view (if static? no-flicker-image/image fast-image/fast-image) image-view (if static? no-flicker-image/image fast-image/fast-image)
font-size (get-in style/sizes [size :font-size]) font-size (get-in style/sizes [size :font-size])
amount-initials (if (#{:xs :xxs :xxxs} size) 1 2) amount-initials (if (#{:xs :xxs :xxxs} size) 1 2)
sizes (get style/sizes size) sizes (get style/sizes size)
indicator-color (get (style/indicator-color theme) (if online? :online :offline)) indicator-color (get (style/indicator-color theme) (if online? :online :offline))]
profile-picture-fn (:fn profile-picture)]
[rn/view {:style outer-styles :accessibility-label :user-avatar} [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 ;; this is for things that's not user-avatar but are currently using user-avatar to render
;; the initials e.g. community avatar ;; the initials e.g. community avatar
[initials-avatar props] [initials-avatar props]
@ -62,8 +63,9 @@
{:accessibility-label :profile-picture {:accessibility-label :profile-picture
:style outer-styles :style outer-styles
:source :source
(cond profile-picture-fn (cond picture-config
{:uri (profile-picture-fn {:uri (image-server/get-image-uri
picture-config
{:length amount-initials {:length amount-initials
:full-name full-name :full-name full-name
:font-size (:font-size (text/text-style {:size :font-size (:font-size (text/text-style {:size
@ -76,7 +78,7 @@
:indicator-center-to-edge (when status-indicator? :indicator-center-to-edge (when status-indicator?
(:status-indicator-center-to-edge sizes)) (:status-indicator-center-to-edge sizes))
:indicator-color indicator-color :indicator-color indicator-color
:override-theme theme :theme theme
:color (:color style/initials-avatar-text) :color (:color style/initials-avatar-text)
:size (:width outer-styles) :size (:width outer-styles)
:ring? ring? :ring? ring?

View File

@ -3,7 +3,9 @@
[quo.foundations.colors :as colors] [quo.foundations.colors :as colors]
[schema.registry :as registry])) [schema.registry :as registry]))
(def ^:private ?profile-picture-fn-params (def ^:private ?customization-color (into [:enum :primary] colors/account-colors))
(def ^:private ?profile-picture-options
[:map [:map
[:length :int] [:length :int]
[:full-name :string] [:full-name :string]
@ -11,22 +13,67 @@
[:indicator-size {:optional true} [:maybe :int]] [:indicator-size {:optional true} [:maybe :int]]
[:indicator-color {:optional true} [:maybe :string]] [:indicator-color {:optional true} [:maybe :string]]
[:indicator-center-to-edge {:optional true} [:maybe :int]] [:indicator-center-to-edge {:optional true} [:maybe :int]]
[:override-theme :schema.common/theme] [:theme :schema.common/theme]
[:background-color :string]
[:color :string] [:color :string]
[:size :int] [:size :int]
[:ring? :boolean] [:ring? :boolean]
[:ring-width :int]]) [:ring-width :int]])
(def ^:private ?account-image-uri-options
[:map
[:port :int]
[:ratio :double]
[:key-uid :string]
[:image-name :string]
[:theme :schema.common/theme]
[:override-ring? [:maybe :boolean]]])
(def ^:private ?initials-image-uri-options
[:map
[:port :int]
[:ratio :double]
[:uppercase-ratio :double]
[:font-file :string]
[:theme :schema.common/theme]
[:customization-color ?customization-color]
[:key-uid {:optional true} [:maybe :string]]
[:public-key {:optional true} [:maybe :string]]
[:override-ring? {:optional true} [:maybe :boolean]]])
(def ^:private ?contact-image-uri-options
[:map
[:port :int]
[:clock :int]
[:ratio :double]
[:image-name :string]
[:public-key :string]
[:theme :schema.common/theme]
[:override-ring? [:maybe :boolean]]])
(def ^:private ?image-uri-config
[:multi {:dispatch :type}
[:account
[:map
[:type [:= :account]]
[:options ?account-image-uri-options]]]
[:contact
[:map
[:type [:= :contact]]
[:options ?contact-image-uri-options]]]
[:initials
[:map
[:type [:= :initials]]
[:options ?initials-image-uri-options]]]])
(def ^:private ?profile-picture-source (def ^:private ?profile-picture-source
[:or [:or
:schema.common/image-source :schema.common/image-source
[:map [:map
[:fn [:=> [:cat ?profile-picture-fn-params] :string]]]]) [:config ?image-uri-config]]])
(def ^:private ?customization-color (into [:enum] colors/account-colors))
(defn register-schemas (defn register-schemas
[] []
(registry/register ::customization-color ?customization-color)
(registry/register ::image-uri-config ?image-uri-config)
(registry/register ::profile-picture-source ?profile-picture-source) (registry/register ::profile-picture-source ?profile-picture-source)
(registry/register ::customization-color ?customization-color)) (registry/register ::profile-picture-options ?profile-picture-options))

View File

@ -11,8 +11,7 @@
[status-im.subs.chat.utils :as chat.utils] [status-im.subs.chat.utils :as chat.utils]
[utils.address :as address] [utils.address :as address]
[utils.collection] [utils.collection]
[utils.i18n :as i18n] [utils.i18n :as i18n]))
[utils.image-server :as image-server]))
(defn query-chat-contacts (defn query-chat-contacts
[{:keys [contacts]} all-contacts query-fn] [{:keys [contacts]} all-contacts query-fn]
@ -45,37 +44,40 @@
(reduce (fn [acc image] (reduce (fn [acc image]
(let [image-name (:type image) (let [image-name (:type image)
clock (:clock image) clock (:clock image)
uri (image-server/get-contact-image-uri-fn options {:port port
{:port port :ratio pixel-ratio/ratio
:ratio pixel-ratio/ratio :public-key
:public-key public-key
public-key :image-name
:image-name image-name
image-name ; We pass the clock so that we reload the
; We pass the clock so that we reload the ; image if the image is updated
; image if the image is updated :clock
:clock clock
clock :theme
:theme theme
theme :override-ring?
:override-ring? (when ens-name false)}]
(when ens-name false)})] (assoc-in acc
(assoc-in acc [(keyword image-name) :fn] uri))) [(keyword image-name) :config]
{:type :contact
:options options})))
images images
(vals images)) (vals images))
images (if (seq images) images (if (seq images)
images images
{:thumbnail {:thumbnail
{:fn (image-server/get-initials-avatar-uri-fn {:config {:type :initials
{:port port :options {:port port
:ratio pixel-ratio/ratio :ratio pixel-ratio/ratio
:public-key public-key :public-key public-key
:override-ring? (when ens-name false) :override-ring? (when ens-name false)
:uppercase-ratio (:uppercase-ratio constants/initials-avatar-font-conf) :uppercase-ratio (:uppercase-ratio
:customization-color customization-color constants/initials-avatar-font-conf)
:theme theme :customization-color customization-color
:font-file font-file})}})] :theme theme
:font-file font-file}}}})]
(assoc contact :images images))) (assoc contact :images images)))

View File

@ -10,7 +10,6 @@
[status-im.common.pixel-ratio :as pixel-ratio] [status-im.common.pixel-ratio :as pixel-ratio]
[status-im.constants :as constants] [status-im.constants :as constants]
[status-im.contexts.profile.utils :as profile.utils] [status-im.contexts.profile.utils :as profile.utils]
[utils.image-server :as image-server]
[utils.security.core :as security])) [utils.security.core :as security]))
(re-frame/reg-sub (re-frame/reg-sub
@ -43,23 +42,24 @@
image-name (-> images first :type) image-name (-> images first :type)
override-ring? (when ens-name? false)] override-ring? (when ens-name? false)]
(when profile (when profile
{:fn {:config
(if image-name (if image-name
(image-server/get-account-image-uri-fn {:port port {:type :account
:ratio pixel-ratio/ratio :options {:port port
:image-name image-name :ratio pixel-ratio/ratio
:key-uid target-key-uid :image-name image-name
:theme theme :key-uid target-key-uid
:override-ring? override-ring?}) :theme theme
(image-server/get-initials-avatar-uri-fn :override-ring? override-ring?}}
{:port port {:type :initials
:ratio pixel-ratio/ratio :options {:port port
:key-uid target-key-uid :ratio pixel-ratio/ratio
:theme theme :key-uid target-key-uid
:uppercase-ratio (:uppercase-ratio constants/initials-avatar-font-conf) :theme theme
:customization-color customization-color :uppercase-ratio (:uppercase-ratio constants/initials-avatar-font-conf)
:override-ring? override-ring? :customization-color customization-color
:font-file font-file}))})))) :override-ring? override-ring?
:font-file font-file}})}))))
;; DEPRECATED ;; DEPRECATED
;; use `:profile/public-key` instead ;; use `:profile/public-key` instead
@ -244,29 +244,31 @@
ens-name? (or ens-name? (seq ens-names)) ens-name? (or ens-name? (seq ens-names))
avatar-opts (assoc avatar-opts :override-ring? (when ens-name? false)) avatar-opts (assoc avatar-opts :override-ring? (when ens-name? false))
images-with-uri (mapv (fn [{key-uid :keyUid image-name :type :as image}] images-with-uri (mapv (fn [{key-uid :keyUid image-name :type :as image}]
(let [uri-fn (image-server/get-account-image-uri-fn (assoc image
(merge :config
{:port port {:type :account
:ratio pixel-ratio/ratio :options (merge
:image-name image-name {:port port
:key-uid key-uid :ratio pixel-ratio/ratio
:theme theme} :image-name image-name
avatar-opts))] :key-uid key-uid
(assoc image :fn uri-fn))) :theme theme}
avatar-opts)}))
images) images)
new-images (if (seq images-with-uri) new-images (if (seq images-with-uri)
images-with-uri images-with-uri
[{:fn (image-server/get-initials-avatar-uri-fn [{:config {:type :initials
(merge {:port port :options (merge
:ratio pixel-ratio/ratio {:port port
:uppercase-ratio :ratio pixel-ratio/ratio
(:uppercase-ratio :uppercase-ratio
constants/initials-avatar-font-conf) (:uppercase-ratio
:key-uid key-uid constants/initials-avatar-font-conf)
:customization-color customization-color :key-uid key-uid
:theme theme :customization-color customization-color
:font-file font-file} :theme theme
avatar-opts))}])] :font-file font-file}
avatar-opts)}}])]
(assoc profile :images new-images))) (assoc profile :images new-images)))
(re-frame/reg-sub (re-frame/reg-sub

View File

@ -4,6 +4,7 @@
[react-native.fs :as utils.fs] [react-native.fs :as utils.fs]
[react-native.platform :as platform] [react-native.platform :as platform]
[schema.core :as schema] [schema.core :as schema]
[schema.quo]
[utils.datetime :as datetime])) [utils.datetime :as datetime]))
(def ^:const image-server-uri-prefix "https://localhost:") (def ^:const image-server-uri-prefix "https://localhost:")
@ -54,8 +55,7 @@
4)) 4))
(defn get-account-image-uri (defn get-account-image-uri
"fn to get the avatar uri when multiaccount has custom image set "fn to get the avatar uri when multiaccount has custom image set.
not directly called, check `get-account-image-uri-fn`
color formats (for all color options): color formats (for all color options):
#RRGGBB #RRGGBB
@ -67,7 +67,8 @@
placeholder-avatar: pass image file path as `image-name` placeholder-avatar: pass image file path as `image-name`
`indicator-size` is outer indicator radius `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 [{:keys [port public-key image-name key-uid size theme indicator-size
indicator-border indicator-center-to-edge indicator-color ring? indicator-border indicator-center-to-edge indicator-color ring?
ring-width ratio]}] ring-width ratio]}]
@ -100,38 +101,8 @@
"&ringWidth=" "&ringWidth="
(* ring-width ratio))) (* 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 (defn get-initials-avatar-uri
"fn to get the avatar uri when account/contact/placeholder has no custom pic set "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 multiaccount: at least one of `key-uid`, `public-key` is required to render the ring
contact: `public-key` is required to render the ring contact: `public-key` is required to render the ring
@ -139,6 +110,7 @@
check `get-account-image-uri` for color formats check `get-account-image-uri` for color formats
check `get-font-file-ready` for `font-file` 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`" `uppercase-ratio` is the uppercase-height/line-height for `font-file`"
[{:keys [port public-key key-uid theme ring? length size customization-color [{:keys [port public-key key-uid theme ring? length size customization-color
color font-size font-file uppercase-ratio indicator-size color font-size font-file uppercase-ratio indicator-size
@ -185,56 +157,13 @@
"&ringWidth=" "&ringWidth="
(* ring-width ratio))) (* ring-width ratio)))
(schema/=> get-initials-avatar-uri (defn get-contact-image-uri
[:=> "check `get-account-image-uri` for color formats
[:cat
[:map
[:theme :schema.common/theme]
[:color string?]
[:background-color {:optional true} [:maybe string?]]
[:size number?]
[:ratio float?]
[:uppercase-ratio number?]
[:customization-color :schema.common/customization-color]
[:font-size number?]
[: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
check `get-font-file-ready` for `font-file` check `get-font-file-ready` for `font-file`
check `get-account-image-uri-fn` for `override-ring?`" `public-key` is required to render the ring
[{:keys [port public-key key-uid theme override-ring? font-file ratio `ring?` shows or hides ring for account with ens name
uppercase-ratio customization-color]}] `uppercase-ratio` is the uppercase-height/line-height for `font-file`"
(fn [{:keys [full-name length size 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
:customization-color customization-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
[{:keys [port public-key image-name clock theme indicator-size indicator-border [{:keys [port public-key image-name clock theme indicator-size indicator-border
indicator-center-to-edge indicator-color size ring? ring-width ratio]}] indicator-center-to-edge indicator-color size ring? ring-width ratio]}]
(str (str
@ -264,24 +193,6 @@
"&ringWidth=" "&ringWidth="
(* ring-width ratio))) (* 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 (defn get-qr-image-uri-for-any-url
[{:keys [url port qr-size error-level]}] [{:keys [url port qr-size error-level]}]
(let [qr-url-base64 (js/btoa url) (let [qr-url-base64 (js/btoa url)
@ -299,3 +210,24 @@
"&size=" "&size="
qr-size)] qr-size)]
media-server-url)) media-server-url))
(defn get-image-uri
[{:keys [type options]}
profile-picture-options]
((case type
: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])