REFACTOR: move support for user card badge images to a plugin discourse-user-card-badges
This commit is contained in:
parent
0bef734c35
commit
bd77795d7a
|
@ -9,7 +9,7 @@ import CleansUp from 'discourse/mixins/cleans-up';
|
|||
export default Ember.Component.extend(CardContentsBase, CanCheckEmails, CleansUp, {
|
||||
elementId: 'user-card',
|
||||
triggeringLinkClass: 'mention',
|
||||
classNameBindings: ['visible:show', 'showBadges', 'hasCardBadgeImage', 'user.card_background::no-bg', 'isFixed:fixed'],
|
||||
classNameBindings: ['visible:show', 'showBadges', 'user.card_background::no-bg', 'isFixed:fixed'],
|
||||
allowBackgrounds: setting('allow_profile_backgrounds'),
|
||||
showBadges: setting('enable_badges'),
|
||||
|
||||
|
@ -92,9 +92,6 @@ export default Ember.Component.extend(CardContentsBase, CanCheckEmails, CleansUp
|
|||
$this.css('background-image', bg);
|
||||
},
|
||||
|
||||
@computed('user.card_badge.image')
|
||||
hasCardBadgeImage: image => image && image.indexOf('fa-') !== 0,
|
||||
|
||||
_showCallback(username, $target) {
|
||||
const args = { stats: false };
|
||||
args.include_post_count_for = this.get('topic.id');
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
import { ajax } from 'discourse/lib/ajax';
|
||||
import BadgeSelectController from "discourse/mixins/badge-select-controller";
|
||||
|
||||
export default Ember.Controller.extend(BadgeSelectController, {
|
||||
filteredList: function() {
|
||||
return this.get('model').filter(function(b) {
|
||||
return !Ember.isEmpty(b.get('badge.image'));
|
||||
});
|
||||
}.property('model'),
|
||||
|
||||
actions: {
|
||||
save: function() {
|
||||
this.setProperties({ saved: false, saving: true });
|
||||
|
||||
ajax(this.get('user.path') + "/preferences/card-badge", {
|
||||
type: "PUT",
|
||||
data: { user_badge_id: this.get('selectedUserBadgeId') }
|
||||
}).then(() => {
|
||||
this.setProperties({
|
||||
saved: true,
|
||||
saving: false,
|
||||
"user.card_image_badge": this.get('selectedUserBadge.badge.image')
|
||||
});
|
||||
}).catch(() => {
|
||||
this.set('saving', false);
|
||||
bootbox.alert(I18n.t('generic_error'));
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
|
@ -127,7 +127,6 @@ export default function() {
|
|||
this.route('second-factor');
|
||||
this.route('about', { path: '/about-me' });
|
||||
this.route('badgeTitle', { path: '/badge_title' });
|
||||
this.route('card-badge', { path: '/card-badge' });
|
||||
});
|
||||
|
||||
this.route('userInvited', { path: '/invited', resetNamespace: true }, function() {
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
import UserBadge from 'discourse/models/user-badge';
|
||||
import RestrictedUserRoute from "discourse/routes/restricted-user";
|
||||
|
||||
export default RestrictedUserRoute.extend({
|
||||
showFooter: true,
|
||||
|
||||
model: function() {
|
||||
return UserBadge.findByUsername(this.modelFor('user').get('username'));
|
||||
},
|
||||
|
||||
renderTemplate: function() {
|
||||
return this.render({ into: 'user' });
|
||||
},
|
||||
|
||||
// A bit odd, but if we leave to /preferences we need to re-render that outlet
|
||||
deactivate: function() {
|
||||
this._super();
|
||||
this.render('preferences', { into: 'user', controller: 'preferences' });
|
||||
},
|
||||
|
||||
setupController: function(controller, model) {
|
||||
controller.set('model', model);
|
||||
controller.set('user', this.modelFor('user'));
|
||||
|
||||
model.forEach(function(userBadge) {
|
||||
if (userBadge.get('badge.image') === controller.get('user.card_image_badge')) {
|
||||
controller.set('selectedUserBadgeId', userBadge.get('id'));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
{{#if user.name}}
|
||||
<h2 class='full-name'>{{user.name}}</h2>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
{{else}}
|
||||
<h2 class='username'>{{username}}</h2>
|
||||
{{/unless}}
|
||||
|
||||
|
@ -78,6 +78,7 @@
|
|||
</li>
|
||||
{{/if}}
|
||||
</ul>
|
||||
|
||||
{{plugin-outlet
|
||||
name="user-card-additional-controls"
|
||||
args=(hash user=user close=(action "close"))
|
||||
|
@ -93,12 +94,6 @@
|
|||
{{#if user.bio_cooked}}<div class='bio'>{{text-overflow class="overflow" text=user.bio_excerpt}}</div>{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#if user.card_badge}}
|
||||
{{#link-to 'badges.show' user.card_badge class="card-badge" title=user.card_badge.name}}
|
||||
{{icon-or-image user.card_badge.image title=user.card_badge.name}}
|
||||
{{/link-to}}
|
||||
{{/if}}
|
||||
|
||||
{{#if hasLocationOrWebsite}}
|
||||
<div class="location-and-website">
|
||||
{{#if user.location}}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
<section class='user-content'>
|
||||
<form class="form-horizontal">
|
||||
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<h3>{{i18n 'user.card_badge.title'}}</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label"></label>
|
||||
<div class="controls">
|
||||
{{combo-box value=selectedUserBadgeId nameProperty="badge.name" content=selectableUserBadges}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<button class="btn btn-primary" disabled={{disableSave}} {{action "save"}}>{{savingStatus}}</button>
|
||||
{{#if saved}}{{i18n 'saved'}}{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</section>
|
|
@ -50,16 +50,6 @@
|
|||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="control-group pref-card-badge">
|
||||
<label class="control-label">{{i18n 'user.card_badge.title'}}</label>
|
||||
<div class="controls">
|
||||
{{#if model.card_image_badge}}
|
||||
{{icon-or-image model.card_image_badge}}
|
||||
{{/if}}
|
||||
{{#link-to "preferences.card-badge" class="btn btn-small pad-left no-text"}}{{d-icon "pencil"}}{{/link-to}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{plugin-outlet name="user-preferences-profile"}}
|
||||
|
||||
{{plugin-outlet name="user-custom-preferences" args=(hash model=model)}}
|
||||
|
|
|
@ -140,10 +140,6 @@ $user_card_background: $secondary;
|
|||
padding-top: 10px;
|
||||
}
|
||||
|
||||
&.has-card-badge-image .bio {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.bio {
|
||||
padding: 10px 0 0 0;
|
||||
clear: left;
|
||||
|
@ -296,17 +292,6 @@ $user_card_background: $secondary;
|
|||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.card-badge {
|
||||
img {
|
||||
max-width: 120px;
|
||||
}
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
bottom: 12px;
|
||||
font-size: $font-up-5;
|
||||
i {color: $user_card_primary;}
|
||||
}
|
||||
|
||||
.metadata .email .btn {
|
||||
padding: 2px 12px;
|
||||
}
|
||||
|
|
|
@ -48,8 +48,7 @@ class UsersController < ApplicationController
|
|||
return redirect_to path('/login') if SiteSetting.hide_user_profiles_from_public && !current_user
|
||||
|
||||
@user = fetch_user_from_params(
|
||||
{ include_inactive: current_user.try(:staff?) || (current_user && SiteSetting.show_inactive_accounts) },
|
||||
[{ user_profile: :card_image_badge }]
|
||||
include_inactive: current_user.try(:staff?) || (current_user && SiteSetting.show_inactive_accounts)
|
||||
)
|
||||
|
||||
user_serializer = UserSerializer.new(@user, scope: guardian, root: 'user')
|
||||
|
@ -90,23 +89,6 @@ class UsersController < ApplicationController
|
|||
show
|
||||
end
|
||||
|
||||
def card_badge
|
||||
end
|
||||
|
||||
def update_card_badge
|
||||
user = fetch_user_from_params
|
||||
guardian.ensure_can_edit!(user)
|
||||
|
||||
user_badge = UserBadge.find_by(id: params[:user_badge_id].to_i)
|
||||
if user_badge && user_badge.user == user && user_badge.badge.image.present?
|
||||
user.user_profile.update_column(:card_image_badge_id, user_badge.badge.id)
|
||||
else
|
||||
user.user_profile.update_column(:card_image_badge_id, nil)
|
||||
end
|
||||
|
||||
render body: nil
|
||||
end
|
||||
|
||||
def user_preferences_redirect
|
||||
redirect_to email_preferences_path(current_user.username_lower)
|
||||
end
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
class UserProfile < ActiveRecord::Base
|
||||
|
||||
# TODO: remove this after Nov 1, 2018
|
||||
self.ignored_columns = %w{card_image_badge_id}
|
||||
|
||||
belongs_to :user, inverse_of: :user_profile
|
||||
|
||||
validates :bio_raw, length: { maximum: 3000 }
|
||||
|
@ -12,7 +16,6 @@ class UserProfile < ActiveRecord::Base
|
|||
|
||||
validate :website_domain_validator, if: Proc.new { |c| c.new_record? || c.website_changed? }
|
||||
|
||||
belongs_to :card_image_badge, class_name: 'Badge'
|
||||
has_many :user_profile_views, dependent: :destroy
|
||||
|
||||
BAKED_VERSION = 1
|
||||
|
@ -126,7 +129,6 @@ end
|
|||
# bio_cooked_version :integer
|
||||
# badge_granted_title :boolean default(FALSE)
|
||||
# card_background :string(255)
|
||||
# card_image_badge_id :integer
|
||||
# views :integer default(0), not null
|
||||
#
|
||||
# Indexes
|
||||
|
|
|
@ -79,7 +79,6 @@ class UserSerializer < BasicUserSerializer
|
|||
has_many :groups, embed: :object, serializer: BasicGroupSerializer
|
||||
has_many :group_users, embed: :object, serializer: BasicGroupUserSerializer
|
||||
has_many :featured_user_badges, embed: :ids, serializer: UserBadgeSerializer, root: :user_badges
|
||||
has_one :card_badge, embed: :object, serializer: BadgeSerializer
|
||||
has_one :user_option, embed: :object, serializer: UserOptionSerializer
|
||||
|
||||
def include_user_option?
|
||||
|
@ -107,8 +106,6 @@ class UserSerializer < BasicUserSerializer
|
|||
:custom_avatar_upload_id,
|
||||
:custom_avatar_template,
|
||||
:has_title_badges,
|
||||
:card_image_badge,
|
||||
:card_image_badge_id,
|
||||
:muted_usernames,
|
||||
:mailing_list_posts_per_day,
|
||||
:can_change_bio,
|
||||
|
@ -171,10 +168,6 @@ class UserSerializer < BasicUserSerializer
|
|||
keys.length > 0 ? keys : nil
|
||||
end
|
||||
|
||||
def card_badge
|
||||
object.user_profile.card_image_badge
|
||||
end
|
||||
|
||||
def bio_raw
|
||||
object.user_profile.bio_raw
|
||||
end
|
||||
|
@ -201,22 +194,6 @@ class UserSerializer < BasicUserSerializer
|
|||
website.present?
|
||||
end
|
||||
|
||||
def card_image_badge_id
|
||||
object.user_profile.card_image_badge.try(:id)
|
||||
end
|
||||
|
||||
def include_card_image_badge_id?
|
||||
card_image_badge_id.present?
|
||||
end
|
||||
|
||||
def card_image_badge
|
||||
object.user_profile.card_image_badge.try(:image)
|
||||
end
|
||||
|
||||
def include_card_image_badge?
|
||||
card_image_badge.present?
|
||||
end
|
||||
|
||||
def profile_background
|
||||
object.user_profile.profile_background
|
||||
end
|
||||
|
|
|
@ -261,7 +261,6 @@ class UserMerger
|
|||
dismissed_banner_key = COALESCE(t.dismissed_banner_key, s.dismissed_banner_key),
|
||||
badge_granted_title = t.badge_granted_title OR s.badge_granted_title,
|
||||
card_background = COALESCE(t.card_background, s.card_background),
|
||||
card_image_badge_id = COALESCE(t.card_image_badge_id, s.card_image_badge_id),
|
||||
views = t.views + s.views
|
||||
FROM user_profiles AS s
|
||||
WHERE t.user_id = :target_user_id AND s.user_id = :source_user_id
|
||||
|
|
|
@ -834,8 +834,6 @@ en:
|
|||
created: "Joined"
|
||||
log_out: "Log Out"
|
||||
location: "Location"
|
||||
card_badge:
|
||||
title: "User Card Badge"
|
||||
|
||||
website: "Web Site"
|
||||
email_settings: "Email"
|
||||
|
|
|
@ -397,8 +397,6 @@ Discourse::Application.routes.draw do
|
|||
get "#{root_path}/:username/preferences/second-factor" => "users#preferences", constraints: { username: RouteFormat.username }
|
||||
delete "#{root_path}/:username/preferences/user_image" => "users#destroy_user_image", constraints: { username: RouteFormat.username }
|
||||
put "#{root_path}/:username/preferences/avatar/pick" => "users#pick_avatar", constraints: { username: RouteFormat.username }
|
||||
get "#{root_path}/:username/preferences/card-badge" => "users#card_badge", constraints: { username: RouteFormat.username }
|
||||
put "#{root_path}/:username/preferences/card-badge" => "users#update_card_badge", constraints: { username: RouteFormat.username }
|
||||
get "#{root_path}/:username/staff-info" => "users#staff_info", constraints: { username: RouteFormat.username }
|
||||
get "#{root_path}/:username/summary" => "users#summary", constraints: { username: RouteFormat.username }
|
||||
get "#{root_path}/:username/invited" => "users#invited", constraints: { username: RouteFormat.username }
|
||||
|
|
|
@ -26,3 +26,13 @@ Migration::TableDropper.delayed_drop(
|
|||
STDERR.puts "Dropping versions. It isn't used anymore."
|
||||
}
|
||||
)
|
||||
|
||||
Migration::ColumnDropper.drop(
|
||||
table: 'user_profiles',
|
||||
after_migration: 'DropUserCardBadgeColumns',
|
||||
columns: ['card_image_badge_id'],
|
||||
on_drop: ->() {
|
||||
STDERR.puts "Removing user_profiles column card_image_badge_id"
|
||||
},
|
||||
delay: 3600
|
||||
)
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
class DropUserCardBadgeColumns < ActiveRecord::Migration[5.1]
|
||||
def up
|
||||
# User card images have been moved to a plugin which uses the
|
||||
# user's custom fields instead of the card_image_badge_id column.
|
||||
execute "INSERT INTO user_custom_fields (user_id, name, value, created_at, updated_at)
|
||||
SELECT user_id, 'card_image_badge_id', card_image_badge_id, now(), now()
|
||||
FROM user_profiles
|
||||
WHERE card_image_badge_id IS NOT NULL
|
||||
AND user_id NOT IN (
|
||||
SELECT user_id
|
||||
FROM user_custom_fields
|
||||
WHERE name = 'card_image_badge_id'
|
||||
)"
|
||||
|
||||
# delayed drop of the user_profiles.card_image_badge_id column
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
|
@ -1687,35 +1687,6 @@ describe UsersController do
|
|||
end
|
||||
end
|
||||
|
||||
describe "badge_card" do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:badge) { Fabricate(:badge) }
|
||||
let(:user_badge) { BadgeGranter.grant(badge, user) }
|
||||
|
||||
it "sets the user's card image to the badge" do
|
||||
log_in_user user
|
||||
put :update_card_badge, params: {
|
||||
user_badge_id: user_badge.id, username: user.username
|
||||
}, format: :json
|
||||
|
||||
expect(user.user_profile.reload.card_image_badge_id).to be_blank
|
||||
badge.update_attributes image: "wat.com/wat.jpg"
|
||||
|
||||
put :update_card_badge, params: {
|
||||
user_badge_id: user_badge.id, username: user.username
|
||||
}, format: :json
|
||||
|
||||
expect(user.user_profile.reload.card_image_badge_id).to eq(badge.id)
|
||||
|
||||
# Can set to nothing
|
||||
put :update_card_badge, params: {
|
||||
username: user.username
|
||||
}, format: :json
|
||||
|
||||
expect(user.user_profile.reload.card_image_badge_id).to be_blank
|
||||
end
|
||||
end
|
||||
|
||||
describe "badge_title" do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:badge) { Fabricate(:badge) }
|
||||
|
|
Loading…
Reference in New Issue