Browse Source

Bot nameplates (#7391)

* Store actor type in database

* Add bot nameplate to web UI, add setting to preferences, API, AP
Fix #7365

* Fix code style issues
master
Eugen Rochko 6 years ago
committed by GitHub
parent
commit
42cd363542
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 48 additions and 6 deletions
  1. +1
    -1
      app/controllers/api/v1/accounts/credentials_controller.rb
  2. +1
    -1
      app/controllers/settings/profiles_controller.rb
  3. +4
    -0
      app/javascript/mastodon/features/account/components/header.js
  4. +6
    -0
      app/javascript/styles/mastodon/components.scss
  5. +4
    -0
      app/javascript/styles/mastodon/forms.scss
  6. +11
    -0
      app/models/account.rb
  7. +1
    -1
      app/serializers/activitypub/actor_serializer.rb
  8. +1
    -1
      app/serializers/rest/account_serializer.rb
  9. +1
    -0
      app/services/activitypub/process_account_service.rb
  10. +5
    -1
      app/views/accounts/_header.html.haml
  11. +3
    -0
      app/views/settings/profiles/show.html.haml
  12. +1
    -0
      config/locales/en.yml
  13. +2
    -0
      config/locales/simple_form.en.yml
  14. +5
    -0
      db/migrate/20180506221944_add_actor_type_to_accounts.rb
  15. +2
    -1
      db/schema.rb

+ 1
- 1
app/controllers/api/v1/accounts/credentials_controller.rb View File

@@ -21,7 +21,7 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController
private private


def account_params def account_params
params.permit(:display_name, :note, :avatar, :header, :locked, fields_attributes: [:name, :value])
params.permit(:display_name, :note, :avatar, :header, :locked, :bot, fields_attributes: [:name, :value])
end end


def user_settings_params def user_settings_params


+ 1
- 1
app/controllers/settings/profiles_controller.rb View File

@@ -27,7 +27,7 @@ class Settings::ProfilesController < ApplicationController
private private


def account_params def account_params
params.require(:account).permit(:display_name, :note, :avatar, :header, :locked, fields_attributes: [:name, :value])
params.require(:account).permit(:display_name, :note, :avatar, :header, :locked, :bot, fields_attributes: [:name, :value])
end end


def set_account def set_account


+ 4
- 0
app/javascript/mastodon/features/account/components/header.js View File

@@ -131,6 +131,7 @@ export default class Header extends ImmutablePureComponent {
const content = { __html: account.get('note_emojified') }; const content = { __html: account.get('note_emojified') };
const displayNameHtml = { __html: account.get('display_name_html') }; const displayNameHtml = { __html: account.get('display_name_html') };
const fields = account.get('fields'); const fields = account.get('fields');
const badge = account.get('bot') ? (<div className='roles'><div className='account-role bot'><FormattedMessage id='account.badges.bot' defaultMessage='Bot' /></div></div>) : null;


return ( return (
<div className={classNames('account__header', { inactive: !!account.get('moved') })} style={{ backgroundImage: `url(${account.get('header')})` }}> <div className={classNames('account__header', { inactive: !!account.get('moved') })} style={{ backgroundImage: `url(${account.get('header')})` }}>
@@ -139,6 +140,9 @@ export default class Header extends ImmutablePureComponent {


<span className='account__header__display-name' dangerouslySetInnerHTML={displayNameHtml} /> <span className='account__header__display-name' dangerouslySetInnerHTML={displayNameHtml} />
<span className='account__header__username'>@{account.get('acct')} {lockedIcon}</span> <span className='account__header__username'>@{account.get('acct')} {lockedIcon}</span>

{badge}

<div className='account__header__content' dangerouslySetInnerHTML={content} /> <div className='account__header__content' dangerouslySetInnerHTML={content} />


{fields.size > 0 && ( {fields.size > 0 && (


+ 6
- 0
app/javascript/styles/mastodon/components.scss View File

@@ -5159,6 +5159,12 @@ noscript {
} }
} }


.account__header .roles {
margin-top: 20px;
margin-bottom: 20px;
padding: 0 15px;
}

.account__header .account__header__fields { .account__header .account__header__fields {
font-size: 14px; font-size: 14px;
line-height: 20px; line-height: 20px;


+ 4
- 0
app/javascript/styles/mastodon/forms.scss View File

@@ -87,6 +87,10 @@ code {
align-items: flex-start; align-items: flex-start;
} }


&.file .label_input {
flex-wrap: nowrap;
}

&.select .label_input { &.select .label_input {
align-items: initial; align-items: initial;
} }


+ 11
- 0
app/models/account.rb View File

@@ -45,6 +45,7 @@
# moved_to_account_id :bigint(8) # moved_to_account_id :bigint(8)
# featured_collection_url :string # featured_collection_url :string
# fields :jsonb # fields :jsonb
# actor_type :string
# #


class Account < ApplicationRecord class Account < ApplicationRecord
@@ -149,6 +150,16 @@ class Account < ApplicationRecord
moved_to_account_id.present? moved_to_account_id.present?
end end


def bot?
%w(Application Service).include? actor_type
end

alias bot bot?

def bot=(val)
self.actor_type = ActiveModel::Type::Boolean.new.cast(val) ? 'Service' : 'Person'
end

def acct def acct
local? ? username : "#{username}@#{domain}" local? ? username : "#{username}@#{domain}"
end end


+ 1
- 1
app/serializers/activitypub/actor_serializer.rb View File

@@ -37,7 +37,7 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer
end end


def type def type
'Person'
object.bot? ? 'Service' : 'Person'
end end


def following def following


+ 1
- 1
app/serializers/rest/account_serializer.rb View File

@@ -3,7 +3,7 @@
class REST::AccountSerializer < ActiveModel::Serializer class REST::AccountSerializer < ActiveModel::Serializer
include RoutingHelper include RoutingHelper


attributes :id, :username, :acct, :display_name, :locked, :created_at,
attributes :id, :username, :acct, :display_name, :locked, :bot, :created_at,
:note, :url, :avatar, :avatar_static, :header, :header_static, :note, :url, :avatar, :avatar_static, :header, :header_static,
:followers_count, :following_count, :statuses_count :followers_count, :following_count, :statuses_count




+ 1
- 0
app/services/activitypub/process_account_service.rb View File

@@ -71,6 +71,7 @@ class ActivityPub::ProcessAccountService < BaseService
@account.note = @json['summary'] || '' @account.note = @json['summary'] || ''
@account.locked = @json['manuallyApprovesFollowers'] || false @account.locked = @json['manuallyApprovesFollowers'] || false
@account.fields = property_values || {} @account.fields = property_values || {}
@account.actor_type = @json['type']
end end


def set_fetchable_attributes! def set_fetchable_attributes!


+ 5
- 1
app/views/accounts/_header.html.haml View File

@@ -10,7 +10,11 @@
%span>< @#{account.local_username_and_domain} %span>< @#{account.local_username_and_domain}
= fa_icon('lock') if account.locked? = fa_icon('lock') if account.locked?


- if Setting.show_staff_badge
- if account.bot?
.roles
.account-role.bot
= t 'accounts.roles.bot'
- elsif Setting.show_staff_badge
- if account.user_admin? - if account.user_admin?
.roles .roles
.account-role.admin .account-role.admin


+ 3
- 0
app/views/settings/profiles/show.html.haml View File

@@ -20,6 +20,9 @@
= f.input :locked, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.locked') = f.input :locked, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.locked')


.fields-group .fields-group
= f.input :bot, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.bot')

.fields-group
.input.with_block_label .input.with_block_label
%label= t('simple_form.labels.defaults.fields') %label= t('simple_form.labels.defaults.fields')
%span.hint= t('simple_form.hints.defaults.fields') %span.hint= t('simple_form.hints.defaults.fields')


+ 1
- 0
config/locales/en.yml View File

@@ -49,6 +49,7 @@ en:
reserved_username: The username is reserved reserved_username: The username is reserved
roles: roles:
admin: Admin admin: Admin
bot: Bot
moderator: Mod moderator: Mod
unfollow: Unfollow unfollow: Unfollow
admin: admin:


+ 2
- 0
config/locales/simple_form.en.yml View File

@@ -4,6 +4,7 @@ en:
hints: hints:
defaults: defaults:
avatar: PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px avatar: PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px
bot: Warns people that the account does not represent a person
digest: Only sent after a long period of inactivity and only if you have received any personal messages in your absence digest: Only sent after a long period of inactivity and only if you have received any personal messages in your absence
display_name: display_name:
one: <span class="name-counter">1</span> character left one: <span class="name-counter">1</span> character left
@@ -29,6 +30,7 @@ en:
value: Content value: Content
defaults: defaults:
avatar: Avatar avatar: Avatar
bot: This is a bot account
confirm_new_password: Confirm new password confirm_new_password: Confirm new password
confirm_password: Confirm password confirm_password: Confirm password
current_password: Current password current_password: Current password


+ 5
- 0
db/migrate/20180506221944_add_actor_type_to_accounts.rb View File

@@ -0,0 +1,5 @@
class AddActorTypeToAccounts < ActiveRecord::Migration[5.2]
def change
add_column :accounts, :actor_type, :string
end
end

+ 2
- 1
db/schema.rb View File

@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.


ActiveRecord::Schema.define(version: 2018_04_16_210259) do
ActiveRecord::Schema.define(version: 2018_05_06_221944) do


# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@@ -75,6 +75,7 @@ ActiveRecord::Schema.define(version: 2018_04_16_210259) do
t.bigint "moved_to_account_id" t.bigint "moved_to_account_id"
t.string "featured_collection_url" t.string "featured_collection_url"
t.jsonb "fields" t.jsonb "fields"
t.string "actor_type"
t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin
t.index "lower((username)::text), lower((domain)::text)", name: "index_accounts_on_username_and_domain_lower" t.index "lower((username)::text), lower((domain)::text)", name: "index_accounts_on_username_and_domain_lower"
t.index ["uri"], name: "index_accounts_on_uri" t.index ["uri"], name: "index_accounts_on_uri"


Loading…
Cancel
Save