feat: enable passing ring width from mobile (#3903)

This commit is contained in:
yqrashawn 2023-09-01 16:17:46 +08:00 committed by GitHub
parent 71800a19f1
commit b168018eaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 71 deletions

View File

@ -42,6 +42,7 @@ type DrawRingParam struct {
ImageBytes []byte `json:"imageBytes"` ImageBytes []byte `json:"imageBytes"`
Height int `json:"height"` Height int `json:"height"`
Width int `json:"width"` Width int `json:"width"`
RingWidth float64 `json:"ringWidth"`
} }
func DrawRing(param *DrawRingParam) ([]byte, error) { func DrawRing(param *DrawRingParam) ([]byte, error) {
@ -62,8 +63,7 @@ func DrawRing(param *DrawRingParam) ([]byte, error) {
} }
dc.DrawImage(img, 0, 0) dc.DrawImage(img, 0, 0)
ringPxSize := math.Max(2.0, float64(param.Width/16.0)) radius := (float64(param.Height) - param.RingWidth) / 2
radius := (float64(param.Height) - ringPxSize) / 2
arcPos := 0.0 arcPos := 0.0
totalRingUnits := 0 totalRingUnits := 0
@ -75,7 +75,7 @@ func DrawRing(param *DrawRingParam) ([]byte, error) {
for i := 0; i < len(param.ColorHash); i++ { for i := 0; i < len(param.ColorHash); i++ {
dc.SetHexColor(colors[param.ColorHash[i][1]]) dc.SetHexColor(colors[param.ColorHash[i][1]])
dc.DrawArc(float64(param.Width/2), float64(param.Height/2), radius, arcPos, arcPos+unitRadLen*float64(param.ColorHash[i][0])) dc.DrawArc(float64(param.Width/2), float64(param.Height/2), radius, arcPos, arcPos+unitRadLen*float64(param.ColorHash[i][0]))
dc.SetLineWidth(ringPxSize) dc.SetLineWidth(param.RingWidth)
dc.SetLineCapButt() dc.SetLineCapButt()
dc.Stroke() dc.Stroke()
arcPos += unitRadLen * float64(param.ColorHash[i][0]) arcPos += unitRadLen * float64(param.ColorHash[i][0])

View File

@ -21,14 +21,12 @@ import (
"github.com/status-im/status-go/ipfs" "github.com/status-im/status-go/ipfs"
"github.com/status-im/status-go/multiaccounts" "github.com/status-im/status-go/multiaccounts"
"github.com/status-im/status-go/protocol/identity/colorhash" "github.com/status-im/status-go/protocol/identity/colorhash"
"github.com/status-im/status-go/protocol/identity/identicon"
"github.com/status-im/status-go/protocol/identity/ring" "github.com/status-im/status-go/protocol/identity/ring"
"github.com/status-im/status-go/protocol/protobuf" "github.com/status-im/status-go/protocol/protobuf"
) )
const ( const (
basePath = "/messages" basePath = "/messages"
identiconsPath = basePath + "/identicons"
imagesPath = basePath + "/images" imagesPath = basePath + "/images"
audioPath = basePath + "/audio" audioPath = basePath + "/audio"
ipfsPath = "/ipfs" ipfsPath = "/ipfs"
@ -72,6 +70,7 @@ type ImageParams struct {
UppercaseRatio float64 UppercaseRatio float64
Theme ring.Theme Theme ring.Theme
Ring bool Ring bool
RingWidth float64
IndicatorSize float64 IndicatorSize float64
IndicatorBorder float64 IndicatorBorder float64
IndicatorColor color.Color IndicatorColor color.Color
@ -228,6 +227,16 @@ func ParseImageParams(logger *zap.Logger, params url.Values) ImageParams {
parsed.IndicatorBorder = indicatorBorder parsed.IndicatorBorder = indicatorBorder
} }
ringWidthStrs := params["ringWidth"]
if len(ringWidthStrs) != 0 {
ringWidth, err := strconv.ParseFloat(ringWidthStrs[0], 64)
if err != nil {
logger.Error("ParseParams: invalid indicatorSize", zap.String("ringWidth", ringWidthStrs[0]))
ringWidth = 0
}
parsed.RingWidth = ringWidth
}
parsed.Theme = getTheme(params, logger) parsed.Theme = getTheme(params, logger)
parsed.Ring = ringEnabled(params) parsed.Ring = ringEnabled(params)
@ -278,6 +287,12 @@ func handleAccountImagesImpl(multiaccountsDB *multiaccounts.Database, logger *za
logger.Error("handleAccountImagesImpl: failed to load image.", zap.String("keyUid", parsed.KeyUID), zap.String("imageName", parsed.ImageName), zap.Error(err)) logger.Error("handleAccountImagesImpl: failed to load image.", zap.String("keyUid", parsed.KeyUID), zap.String("imageName", parsed.ImageName), zap.Error(err))
return return
} }
if parsed.Ring && parsed.RingWidth == 0 {
logger.Error("handleAccountImagesImpl: no ringWidth.")
return
}
if parsed.BgSize == 0 { if parsed.BgSize == 0 {
parsed.BgSize = identityImage.Width parsed.BgSize = identityImage.Width
} }
@ -288,6 +303,8 @@ func handleAccountImagesImpl(multiaccountsDB *multiaccounts.Database, logger *za
return return
} }
enlargeRatio := float64(identityImage.Width) / float64(parsed.BgSize)
if parsed.Ring { if parsed.Ring {
account, err := multiaccountsDB.GetAccount(parsed.KeyUID) account, err := multiaccountsDB.GetAccount(parsed.KeyUID)
if err != nil { if err != nil {
@ -311,7 +328,7 @@ func handleAccountImagesImpl(multiaccountsDB *multiaccounts.Database, logger *za
} }
payload, err = ring.DrawRing(&ring.DrawRingParam{ payload, err = ring.DrawRing(&ring.DrawRingParam{
Theme: parsed.Theme, ColorHash: accColorHash, ImageBytes: payload, Height: identityImage.Height, Width: identityImage.Width, Theme: parsed.Theme, ColorHash: accColorHash, ImageBytes: payload, Height: identityImage.Height, Width: identityImage.Width, RingWidth: parsed.RingWidth * enlargeRatio,
}) })
if err != nil { if err != nil {
logger.Error("handleAccountImagesImpl: failed to draw ring for account identity", zap.Error(err)) logger.Error("handleAccountImagesImpl: failed to draw ring for account identity", zap.Error(err))
@ -322,8 +339,7 @@ func handleAccountImagesImpl(multiaccountsDB *multiaccounts.Database, logger *za
if parsed.IndicatorSize != 0 { if parsed.IndicatorSize != 0 {
// enlarge indicator size based on identity image size / desired size // enlarge indicator size based on identity image size / desired size
// or we get a bad quality identity image // or we get a bad quality identity image
enlargeIndicatorRatio := float64(identityImage.Width / parsed.BgSize) payload, err = images.AddStatusIndicatorToImage(payload, parsed.IndicatorColor, parsed.IndicatorSize*enlargeRatio, parsed.IndicatorBorder*enlargeRatio)
payload, err = images.AddStatusIndicatorToImage(payload, parsed.IndicatorColor, parsed.IndicatorSize*enlargeIndicatorRatio, parsed.IndicatorBorder*enlargeIndicatorRatio)
if err != nil { if err != nil {
logger.Error("handleAccountImagesImpl: failed to draw status-indicator for initials", zap.Error(err)) logger.Error("handleAccountImagesImpl: failed to draw status-indicator for initials", zap.Error(err))
return return
@ -418,6 +434,11 @@ func handleAccountInitialsImpl(multiaccountsDB *multiaccounts.Database, logger *
var accColorHash multiaccounts.ColorHash var accColorHash multiaccounts.ColorHash
var account *multiaccounts.Account var account *multiaccounts.Account
if parsed.Ring && parsed.RingWidth == 0 {
logger.Error("handleAccountInitialsImpl: no ringWidth.")
return
}
if parsed.KeyUID != "" { if parsed.KeyUID != "" {
account, err := multiaccountsDB.GetAccount(parsed.KeyUID) account, err := multiaccountsDB.GetAccount(parsed.KeyUID)
@ -453,7 +474,7 @@ func handleAccountInitialsImpl(multiaccountsDB *multiaccounts.Database, logger *
} }
payload, err = ring.DrawRing(&ring.DrawRingParam{ payload, err = ring.DrawRing(&ring.DrawRingParam{
Theme: parsed.Theme, ColorHash: accColorHash, ImageBytes: payload, Height: parsed.BgSize, Width: parsed.BgSize, Theme: parsed.Theme, ColorHash: accColorHash, ImageBytes: payload, Height: parsed.BgSize, Width: parsed.BgSize, RingWidth: parsed.RingWidth,
}) })
if err != nil { if err != nil {
@ -584,6 +605,11 @@ func handleContactImages(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
return return
} }
if parsed.Ring && parsed.RingWidth == 0 {
logger.Error("handleAccountImagesImpl: no ringWidth.")
return
}
var payload []byte var payload []byte
err := db.QueryRow(`SELECT payload FROM chat_identity_contacts WHERE contact_id = ? and image_type = ?`, parsed.PublicKey, parsed.ImageName).Scan(&payload) err := db.QueryRow(`SELECT payload FROM chat_identity_contacts WHERE contact_id = ? and image_type = ?`, parsed.PublicKey, parsed.ImageName).Scan(&payload)
if err != nil { if err != nil {
@ -608,6 +634,8 @@ func handleContactImages(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
return return
} }
enlargeRatio := float64(width) / float64(parsed.BgSize)
if parsed.Ring { if parsed.Ring {
colorHash, err := colorhash.GenerateFor(parsed.PublicKey) colorHash, err := colorhash.GenerateFor(parsed.PublicKey)
if err != nil { if err != nil {
@ -616,7 +644,7 @@ func handleContactImages(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
} }
payload, err = ring.DrawRing(&ring.DrawRingParam{ payload, err = ring.DrawRing(&ring.DrawRingParam{
Theme: parsed.Theme, ColorHash: colorHash, ImageBytes: payload, Height: width, Width: width, Theme: parsed.Theme, ColorHash: colorHash, ImageBytes: payload, Height: width, Width: width, RingWidth: parsed.RingWidth * enlargeRatio,
}) })
if err != nil { if err != nil {
@ -626,8 +654,7 @@ func handleContactImages(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
} }
if parsed.IndicatorSize != 0 { if parsed.IndicatorSize != 0 {
enlargeIndicatorRatio := float64(width / parsed.BgSize) payload, err = images.AddStatusIndicatorToImage(payload, parsed.IndicatorColor, parsed.IndicatorSize*enlargeRatio, parsed.IndicatorBorder*enlargeRatio)
payload, err = images.AddStatusIndicatorToImage(payload, parsed.IndicatorColor, parsed.IndicatorSize*enlargeIndicatorRatio, parsed.IndicatorBorder*enlargeIndicatorRatio)
if err != nil { if err != nil {
logger.Error("handleAccountImagesImpl: failed to draw status-indicator for initials", zap.Error(err)) logger.Error("handleAccountImagesImpl: failed to draw status-indicator for initials", zap.Error(err))
return return
@ -672,47 +699,6 @@ func getTheme(params url.Values, logger *zap.Logger) ring.Theme {
return theme return theme
} }
func handleIdenticon(logger *zap.Logger) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
params := r.URL.Query()
parsed := ParseImageParams(logger, params)
if parsed.PublicKey == "" {
logger.Error("no publicKey")
return
}
identiconImage, err := identicon.Generate(parsed.PublicKey)
if err != nil {
logger.Error("could not generate identicon")
}
if identiconImage != nil && parsed.Ring {
colorHash, err := colorhash.GenerateFor(parsed.PublicKey)
if err != nil {
logger.Error("could not generate color hash")
return
}
identiconImage, err = ring.DrawRing(&ring.DrawRingParam{
Theme: parsed.Theme, ColorHash: colorHash, ImageBytes: identiconImage, Height: identicon.Height, Width: identicon.Width,
})
if err != nil {
logger.Error("failed to draw ring", zap.Error(err))
}
}
w.Header().Set("Content-Type", "image/png")
w.Header().Set("Cache-Control", "max-age:290304000, public")
w.Header().Set("Expires", time.Now().AddDate(60, 0, 0).Format(http.TimeFormat))
_, err = w.Write(identiconImage)
if err != nil {
logger.Error("failed to write image", zap.Error(err))
}
}
}
func handleDiscordAuthorAvatar(db *sql.DB, logger *zap.Logger) http.HandlerFunc { func handleDiscordAuthorAvatar(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
if db == nil { if db == nil {
return handleRequestDBMissing(logger) return handleRequestDBMissing(logger)

View File

@ -44,7 +44,6 @@ func NewMediaServer(db *sql.DB, downloader *ipfs.Downloader, multiaccountsDB *mu
discordAttachmentsPath: handleDiscordAttachment(s.db, s.logger), discordAttachmentsPath: handleDiscordAttachment(s.db, s.logger),
discordAuthorsPath: handleDiscordAuthorAvatar(s.db, s.logger), discordAuthorsPath: handleDiscordAuthorAvatar(s.db, s.logger),
generateQRCode: handleQRCodeGeneration(s.multiaccountsDB, s.logger), generateQRCode: handleQRCodeGeneration(s.multiaccountsDB, s.logger),
identiconsPath: handleIdenticon(s.logger),
imagesPath: handleImage(s.db, s.logger), imagesPath: handleImage(s.db, s.logger),
ipfsPath: handleIPFS(s.downloader, s.logger), ipfsPath: handleIPFS(s.downloader, s.logger),
LinkPreviewThumbnailPath: handleLinkPreviewThumbnail(s.db, s.logger), LinkPreviewThumbnailPath: handleLinkPreviewThumbnail(s.db, s.logger),
@ -59,14 +58,6 @@ func (s *MediaServer) MakeImageServerURL() string {
return u.String() return u.String()
} }
func (s *MediaServer) MakeIdenticonURL(from string) string {
u := s.MakeBaseURL()
u.Path = identiconsPath
u.RawQuery = url.Values{"publicKey": {from}}.Encode()
return u.String()
}
func (s *MediaServer) MakeImageURL(id string) string { func (s *MediaServer) MakeImageURL(id string) string {
u := s.MakeBaseURL() u := s.MakeBaseURL()
u.Path = imagesPath u.Path = imagesPath

View File

@ -96,15 +96,6 @@ func (s *ServerURLSuite) TestServer_MakeImageServerURL() {
s.testNoPort(baseURLWithDefaultPort+"/messages/", s.serverNoPort.MakeImageServerURL()) s.testNoPort(baseURLWithDefaultPort+"/messages/", s.serverNoPort.MakeImageServerURL())
} }
func (s *ServerURLSuite) TestServer_MakeIdenticonURL() {
s.Require().Equal(
baseURLWithCustomPort+"/messages/identicons?publicKey=0xdaff0d11decade",
s.server.MakeIdenticonURL("0xdaff0d11decade"))
s.testNoPort(
baseURLWithDefaultPort+"/messages/identicons?publicKey=0xdaff0d11decade",
s.serverNoPort.MakeIdenticonURL("0xdaff0d11decade"))
}
func (s *ServerURLSuite) TestServer_MakeImageURL() { func (s *ServerURLSuite) TestServer_MakeImageURL() {
s.Require().Equal( s.Require().Equal(
baseURLWithCustomPort+"/messages/images?messageId=0x10aded70ffee", baseURLWithCustomPort+"/messages/images?messageId=0x10aded70ffee",