UX: The Site's logo is the selected option when changing the system's user avatar. (#12861)

UX: The Site’s logo is the selected option when changing the system’s user avatar. (#12861)

If the “use_site_small_logo_as_system_avatar” setting is enabled, the site’s small logo is displayed as the selected option by the avatar-selector. Choosing a different avatar disables the setting.

diff --git a/app/assets/javascripts/discourse/app/controllers/avatar-selector.js b/app/assets/javascripts/discourse/app/controllers/avatar-selector.js
index a7d7e2c..965207f 100644
--- a/app/assets/javascripts/discourse/app/controllers/avatar-selector.js
+++ b/app/assets/javascripts/discourse/app/controllers/avatar-selector.js
@@ -11,6 +11,11 @@ export default Controller.extend(ModalFunctionality, {
   gravatarBaseUrl: setting("gravatar_base_url"),
   gravatarLoginUrl: setting("gravatar_login_url"),
 
+  @discourseComputed("selected", "uploading")
+  submitDisabled(selected, uploading) {
+    return selected === "logo" || uploading;
+  },
+
   @discourseComputed(
     "siteSettings.selectable_avatars_enabled",
     "siteSettings.selectable_avatars"
@@ -22,12 +27,20 @@ export default Controller.extend(ModalFunctionality, {
   },
 
   @discourseComputed(
+    "user.use_logo_small_as_avatar",
     "user.avatar_template",
     "user.system_avatar_template",
     "user.gravatar_avatar_template"
   )
-  selected(avatarTemplate, systemAvatarTemplate, gravatarAvatarTemplate) {
-    if (avatarTemplate === systemAvatarTemplate) {
+  selected(
+    useLogo,
+    avatarTemplate,
+    systemAvatarTemplate,
+    gravatarAvatarTemplate
+  ) {
+    if (useLogo) {
+      return "logo";
+    } else if (avatarTemplate === systemAvatarTemplate) {
       return "system";
     } else if (avatarTemplate === gravatarAvatarTemplate) {
       return "gravatar";
diff --git a/app/assets/javascripts/discourse/app/templates/modal/avatar-selector.hbs b/app/assets/javascripts/discourse/app/templates/modal/avatar-selector.hbs
index bb86ad9..fe52ecf 100644
--- a/app/assets/javascripts/discourse/app/templates/modal/avatar-selector.hbs
+++ b/app/assets/javascripts/discourse/app/templates/modal/avatar-selector.hbs
@@ -8,6 +8,12 @@
       {{/each}}
     </div>
   {{else}}
+    {{#if user.use_logo_small_as_avatar}}
+      <div class="avatar-choice">
+        {{radio-button id="logo-small" name="logo" value="logo" selection=selected}}
+        <label class="radio" for="logo-small">{{bound-avatar-template siteSettings.site_logo_small_url "large"}} {{html-safe (i18n "user.change_avatar.logo_small")}}</label>
+      </div>
+    {{/if}}
     <div class="avatar-choice">
       {{radio-button id="system-avatar" name="avatar" value="system" selection=selected}}
       <label class="radio" for="system-avatar">{{bound-avatar-template user.system_avatar_template "large"}} {{html-safe (i18n "user.change_avatar.letter_based")}}</label>
@@ -28,7 +34,7 @@
         {{/if}}
       </div>
       <div class="avatar-choice">
-        {{radio-button id="uploaded-avatar" name="avatar" value="uploaded" selection=selected}}
+        {{radio-button id="uploaded-avatar" name="avatar" value="custom" selection=selected}}
         <label class="radio" for="uploaded-avatar">
           {{#if user.custom_avatar_template}}
             {{bound-avatar-template user.custom_avatar_template "large"}}
@@ -50,7 +56,7 @@
 
 {{#unless siteSettings.selectable_avatars_enabled}}
   <div class="modal-footer">
-    {{d-button action=(action "saveAvatarSelection") class="btn-primary" disabled=uploading label="save"}}
+    {{d-button action=(action "saveAvatarSelection") class="btn-primary" disabled=submitDisabled label="save"}}
     {{d-modal-cancel close=(route-action "closeModal")}}
   </div>
 {{/unless}}
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 0940a32..bb796c3 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -1129,11 +1129,9 @@ class UsersController < ApplicationController
 
     if type.blank? || type == 'system'
       upload_id = nil
+    elsif !SiteSetting.allow_uploaded_avatars
+      return render json: failed_json, status: 422
     else
-      if !SiteSetting.allow_uploaded_avatars
-        return render json: failed_json, status: 422
-      end
-
       upload_id = params[:upload_id]
       upload = Upload.find_by(id: upload_id)
 
@@ -1153,6 +1151,10 @@ class UsersController < ApplicationController
       end
     end
 
+    if user.is_system_user?
+      SiteSetting.use_site_small_logo_as_system_avatar = false
+    end
+
     user.uploaded_avatar_id = upload_id
     user.save!
     user.user_avatar.save!
@@ -1187,6 +1189,11 @@ class UsersController < ApplicationController
     end
 
     user.uploaded_avatar_id = upload.id
+
+    if user.is_system_user?
+      SiteSetting.use_site_small_logo_as_system_avatar = false
+    end
+
     user.save!
 
     avatar = user.user_avatar || user.create_user_avatar
diff --git a/app/models/user.rb b/app/models/user.rb
index e9c7af5..eb2489b 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -872,8 +872,12 @@ class User < ActiveRecord::Base
     Digest::MD5.hexdigest(username)[0...15].to_i(16) % length
   end
 
+  def is_system_user?
+    id == Discourse::SYSTEM_USER_ID
+  end
+
   def avatar_template
-    use_small_logo = id == Discourse::SYSTEM_USER_ID &&
+    use_small_logo = is_system_user? &&
       SiteSetting.logo_small && SiteSetting.use_site_small_logo_as_system_avatar
 
     if use_small_logo
diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb
index afe57d8..56d4778 100644
--- a/app/serializers/user_serializer.rb
+++ b/app/serializers/user_serializer.rb
@@ -59,7 +59,8 @@ class UserSerializer < UserCardSerializer
                      :can_change_website,
                      :user_api_keys,
                      :user_auth_tokens,
-                     :user_notification_schedule
+                     :user_notification_schedule,
+                     :use_logo_small_as_avatar
 
   untrusted_attributes :bio_raw,
                        :bio_cooked,
@@ -309,6 +310,10 @@ class UserSerializer < UserCardSerializer
     object.profile_background_upload&.url
   end
 
+  def use_logo_small_as_avatar
+    object.is_system_user? && SiteSetting.logo_small && SiteSetting.use_site_small_logo_as_system_avatar
+  end
+
   private
 
   def custom_field_keys
diff --git a/app/serializers/web_hook_user_serializer.rb b/app/serializers/web_hook_user_serializer.rb
index 32fbde0..43200e4 100644
--- a/app/serializers/web_hook_user_serializer.rb
+++ b/app/serializers/web_hook_user_serializer.rb
@@ -34,6 +34,7 @@ class WebHookUserSerializer < UserSerializer
     group_users
     user_auth_tokens
     user_auth_token_logs
+    use_logo_small_as_avatar
   }.each do |attr|
     define_method("include_#{attr}?") do
       false
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index b84d8d7..0f97c5f 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -1268,6 +1268,7 @@ en:
         uploaded_avatar_empty: "Add a custom picture"
         upload_title: "Upload your picture"
         image_is_not_a_square: "Warning: we've cropped your image; width and height were not equal."
+        logo_small: "Site's small logo. Used by default."
 
       change_profile_background:
         title: "Profile Header"
diff --git a/spec/requests/users_controller_spec.rb b/spec/requests/users_controller_spec.rb
index 31c8b07..d48cc54 100644
--- a/spec/requests/users_controller_spec.rb
+++ b/spec/requests/users_controller_spec.rb
@@ -2393,6 +2393,20 @@ describe UsersController do
         expect(user.reload.uploaded_avatar_id).to eq(nil)
       end
 
+      it 'disables the use_site_small_logo_as_system_avatar setting when picking an avatar for the system user' do
+        system_user = Discourse.system_user
+        SiteSetting.use_site_small_logo_as_system_avatar = true
+        another_upload = Fabricate(:upload, user: system_user)
+        sign_in(system_user)
+
+        put "/u/#{system_user.username}/preferences/avatar/pick.json", params: {
+          upload_id: another_upload.id, type: "uploaded"
+        }
+
+        expect(response.status).to eq(200)
+        expect(SiteSetting.use_site_small_logo_as_system_avatar).to eq(false)

[... diff too long, it was truncated ...]

GitHub sha: cdbdb049

This commit appears in #12861 which was approved by CvX. It was merged by romanrizzi.