change colors to work in uint32 and Rgba type

This commit is contained in:
2026-04-12 20:44:38 +02:00
parent 376992d2e1
commit e7f408788c
6 changed files with 53 additions and 38 deletions
+16 -8
View File
@@ -14,20 +14,28 @@ func ConvertStringUint32(s string) (uint32, error) {
return uint32(v), err return uint32(v), err
} }
func ConvertStringToRgb(str string) ([3]uint8, error) { func ConvertStringToRgba(str string) (*Rgba, error) {
parts := strings.SplitN(str, ",", 4) parts := strings.SplitN(str, ",", 5)
if len(parts) != 3 { if len(parts) != 4 {
return [3]uint8{}, fmt.Errorf("invalid rgb") return nil, fmt.Errorf("invalid rgba")
} }
var rgb [3]uint8 rgba := &Rgba{}
for i, p := range parts { for i, p := range parts {
n, err := strconv.ParseUint(strings.TrimSpace(p), 10, 8) n, err := strconv.ParseUint(strings.TrimSpace(p), 10, 8)
if err != nil { if err != nil {
return [3]uint8{}, fmt.Errorf("invalid component %d: %w", i, err) return nil, fmt.Errorf("invalid component %d: %w", i, err)
} }
rgb[i] = uint8(n) rgba[i] = uint8(n)
} }
return rgb, nil return rgba, nil
}
func RgbaToUint32(r *Rgba) uint32 {
return uint32(r[0])<<24 | uint32(r[1])<<16 | uint32(r[2])<<8 | uint32(r[3])
}
func Uint32ToRgba(v uint32) *Rgba {
return &Rgba{uint8(v >> 24), uint8(v >> 16), uint8(v >> 8), uint8(v)}
} }
func ConvertStringUuid(str string) (uuid.UUID, error) { func ConvertStringUuid(str string) (uuid.UUID, error) {
+19 -14
View File
@@ -29,10 +29,8 @@ func DbInit(ctx context.Context) {
name TEXT UNIQUE NOT NULL, name TEXT UNIQUE NOT NULL,
pass_hash TEXT NOT NULL, pass_hash TEXT NOT NULL,
pronouns TEXT DEFAULT NULL, pronouns TEXT DEFAULT NULL,
color_red SMALLINT DEFAULT NULL, rgba BIGINT NOT NULL DEFAULT 0 CHECK (rgba BETWEEN 0 AND 4294967295),
color_green SMALLINT DEFAULT NULL, created_at TIMESTAMP NOT NULL DEFAULT NOW()
color_blue SMALLINT DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
) )
`) `)
if err != nil { if err != nil {
@@ -69,10 +67,10 @@ func DbInit(ctx context.Context) {
func DbUserSave(ctx context.Context, user *User) error { func DbUserSave(ctx context.Context, user *User) error {
err := dbConn.QueryRow(ctx, ` err := dbConn.QueryRow(ctx, `
INSERT INTO users (name, pass_hash, pronouns, color_red, color_green, color_blue, created_at) INSERT INTO users (name, pass_hash, pronouns, rgba, created_at)
VALUES ($1, $2, $3, $4, $5, $6, $7) VALUES ($1, $2, $3, $4, $5)
RETURNING id RETURNING id
`, user.Name, user.PasswordHash, user.Pronouns, user.Color[0], user.Color[1], user.Color[2], user.CreatedAt). `, user.Name, user.PasswordHash, user.Pronouns, RgbaToUint32(user.Color), user.CreatedAt).
Scan(&user.Id) Scan(&user.Id)
return err return err
} }
@@ -85,23 +83,31 @@ func DbUserDelete(ctx context.Context, id uuid.UUID) error {
} }
func DbUserGetStandardInfoByName(ctx context.Context, user *User) error { func DbUserGetStandardInfoByName(ctx context.Context, user *User) error {
var rgba int64
err := dbConn.QueryRow(ctx, ` err := dbConn.QueryRow(ctx, `
SELECT id, name, pass_hash, COALESCE(pronouns, ''), color_red, color_green, color_blue, created_at FROM users WHERE name = $1 SELECT id, name, pass_hash, COALESCE(pronouns, ''), rgba, created_at FROM users WHERE name = $1
`, user.Name).Scan(&user.Id, &user.Name, &user.PasswordHash, &user.Pronouns, &user.Color[0], &user.Color[1], &user.Color[2], &user.CreatedAt) `, user.Name).Scan(&user.Id, &user.Name, &user.PasswordHash, &user.Pronouns, &rgba, &user.CreatedAt)
if err == nil {
user.Color = Uint32ToRgba(uint32(rgba))
}
return err return err
} }
func DbUserGetById(ctx context.Context, user *User) error { func DbUserGetById(ctx context.Context, user *User) error {
var rgba int64
err := dbConn.QueryRow(ctx, ` err := dbConn.QueryRow(ctx, `
SELECT name, pass_hash, COALESCE(pronouns, ''), color_red, color_green, color_blue, created_at FROM users WHERE id = $1 SELECT name, pass_hash, COALESCE(pronouns, ''), rgba, created_at FROM users WHERE id = $1
`, user.Id).Scan(&user.Name, &user.PasswordHash, &user.Pronouns, &user.Color[0], &user.Color[1], &user.Color[2], &user.CreatedAt) `, user.Id).Scan(&user.Name, &user.PasswordHash, &user.Pronouns, &rgba, &user.CreatedAt)
if err == nil {
user.Color = Uint32ToRgba(uint32(rgba))
}
return err return err
} }
func DbUserSetColor(ctx context.Context, user *User) error { func DbUserSetColor(ctx context.Context, user *User) error {
_, err := dbConn.Exec(ctx, ` _, err := dbConn.Exec(ctx, `
UPDATE users SET color_red = $1, color_green = $2, color_blue = $3 WHERE id = $4 UPDATE users SET rgba = $1 WHERE id = $2
`, user.Color[0], user.Color[1], user.Color[2], user.Id) `, RgbaToUint32(user.Color), user.Id)
return err return err
} }
@@ -211,4 +217,3 @@ func DbConnectionGetMessagesBefore(ctx context.Context, before time.Time, connec
} }
return messages, rows.Err() return messages, rows.Err()
} }
+1 -2
View File
@@ -1,6 +1,5 @@
package main package main
const ( const (
MaxDirectMsgCache uint32 = 12 MaxDirectMsgCache uint32 = 12
MessagesPartitions uint8 = 2
) )
+2 -8
View File
@@ -84,12 +84,6 @@ func HttpHandleUserNew(response http.ResponseWriter, request *http.Request) {
return return
} }
color, err := ConvertStringToRgb(request.FormValue("color"))
if err != nil {
http.Error(response, "bad color", http.StatusBadRequest)
return
}
hashedPassword, err := PasswordHash(password) hashedPassword, err := PasswordHash(password)
if err != nil { if err != nil {
http.Error(response, "internal server error", http.StatusInternalServerError) http.Error(response, "internal server error", http.StatusInternalServerError)
@@ -99,7 +93,7 @@ func HttpHandleUserNew(response http.ResponseWriter, request *http.Request) {
newUser := &User{ newUser := &User{
Name: username, Name: username,
PasswordHash: hashedPassword, PasswordHash: hashedPassword,
Color: color, Color: Rgba{}.GetRandom(),
CreatedAt: time.Now(), CreatedAt: time.Now(),
} }
@@ -149,7 +143,7 @@ func HttpHandleUserModifyAppearance(response http.ResponseWriter, request *http.
return return
} }
color, err := ConvertStringToRgb(request.FormValue("color")) color, err := ConvertStringToRgba(request.FormValue("color"))
if err != nil { if err != nil {
http.Error(response, "invalid color", http.StatusBadRequest) http.Error(response, "invalid color", http.StatusBadRequest)
return return
+4 -5
View File
@@ -1,7 +1,6 @@
add hubs
media support
fix color saving to use INT (002255255035) rgba fix color saving to use INT (002255255035) rgba
media support
more user customization (avatar, banners, desc) more user customization (avatar, banners, desc)
add hubs
+11 -1
View File
@@ -1,6 +1,7 @@
package main package main
import ( import (
"math/rand/v2"
"sync" "sync"
"time" "time"
@@ -11,6 +12,15 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
) )
type Rgba [4]uint8
func (r Rgba) GetRandom() *Rgba {
for i := range r {
r[i] = uint8(rand.IntN(256))
}
return &r
}
type User struct { type User struct {
Mu sync.RWMutex Mu sync.RWMutex
Name string Name string
@@ -20,7 +30,7 @@ type User struct {
WsConn *websocket.Conn WsConn *websocket.Conn
Id uuid.UUID Id uuid.UUID
Connections map[uuid.UUID]*Connection Connections map[uuid.UUID]*Connection
Color [3]uint8 Color *Rgba
} }
type Connection struct { type Connection struct {