Implement cat feature
This commit is contained in:
parent
633d175146
commit
3151eecd5a
@ -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, :bot, :discoverable, fields_attributes: [:name, :value])
|
params.permit(:display_name, :note, :avatar, :header, :locked, :bot, :cat, :discoverable, fields_attributes: [:name, :value])
|
||||||
end
|
end
|
||||||
|
|
||||||
def user_settings_params
|
def user_settings_params
|
||||||
|
@ -20,7 +20,7 @@ class Settings::ProfilesController < Settings::BaseController
|
|||||||
private
|
private
|
||||||
|
|
||||||
def account_params
|
def account_params
|
||||||
params.require(:account).permit(:display_name, :note, :avatar, :header, :locked, :bot, :discoverable, fields_attributes: [:name, :value])
|
params.require(:account).permit(:display_name, :note, :avatar, :header, :locked, :bot, :cat, :discoverable, fields_attributes: [:name, :value])
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_account
|
def set_account
|
||||||
|
@ -24,6 +24,7 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
|
|||||||
voters_count: { 'toot' => 'http://joinmastodon.org/ns#', 'votersCount' => 'toot:votersCount' },
|
voters_count: { 'toot' => 'http://joinmastodon.org/ns#', 'votersCount' => 'toot:votersCount' },
|
||||||
olm: { 'toot' => 'http://joinmastodon.org/ns#', 'Device' => 'toot:Device', 'Ed25519Signature' => 'toot:Ed25519Signature', 'Ed25519Key' => 'toot:Ed25519Key', 'Curve25519Key' => 'toot:Curve25519Key', 'EncryptedMessage' => 'toot:EncryptedMessage', 'publicKeyBase64' => 'toot:publicKeyBase64', 'deviceId' => 'toot:deviceId', 'claim' => { '@type' => '@id', '@id' => 'toot:claim' }, 'fingerprintKey' => { '@type' => '@id', '@id' => 'toot:fingerprintKey' }, 'identityKey' => { '@type' => '@id', '@id' => 'toot:identityKey' }, 'devices' => { '@type' => '@id', '@id' => 'toot:devices' }, 'messageFranking' => 'toot:messageFranking', 'messageType' => 'toot:messageType', 'cipherText' => 'toot:cipherText' },
|
olm: { 'toot' => 'http://joinmastodon.org/ns#', 'Device' => 'toot:Device', 'Ed25519Signature' => 'toot:Ed25519Signature', 'Ed25519Key' => 'toot:Ed25519Key', 'Curve25519Key' => 'toot:Curve25519Key', 'EncryptedMessage' => 'toot:EncryptedMessage', 'publicKeyBase64' => 'toot:publicKeyBase64', 'deviceId' => 'toot:deviceId', 'claim' => { '@type' => '@id', '@id' => 'toot:claim' }, 'fingerprintKey' => { '@type' => '@id', '@id' => 'toot:fingerprintKey' }, 'identityKey' => { '@type' => '@id', '@id' => 'toot:identityKey' }, 'devices' => { '@type' => '@id', '@id' => 'toot:devices' }, 'messageFranking' => 'toot:messageFranking', 'messageType' => 'toot:messageType', 'cipherText' => 'toot:cipherText' },
|
||||||
suspended: { 'toot' => 'http://joinmastodon.org/ns#', 'suspended' => 'toot:suspended' },
|
suspended: { 'toot' => 'http://joinmastodon.org/ns#', 'suspended' => 'toot:suspended' },
|
||||||
|
is_cat: { 'isCat' => 'as:isCat' },
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
def self.default_key_transform
|
def self.default_key_transform
|
||||||
|
@ -28,6 +28,7 @@ class Formatter
|
|||||||
unless status.local?
|
unless status.local?
|
||||||
html = reformat(raw_content)
|
html = reformat(raw_content)
|
||||||
html = encode_custom_emojis(html, status.emojis, options[:autoplay]) if options[:custom_emojify]
|
html = encode_custom_emojis(html, status.emojis, options[:autoplay]) if options[:custom_emojify]
|
||||||
|
html = nyaize(html) if options[:nyaize]
|
||||||
return html.html_safe # rubocop:disable Rails/OutputSafety
|
return html.html_safe # rubocop:disable Rails/OutputSafety
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -39,6 +40,7 @@ class Formatter
|
|||||||
html = encode_and_link_urls(html, linkable_accounts)
|
html = encode_and_link_urls(html, linkable_accounts)
|
||||||
html = encode_custom_emojis(html, status.emojis, options[:autoplay]) if options[:custom_emojify]
|
html = encode_custom_emojis(html, status.emojis, options[:autoplay]) if options[:custom_emojify]
|
||||||
html = simple_format(html, {}, sanitize: false)
|
html = simple_format(html, {}, sanitize: false)
|
||||||
|
html = nyaize(html) if options[:nyaize]
|
||||||
html = html.delete("\n")
|
html = html.delete("\n")
|
||||||
|
|
||||||
html.html_safe # rubocop:disable Rails/OutputSafety
|
html.html_safe # rubocop:disable Rails/OutputSafety
|
||||||
@ -192,6 +194,10 @@ class Formatter
|
|||||||
end
|
end
|
||||||
# rubocop:enable Metrics/BlockNesting
|
# rubocop:enable Metrics/BlockNesting
|
||||||
|
|
||||||
|
def nyaize(html)
|
||||||
|
html.gsub(/な/, "にゃ").gsub(/ナ/, "ニャ").gsub(/ナ/, "ニャ").gsub(/[나-낳]/){|c|(c.ord + '냐'.ord - '나'.ord).chr}
|
||||||
|
end
|
||||||
|
|
||||||
def rewrite(text, entities)
|
def rewrite(text, entities)
|
||||||
text = text.to_s
|
text = text.to_s
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
# featured_collection_url :string
|
# featured_collection_url :string
|
||||||
# fields :jsonb
|
# fields :jsonb
|
||||||
# actor_type :string
|
# actor_type :string
|
||||||
|
# cat :boolean default(FALSE), not null
|
||||||
# discoverable :boolean
|
# discoverable :boolean
|
||||||
# also_known_as :string is an Array
|
# also_known_as :string is an Array
|
||||||
# silenced_at :datetime
|
# silenced_at :datetime
|
||||||
|
@ -129,7 +129,10 @@ class Status < ApplicationRecord
|
|||||||
],
|
],
|
||||||
thread: { account: :account_stat }
|
thread: { account: :account_stat }
|
||||||
|
|
||||||
delegate :domain, to: :account, prefix: true
|
delegate :domain,
|
||||||
|
:cat,
|
||||||
|
to: :account,
|
||||||
|
prefix: true
|
||||||
|
|
||||||
REAL_TIME_WINDOW = 6.hours
|
REAL_TIME_WINDOW = 6.hours
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
|
|||||||
attributes :id, :type, :following, :followers,
|
attributes :id, :type, :following, :followers,
|
||||||
:inbox, :outbox, :featured, :featured_tags,
|
:inbox, :outbox, :featured, :featured_tags,
|
||||||
:preferred_username, :name, :summary,
|
:preferred_username, :name, :summary,
|
||||||
:url, :manually_approves_followers,
|
:url, :manually_approves_followers, :is_cat
|
||||||
:discoverable
|
:discoverable
|
||||||
|
|
||||||
has_one :public_key, serializer: ActivityPub::PublicKeySerializer
|
has_one :public_key, serializer: ActivityPub::PublicKeySerializer
|
||||||
@ -138,6 +138,10 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
|
|||||||
object.suspended? ? false : object.locked
|
object.suspended? ? false : object.locked
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def is_cat
|
||||||
|
object.cat
|
||||||
|
end
|
||||||
|
|
||||||
def virtual_tags
|
def virtual_tags
|
||||||
object.suspended? ? [] : (object.emojis + object.tags)
|
object.suspended? ? [] : (object.emojis + object.tags)
|
||||||
end
|
end
|
||||||
|
@ -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, :bot, :discoverable, :group, :created_at,
|
attributes :id, :username, :acct, :display_name, :locked, :bot, :cat, :discoverable, :group, :created_at,
|
||||||
:note, :url, :avatar, :avatar_static, :header, :header_static,
|
:note, :url, :avatar, :avatar_static, :header, :header_static,
|
||||||
:followers_count, :following_count, :statuses_count, :last_status_at
|
:followers_count, :following_count, :statuses_count, :last_status_at
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
|||||||
end
|
end
|
||||||
|
|
||||||
def content
|
def content
|
||||||
Formatter.instance.format(object)
|
Formatter.instance.format(object, nyaize: object.account.cat)
|
||||||
end
|
end
|
||||||
|
|
||||||
def url
|
def url
|
||||||
|
@ -112,6 +112,7 @@ class ActivityPub::ProcessAccountService < BaseService
|
|||||||
@account.followers_count = followers_total_items if followers_total_items.present?
|
@account.followers_count = followers_total_items if followers_total_items.present?
|
||||||
@account.hide_collections = following_private? || followers_private?
|
@account.hide_collections = following_private? || followers_private?
|
||||||
@account.moved_to_account = @json['movedTo'].present? ? moved_account : nil
|
@account.moved_to_account = @json['movedTo'].present? ? moved_account : nil
|
||||||
|
@account.cat = @json['isCat'] || false
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_suspension!
|
def set_suspension!
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
.batch-table__row__content
|
.batch-table__row__content
|
||||||
.status__content><
|
.status__content><
|
||||||
- if status.proper.spoiler_text.blank?
|
- if status.proper.spoiler_text.blank?
|
||||||
= Formatter.instance.format(status.proper, custom_emojify: true)
|
= Formatter.instance.format(status.proper, custom_emojify: true, nyaize: status.proper.account.cat)
|
||||||
- else
|
- else
|
||||||
%details<
|
%details<
|
||||||
%summary><
|
%summary><
|
||||||
%strong> Content warning: #{Formatter.instance.format_spoiler(status.proper)}
|
%strong> Content warning: #{Formatter.instance.format_spoiler(status.proper)}
|
||||||
= Formatter.instance.format(status.proper, custom_emojify: true)
|
= Formatter.instance.format(status.proper, custom_emojify: true, nyaize: status.proper.account.cat)
|
||||||
|
|
||||||
- unless status.proper.media_attachments.empty?
|
- unless status.proper.media_attachments.empty?
|
||||||
- if status.proper.media_attachments.first.video?
|
- if status.proper.media_attachments.first.video?
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
= Formatter.instance.format_spoiler(status)
|
= Formatter.instance.format_spoiler(status)
|
||||||
|
|
||||||
%div.auto-dir
|
%div.auto-dir
|
||||||
= Formatter.instance.format(status)
|
= Formatter.instance.format(status, nyaize: status.account.cat)
|
||||||
|
|
||||||
- if status.media_attachments.size > 0
|
- if status.media_attachments.size > 0
|
||||||
%p
|
%p
|
||||||
|
@ -29,6 +29,9 @@
|
|||||||
.fields-group
|
.fields-group
|
||||||
= f.input :bot, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.bot')
|
= f.input :bot, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.bot')
|
||||||
|
|
||||||
|
.fields-group
|
||||||
|
= f.input :cat, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.cat')
|
||||||
|
|
||||||
- if Setting.profile_directory
|
- if Setting.profile_directory
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :discoverable, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.discoverable'), recommended: true
|
= f.input :discoverable, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.discoverable'), recommended: true
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
%span.p-summary> #{Formatter.instance.format_spoiler(status, autoplay: autoplay)}
|
%span.p-summary> #{Formatter.instance.format_spoiler(status, autoplay: autoplay)}
|
||||||
%button.status__content__spoiler-link= t('statuses.show_more')
|
%button.status__content__spoiler-link= t('statuses.show_more')
|
||||||
.e-content
|
.e-content
|
||||||
= Formatter.instance.format(status, custom_emojify: true, autoplay: autoplay)
|
= Formatter.instance.format(status, custom_emojify: true, autoplay: autoplay, nyaize: status.account.cat)
|
||||||
- if status.preloadable_poll
|
- if status.preloadable_poll
|
||||||
= react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.preloadable_poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do
|
= react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.preloadable_poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do
|
||||||
= render partial: 'statuses/poll', locals: { status: status, poll: status.preloadable_poll, autoplay: autoplay }
|
= render partial: 'statuses/poll', locals: { status: status, poll: status.preloadable_poll, autoplay: autoplay }
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
%span.p-summary> #{Formatter.instance.format_spoiler(status, autoplay: autoplay)}
|
%span.p-summary> #{Formatter.instance.format_spoiler(status, autoplay: autoplay)}
|
||||||
%button.status__content__spoiler-link= t('statuses.show_more')
|
%button.status__content__spoiler-link= t('statuses.show_more')
|
||||||
.e-content
|
.e-content
|
||||||
= Formatter.instance.format(status, custom_emojify: true, autoplay: autoplay)
|
= Formatter.instance.format(status, custom_emojify: true, autoplay: autoplay, nyaize: status.account.cat)
|
||||||
- if status.preloadable_poll
|
- if status.preloadable_poll
|
||||||
= react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.preloadable_poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do
|
= react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.preloadable_poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do
|
||||||
= render partial: 'statuses/poll', locals: { status: status, poll: status.preloadable_poll, autoplay: autoplay }
|
= render partial: 'statuses/poll', locals: { status: status, poll: status.preloadable_poll, autoplay: autoplay }
|
||||||
|
@ -25,6 +25,7 @@ en:
|
|||||||
autofollow: People who sign up through the invite will automatically follow you
|
autofollow: People who sign up through the invite will automatically follow you
|
||||||
avatar: PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px
|
avatar: PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px
|
||||||
bot: This account mainly performs automated actions and might not be monitored
|
bot: This account mainly performs automated actions and might not be monitored
|
||||||
|
cat: This account is Cat
|
||||||
context: One or multiple contexts where the filter should apply
|
context: One or multiple contexts where the filter should apply
|
||||||
current_password: For security purposes please enter the password of the current account
|
current_password: For security purposes please enter the password of the current account
|
||||||
current_username: To confirm, please enter the username of the current account
|
current_username: To confirm, please enter the username of the current account
|
||||||
|
@ -25,6 +25,7 @@ ja:
|
|||||||
autofollow: 招待から登録した人が自動的にあなたをフォローするようになります
|
autofollow: 招待から登録した人が自動的にあなたをフォローするようになります
|
||||||
avatar: "%{size}までのPNG、GIF、JPGが利用可能です。%{dimensions}pxまで縮小されます"
|
avatar: "%{size}までのPNG、GIF、JPGが利用可能です。%{dimensions}pxまで縮小されます"
|
||||||
bot: このアカウントは主に自動で動作し、人が見ていない可能性があります
|
bot: このアカウントは主に自動で動作し、人が見ていない可能性があります
|
||||||
|
cat: このアカウントはCatです
|
||||||
context: フィルターを適用する対象 (複数選択可)
|
context: フィルターを適用する対象 (複数選択可)
|
||||||
current_password: 現在のアカウントのパスワードを入力してください
|
current_password: 現在のアカウントのパスワードを入力してください
|
||||||
current_username: 確認のため、現在のアカウントのユーザー名を入力してください
|
current_username: 確認のため、現在のアカウントのユーザー名を入力してください
|
||||||
|
7
db/migrate/20181122090024_add_cat_to_accounts.rb
Normal file
7
db/migrate/20181122090024_add_cat_to_accounts.rb
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class AddCatToAccounts < ActiveRecord::Migration[5.2]
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
def change
|
||||||
|
add_column :accounts, :cat, :boolean, default: false, null: false
|
||||||
|
end
|
||||||
|
end
|
@ -180,6 +180,7 @@ ActiveRecord::Schema.define(version: 2020_12_18_054746) do
|
|||||||
t.string "featured_collection_url"
|
t.string "featured_collection_url"
|
||||||
t.jsonb "fields"
|
t.jsonb "fields"
|
||||||
t.string "actor_type"
|
t.string "actor_type"
|
||||||
|
t.boolean "cat", default: false, null: false
|
||||||
t.boolean "discoverable"
|
t.boolean "discoverable"
|
||||||
t.string "also_known_as", array: true
|
t.string "also_known_as", array: true
|
||||||
t.datetime "silenced_at"
|
t.datetime "silenced_at"
|
||||||
|
Loading…
Reference in New Issue
Block a user