143 lines
4.0 KiB
Go
143 lines
4.0 KiB
Go
package mail
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"strings"
|
|
|
|
"github.com/jackc/pgx/v5"
|
|
)
|
|
|
|
func (s *Service) GetMailSettings(ctx context.Context, externalID string) (MailSettings, error) {
|
|
defaults := defaultMailSettings()
|
|
|
|
var density, themeMode, backgroundID, inboxSort, readingPane *string
|
|
var conversationMode *bool
|
|
var notificationsJSON []byte
|
|
var updatedAt any
|
|
|
|
err := s.db.QueryRow(ctx, `
|
|
SELECT
|
|
s.preferences->'mail'->>'density',
|
|
s.preferences->'mail'->>'theme_mode',
|
|
s.preferences->'mail'->>'background_id',
|
|
s.preferences->'mail'->>'inbox_sort',
|
|
s.preferences->'mail'->>'reading_pane',
|
|
(s.preferences->'mail'->>'conversation_mode')::boolean,
|
|
s.preferences->'mail'->'notifications',
|
|
s.updated_at
|
|
FROM users u
|
|
LEFT JOIN settings s ON s.user_id = u.id
|
|
WHERE u.external_id = $1
|
|
`, externalID).Scan(&density, &themeMode, &backgroundID, &inboxSort, &readingPane, &conversationMode, ¬ificationsJSON, &updatedAt)
|
|
if err != nil {
|
|
if err == pgx.ErrNoRows {
|
|
return defaults, nil
|
|
}
|
|
return MailSettings{}, err
|
|
}
|
|
|
|
if density != nil && *density != "" {
|
|
defaults.Density = *density
|
|
}
|
|
if themeMode != nil && *themeMode != "" {
|
|
defaults.ThemeMode = *themeMode
|
|
}
|
|
if backgroundID != nil && *backgroundID != "" {
|
|
defaults.BackgroundID = *backgroundID
|
|
}
|
|
if inboxSort != nil && *inboxSort != "" {
|
|
defaults.InboxSort = *inboxSort
|
|
}
|
|
if readingPane != nil && *readingPane != "" {
|
|
defaults.ReadingPane = *readingPane
|
|
}
|
|
if conversationMode != nil {
|
|
defaults.ConversationMode = *conversationMode
|
|
}
|
|
if len(notificationsJSON) > 0 && string(notificationsJSON) != "null" {
|
|
var n MailNotificationSettings
|
|
if err := json.Unmarshal(notificationsJSON, &n); err == nil {
|
|
defaults.Notifications = n
|
|
}
|
|
}
|
|
if updatedAt != nil {
|
|
defaults.UpdatedAt = updatedAt
|
|
}
|
|
return defaults, nil
|
|
}
|
|
|
|
func (s *Service) UpdateMailSettings(ctx context.Context, externalID string, req *patchMailSettingsRequest) (MailSettings, error) {
|
|
patch := map[string]any{}
|
|
if req.Density != nil {
|
|
patch["density"] = strings.ToLower(strings.TrimSpace(*req.Density))
|
|
}
|
|
if req.ThemeMode != nil {
|
|
patch["theme_mode"] = strings.ToLower(strings.TrimSpace(*req.ThemeMode))
|
|
}
|
|
if req.BackgroundID != nil {
|
|
patch["background_id"] = strings.ToLower(strings.TrimSpace(*req.BackgroundID))
|
|
}
|
|
if req.InboxSort != nil {
|
|
patch["inbox_sort"] = strings.ToLower(strings.TrimSpace(*req.InboxSort))
|
|
}
|
|
if req.ReadingPane != nil {
|
|
patch["reading_pane"] = strings.ToLower(strings.TrimSpace(*req.ReadingPane))
|
|
}
|
|
if req.ConversationMode != nil {
|
|
patch["conversation_mode"] = *req.ConversationMode
|
|
}
|
|
if req.Notifications != nil {
|
|
current, err := s.GetMailSettings(ctx, externalID)
|
|
if err != nil {
|
|
return MailSettings{}, err
|
|
}
|
|
merged := current.Notifications
|
|
if req.Notifications.DesktopNewMail != nil {
|
|
merged.DesktopNewMail = *req.Notifications.DesktopNewMail
|
|
}
|
|
if req.Notifications.DesktopMentions != nil {
|
|
merged.DesktopMentions = *req.Notifications.DesktopMentions
|
|
}
|
|
if req.Notifications.EmailDigest != nil {
|
|
merged.EmailDigest = *req.Notifications.EmailDigest
|
|
}
|
|
if req.Notifications.SoundEnabled != nil {
|
|
merged.SoundEnabled = *req.Notifications.SoundEnabled
|
|
}
|
|
patch["notifications"] = merged
|
|
}
|
|
|
|
patchJSON, err := json.Marshal(patch)
|
|
if err != nil {
|
|
return MailSettings{}, err
|
|
}
|
|
|
|
var updatedAt any
|
|
err = s.db.QueryRow(ctx, `
|
|
INSERT INTO settings (user_id, preferences)
|
|
VALUES (
|
|
(SELECT id FROM users WHERE external_id = $1),
|
|
jsonb_build_object('mail', $2::jsonb)
|
|
)
|
|
ON CONFLICT (user_id) DO UPDATE SET
|
|
preferences = jsonb_set(
|
|
COALESCE(settings.preferences, '{}'::jsonb),
|
|
'{mail}',
|
|
COALESCE(settings.preferences->'mail', '{}'::jsonb) || $2::jsonb
|
|
),
|
|
updated_at = NOW()
|
|
RETURNING updated_at
|
|
`, externalID, patchJSON).Scan(&updatedAt)
|
|
if err != nil {
|
|
return MailSettings{}, err
|
|
}
|
|
|
|
result, err := s.GetMailSettings(ctx, externalID)
|
|
if err != nil {
|
|
return MailSettings{}, err
|
|
}
|
|
result.UpdatedAt = updatedAt
|
|
return result, nil
|
|
}
|