0.2.64 update

This commit is contained in:
ponzischeme89
2026-08-15 09:23:26 +12:00
parent a2ca7e8061
commit d5d47473a2
90 changed files with 9188 additions and 451 deletions
+41 -2
View File
@@ -43,7 +43,8 @@ type adminMembyAccount struct {
// of it. Saved is false for someone who has never synced — the values shown are then
// the defaults, and saying so is the difference between "chose this" and "has not
// chosen anything".
Settings adminAccountSettings `json:"settings"`
Settings adminAccountSettings `json:"settings"`
Notifications store.NotificationPreferences `json:"notifications"`
// Themes is the ids this person may choose between, and an empty array means every
// selectable theme rather than none — the same permissive reading the store and
// themeAllowed take. The console renders that as every box ticked, which is what an
@@ -100,6 +101,12 @@ func (s *Server) handleAdminAccounts(w http.ResponseWriter, r *http.Request) {
themes = map[string][]string{}
}
notifications, err := s.store.AllNotificationPreferences(r.Context())
if err != nil {
s.loggerFor(r.Context()).Warn("account notification preferences read failed", "error", err)
notifications = map[string]store.NotificationPreferences{}
}
result := make([]adminMembyAccount, 0, len(accounts))
for _, account := range accounts {
pref := preferences[account.ID]
@@ -125,10 +132,15 @@ func (s *Server) handleAdminAccounts(w http.ResponseWriter, r *http.Request) {
if !stored.UpdatedAt.IsZero() {
accountSettings.UpdatedAt = stored.UpdatedAt
}
notificationPrefs, savedNotifications := notifications[account.ID]
if !savedNotifications {
notificationPrefs = store.DefaultNotificationPreferences()
}
result = append(result, adminMembyAccount{
ID: account.ID, Username: account.Username, CreatedAt: account.CreatedAt,
LastSeen: account.LastSeen, Devices: account.Devices, Settings: accountSettings,
Themes: nonNilStrings(themes[account.ID]),
Themes: nonNilStrings(themes[account.ID]),
Notifications: notificationPrefs,
Recommendations: adminOnboardingPreferences{
Completed: pref.Completed, Prompted: pref.Prompted,
Updated: len(account.RecommendationPreferences) > 2,
@@ -153,6 +165,33 @@ func (s *Server) handleAdminAccounts(w http.ResponseWriter, r *http.Request) {
})
}
// handleAdminNotificationPreferences changes what one person is told without requiring
// a television or an app release. The loaded value is decoded in place so a console from
// an older gateway generation cannot accidentally turn off fields it does not know.
func (s *Server) handleAdminNotificationPreferences(w http.ResponseWriter, r *http.Request) {
userID := strings.TrimSpace(r.PathValue("userID"))
if userID == "" {
writeError(w, http.StatusBadRequest, "user is required")
return
}
prefs, err := s.notificationPreferencesFor(r.Context(), userID)
if err != nil {
writeError(w, http.StatusInternalServerError, "could not load notification settings")
return
}
if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, 8<<10)).Decode(&prefs); err != nil {
writeError(w, http.StatusBadRequest, "malformed request body")
return
}
if err := s.saveNotificationPreferences(r.Context(), userID, prefs); err != nil {
s.loggerFor(r.Context()).Error("admin notification preferences save failed", "user", userID, "error", err)
writeError(w, http.StatusInternalServerError, "could not save notification settings")
return
}
s.loggerFor(r.Context()).Info("notification settings saved for viewer", "user", userID)
writeJSON(w, http.StatusOK, prefs)
}
func (s *Server) handleAdminPromptRecommendations(w http.ResponseWriter, r *http.Request) {
userID := strings.TrimSpace(r.PathValue("userID"))
if userID == "" {