feat: enable passing ring width from mobile (#3903)
This commit is contained in:
parent
71800a19f1
commit
b168018eaf
|
@ -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])
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in New Issue