feat: realtime status, mentions, push notifications
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"git.dustin.coffee/hobokenchicken/dumpsterChat/internal/config"
|
||||
"git.dustin.coffee/hobokenchicken/dumpsterChat/internal/gateway"
|
||||
"git.dustin.coffee/hobokenchicken/dumpsterChat/internal/middleware"
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
@@ -19,13 +20,15 @@ type Handler struct {
|
||||
db *sql.DB
|
||||
cfg *config.Config
|
||||
sessions *SessionStore
|
||||
hub *gateway.Hub
|
||||
}
|
||||
|
||||
func NewHandler(db *sql.DB, cfg *config.Config) *Handler {
|
||||
func NewHandler(db *sql.DB, cfg *config.Config, hub *gateway.Hub) *Handler {
|
||||
return &Handler{
|
||||
db: db,
|
||||
cfg: cfg,
|
||||
sessions: NewSessionStore(db, cfg),
|
||||
hub: hub,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +62,7 @@ type updateProfileRequest struct {
|
||||
Bio string `json:"bio"`
|
||||
AccentColor string `json:"accent_color"`
|
||||
StatusText string `json:"status_text"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type changePasswordRequest struct {
|
||||
@@ -279,17 +283,29 @@ func (h *Handler) UpdateProfile(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, `{"error":"accent color must be 7 char hex"}`, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if req.Status != "" && !isValidStatus(req.Status) {
|
||||
http.Error(w, `{"error":"invalid status"}`, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
_, err := h.db.ExecContext(r.Context(), `
|
||||
UPDATE users
|
||||
SET display_name = $2, bio = $3, accent_color = $4, status_text = $5
|
||||
SET display_name = $2, bio = $3, accent_color = $4, status_text = $5, status = COALESCE(NULLIF($6, ''), status)
|
||||
WHERE id = $1
|
||||
`, userID, req.DisplayName, req.Bio, req.AccentColor, req.StatusText)
|
||||
`, userID, req.DisplayName, req.Bio, req.AccentColor, req.StatusText, req.Status)
|
||||
if err != nil {
|
||||
http.Error(w, `{"error":"update failed"}`, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if req.Status != "" && h.hub != nil {
|
||||
user, err := h.getProfile(r.Context(), userID)
|
||||
if err == nil {
|
||||
h.hub.SetUserStatus(userID, req.Status)
|
||||
h.hub.BroadcastPresence(userID, user.Username, req.Status)
|
||||
}
|
||||
}
|
||||
|
||||
user, err := h.getProfile(r.Context(), userID)
|
||||
if err != nil {
|
||||
http.Error(w, `{"error":"not found"}`, http.StatusNotFound)
|
||||
@@ -300,6 +316,14 @@ func (h *Handler) UpdateProfile(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewEncoder(w).Encode(user)
|
||||
}
|
||||
|
||||
func isValidStatus(status string) bool {
|
||||
switch status {
|
||||
case "online", "idle", "dnd", "offline":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *Handler) getProfile(ctx context.Context, userID string) (UserProfile, error) {
|
||||
var user UserProfile
|
||||
return user, h.db.QueryRowContext(ctx, `
|
||||
|
||||
Reference in New Issue
Block a user