Compare commits

...
Sign in to create a new pull request.

18 commits

Author SHA1 Message Date
KMY(雪あすか)
fcb81c4eac
Merge pull request #687 from kmycode/kb-draft-11.4
Release: 11.4
2024-04-11 08:34:24 +09:00
KMY
2de228f84f Bump version to 11.4 2024-04-10 08:35:12 +09:00
Yuicho
bc968abfbe Fix: [WebUI] フルダークテーマの修正 (#708)
* Fix media alt textarea color

投稿に添付したメディアの編集モーダルウインドウに存在する「視覚的に閲覧が難しいユーザーへの説明」を入力するテキストエリアの色を修正

* Fix compose-form__warning color

投稿画面にて一部の公開範囲などを選んだ際に、入力欄の上部に表示される .compose-form__warning の背景色を修正(文字の視認性向上のため)

* fix CSS Selector

idの指定を`#~~~` から `[id=~~~]` に変更
2024-04-10 08:35:12 +09:00
KMY
83900d2581 Fix test 2024-04-09 09:22:40 +09:00
KMY(雪あすか)
e53c6b13eb Fix: #703 NGワード、センシティブワード「無関係なフォロワーへのメンション」が、自分自身へのメンションにも適用される (#704) 2024-04-09 09:03:11 +09:00
KMY(雪あすか)
13e5eed811 Fix: #367 #557 Webで引用された投稿を表示すると、その投稿のリアクション情報がリセットされる (#702) 2024-04-09 08:44:31 +09:00
KMY(雪あすか)
af7aae66f8 Add: 絵文字リアクション対応サーバーにrosekey (#698) 2024-04-09 08:44:31 +09:00
KMY
f16bd4fcb1 Fix test 2024-04-01 09:25:13 +09:00
KMY(雪あすか)
305021b543 Fix: threads.netのインスタンス情報のフェッチが止まらない問題 (#681) 2024-04-01 09:02:28 +09:00
KMY(雪あすか)
aef6d96d55 Fix: 投稿にNGワードが含まれる場合、投稿のモデレーションができなくなる場合がある問題 (#685) 2024-04-01 09:02:22 +09:00
KMY(雪あすか)
de9ab9042f Fix: ドメインブロックのトレンド掲載を拒否に、ハッシュタグが含まれない問題 (#676) 2024-04-01 09:02:06 +09:00
KMY(雪あすか)
f096449e7f Change: #671 「メディアを常に閲覧注意としてマークする」をONにしている時、2枚目以降の画像アップロードでセンシティブフラグを付けない (#673) 2024-04-01 09:01:50 +09:00
KMY(雪あすか)
08d6cf2a38 Fix: #655 センシティブフラグ付きの画像を編集するとフラグが外れる (#662) 2024-04-01 09:01:31 +09:00
KMY(雪あすか)
a670b10552 Add: 貢献者 (#658) 2024-04-01 09:01:12 +09:00
aoisensi
2db9d6ac92 Fix: お知らせのページ送りの数字がずれるのを修正 (#656) 2024-04-01 09:00:52 +09:00
KMY(雪あすか)
490923d104
Merge pull request #652 from kmycode/kb-draft-11.3
Release: 11.3
2024-03-12 08:28:08 +09:00
KMY
704e6264fd Merge remote-tracking branch 'origin/kb_development' into releases/11.3 2024-03-08 12:47:58 +09:00
KMY
78948753b1 Release: 11.3 2024-03-08 12:43:51 +09:00
19 changed files with 100 additions and 22 deletions

View file

@ -5,6 +5,7 @@
kmyblueフォークは、以下の方の貢献によって成り立っています。 kmyblueフォークは、以下の方の貢献によって成り立っています。
本家Mastodonの貢献者については、`AUTHORS.md`をご覧ください。 本家Mastodonの貢献者については、`AUTHORS.md`をご覧ください。
- [aoisensi](https://github.com/aoisensi)
- [KMY](https://github.com/kmycode) - [KMY](https://github.com/kmycode)
- [S-H-GAMELINKS](https://github.com/S-H-GAMELINKS) - [S-H-GAMELINKS](https://github.com/S-H-GAMELINKS)
- [Yuicho](https://github.com/yuicho) - [Yuicho](https://github.com/yuicho)
@ -12,6 +13,6 @@ kmyblueフォークは、以下の方の貢献によって成り立っていま
## 特記 ## 特記
kmyblueフォークの開発にあたって、API・Activity仕様の設計一部機能については内部仕様策定の過程で下記リポジトリのコードを参考にしました。 kmyblueフォークの開発にあたって、API・Activity仕様の設計一部機能については内部仕様策定の過程で下記リポジトリのコードを参考にしました。
kmyblueフォークに直接貢献したわけではありませんが、以下のリポジトリにある絵文字リアクション機能・検索範囲機能のコードのうち、ごく一部ではありますがkmyblueへ転写した箇所がございますため、お名前記載させていただきます。 kmyblueフォークに直接貢献したわけではありませんが、以下のリポジトリにある絵文字リアクション機能・検索範囲機能のコードのうち一部にkmyblueへ転写した箇所がございますため、お名前記載させていただきます。
- [Fedibird](https://github.com/fedibird/mastodon) - [Fedibird](https://github.com/fedibird/mastodon)

View file

@ -34,7 +34,8 @@ module Admin
UpdateStatusService.new.call( UpdateStatusService.new.call(
@status, @status,
edit_status_account_id, edit_status_account_id,
no_history: true no_history: true,
bypass_validation: true
) )
log_action(:remove_history, @status) log_action(:remove_history, @status)
redirect_to admin_account_status_path redirect_to admin_account_status_path
@ -46,7 +47,8 @@ module Admin
@status, @status,
edit_status_account_id, edit_status_account_id,
media_ids: [], media_ids: [],
media_attributes: [] media_attributes: [],
bypass_validation: true
) )
log_action(:remove_media, @status) log_action(:remove_media, @status)
redirect_to admin_account_status_path redirect_to admin_account_status_path
@ -57,7 +59,8 @@ module Admin
UpdateStatusService.new.call( UpdateStatusService.new.call(
@status, @status,
edit_status_account_id, edit_status_account_id,
sensitive: true sensitive: true,
bypass_validation: true
) )
log_action(:force_sensitive, @status) log_action(:force_sensitive, @status)
redirect_to admin_account_status_path redirect_to admin_account_status_path
@ -68,7 +71,8 @@ module Admin
UpdateStatusService.new.call( UpdateStatusService.new.call(
@status, @status,
edit_status_account_id, edit_status_account_id,
spoiler_text: 'CW' spoiler_text: 'CW',
bypass_validation: true
) )
log_action(:force_cw, @status) log_action(:force_cw, @status)
redirect_to admin_account_status_path redirect_to admin_account_status_path

View file

@ -337,7 +337,7 @@ export function uploadCompose(files) {
if (status === 200) { if (status === 200) {
dispatch(uploadComposeSuccess(data, file)); dispatch(uploadComposeSuccess(data, file));
if (defaultSensitive && !spoiler) { if (defaultSensitive && !spoiler && (media.size + i) === 0) {
dispatch(changeComposeSpoilerness()); dispatch(changeComposeSpoilerness());
} }
} else if (status === 202) { } else if (status === 202) {

View file

@ -72,7 +72,7 @@ export function importFetchedStatuses(statuses) {
processStatus(status.reblog); processStatus(status.reblog);
} }
if (status.quote && status.quote.id) { if (status.quote && status.quote.id && !getState().getIn(['statuses', status.id])) {
processStatus(status.quote); processStatus(status.quote);
} }

View file

@ -629,7 +629,7 @@ export default function compose(state = initialState, action) {
map.set('spoiler', true); map.set('spoiler', true);
map.set('spoiler_text', action.spoiler_text); map.set('spoiler_text', action.spoiler_text);
} else { } else {
map.set('spoiler', false); map.set('spoiler', action.status.get('sensitive'));
map.set('spoiler_text', ''); map.set('spoiler_text', '');
} }

View file

@ -1,6 +1,7 @@
input[type='text']:not(#cw-spoiler-input), input[type='text']:not(#cw-spoiler-input),
input[type='search'], input[type='search'],
input[type='number'], input[type='number'],
textarea[id='upload-modal__description'],
input:not([type]) { input:not([type]) {
background: $ui-base-color !important; background: $ui-base-color !important;
color: $primary-text-color !important; color: $primary-text-color !important;
@ -24,6 +25,7 @@ input:not([type]) {
color: $classic-secondary-color !important; color: $classic-secondary-color !important;
} }
.compose-form__warning,
.modal-root__modal { .modal-root__modal {
background: lighten($classic-base-color, 12%); background: lighten($classic-base-color, 12%);
} }

View file

@ -4142,6 +4142,10 @@ a.status-card {
.announcements { .announcements {
z-index: 1; z-index: 1;
position: relative; position: relative;
.announcements__pagination > * {
vertical-align: middle;
}
} }
} }

View file

@ -83,7 +83,7 @@ class Admin::StatusBatchAction
authorize([:admin, status], :update?) authorize([:admin, status], :update?)
if target_account.local? if target_account.local?
UpdateStatusService.new.call(status, representative_account.id, sensitive: true) UpdateStatusService.new.call(status, representative_account.id, sensitive: true, bypass_validation: true)
else else
status.update(sensitive: true) status.update(sensitive: true)
end end
@ -119,7 +119,7 @@ class Admin::StatusBatchAction
status_text = "#{status.spoiler_text}\n\n#{status_text}" if status.spoiler_text status_text = "#{status.spoiler_text}\n\n#{status_text}" if status.spoiler_text
if target_account.local? if target_account.local?
UpdateStatusService.new.call(status, representative_account.id, spoiler_text: 'CW', text: status_text) UpdateStatusService.new.call(status, representative_account.id, spoiler_text: 'CW', text: status_text, bypass_validation: true)
else else
status.update(spoiler_text: 'CW', text: status_text) status.update(spoiler_text: 'CW', text: status_text)
end end

View file

@ -186,6 +186,10 @@ module Account::Interactions
active_relationships.exists?(target_account: other_account) active_relationships.exists?(target_account: other_account)
end end
def following_or_self?(other_account)
id == other_account.id || following?(other_account)
end
def following_anyone? def following_anyone?
active_relationships.exists? active_relationships.exists?
end end

View file

@ -27,6 +27,7 @@ class InstanceInfo < ApplicationRecord
meisskey meisskey
misskey misskey
pleroma pleroma
rosekey
sharkey sharkey
).freeze ).freeze

View file

@ -13,6 +13,7 @@ class Trends::Tags < Trends::Base
def register(status, at_time = Time.now.utc) def register(status, at_time = Time.now.utc)
return unless !status.reblog? && %i(public public_unlisted login).include?(status.visibility.to_sym) && !status.account.silenced? return unless !status.reblog? && %i(public public_unlisted login).include?(status.visibility.to_sym) && !status.account.silenced?
return if !status.account.local? && DomainBlock.block_trends?(status.account.domain)
status.tags.each do |tag| status.tags.each do |tag|
add(tag, status.account_id, at_time) if tag.usable? add(tag, status.account_id, at_time) if tag.usable?

View file

@ -56,14 +56,14 @@ class ApproveAppealService < BaseService
def undo_mark_statuses_as_sensitive! def undo_mark_statuses_as_sensitive!
representative_account = Account.representative representative_account = Account.representative
@strike.statuses.includes(:media_attachments).find_each do |status| @strike.statuses.includes(:media_attachments).find_each do |status|
UpdateStatusService.new.call(status, representative_account.id, sensitive: false) if status.with_media? UpdateStatusService.new.call(status, representative_account.id, sensitive: false, bypass_validation: true) if status.with_media?
end end
end end
def undo_force_cw! def undo_force_cw!
representative_account = Account.representative representative_account = Account.representative
@strike.statuses.includes(:media_attachments).find_each do |status| @strike.statuses.includes(:media_attachments).find_each do |status|
UpdateStatusService.new.call(status, representative_account.id, spoiler_text: '') UpdateStatusService.new.call(status, representative_account.id, spoiler_text: '', bypass_validation: true) if status.spoiler_text.present?
end end
end end

View file

@ -248,12 +248,12 @@ class PostStatusService < BaseService
def mention_to_stranger? def mention_to_stranger?
return @mention_to_stranger if defined?(@mention_to_stranger) return @mention_to_stranger if defined?(@mention_to_stranger)
@mention_to_stranger = @status.mentions.map(&:account).to_a.any? { |mentioned_account| mentioned_account.id != @account.id && !mentioned_account.following?(@account) } || @mention_to_stranger = @status.mentions.map(&:account).to_a.any? { |mentioned_account| !mentioned_account.following_or_self?(@account) } ||
(@in_reply_to && @in_reply_to.account.id != @account.id && !@in_reply_to.account.following?(@account)) (@in_reply_to && !@in_reply_to.account.following_or_self?(@account))
end end
def reference_to_stranger? def reference_to_stranger?
referred_statuses.any? { |status| !status.account.following?(@account) } referred_statuses.any? { |status| !status.account.following_or_self?(@account) }
end end
def referred_statuses def referred_statuses

View file

@ -84,6 +84,7 @@ class UpdateStatusService < BaseService
end end
def validate_status! def validate_status!
return if @options[:bypass_validation]
raise Mastodon::ValidationError, I18n.t('statuses.contains_ng_words') if Admin::NgWord.reject?("#{@options[:spoiler_text]}\n#{@options[:text]}") raise Mastodon::ValidationError, I18n.t('statuses.contains_ng_words') if Admin::NgWord.reject?("#{@options[:spoiler_text]}\n#{@options[:text]}")
raise Mastodon::ValidationError, I18n.t('statuses.too_many_hashtags') if Admin::NgWord.hashtag_reject_with_extractor?(@options[:text] || '') raise Mastodon::ValidationError, I18n.t('statuses.too_many_hashtags') if Admin::NgWord.hashtag_reject_with_extractor?(@options[:text] || '')
raise Mastodon::ValidationError, I18n.t('statuses.too_many_mentions') if Admin::NgWord.mention_reject_with_extractor?(@options[:text] || '') raise Mastodon::ValidationError, I18n.t('statuses.too_many_mentions') if Admin::NgWord.mention_reject_with_extractor?(@options[:text] || '')
@ -91,10 +92,13 @@ class UpdateStatusService < BaseService
end end
def validate_status_mentions! def validate_status_mentions!
return if @options[:bypass_validation]
raise Mastodon::ValidationError, I18n.t('statuses.contains_ng_words') if (mention_to_stranger? || reference_to_stranger?) && Setting.stranger_mention_from_local_ng && Admin::NgWord.stranger_mention_reject?("#{@options[:spoiler_text]}\n#{@options[:text]}") raise Mastodon::ValidationError, I18n.t('statuses.contains_ng_words') if (mention_to_stranger? || reference_to_stranger?) && Setting.stranger_mention_from_local_ng && Admin::NgWord.stranger_mention_reject?("#{@options[:spoiler_text]}\n#{@options[:text]}")
end end
def validate_status_ng_rules! def validate_status_ng_rules!
return if @options[:bypass_validation]
result = check_invalid_status_for_ng_rule! @status.account, result = check_invalid_status_for_ng_rule! @status.account,
reaction_type: 'edit', reaction_type: 'edit',
spoiler_text: @options.key?(:spoiler_text) ? (@options[:spoiler_text] || '') : @status.spoiler_text, spoiler_text: @options.key?(:spoiler_text) ? (@options[:spoiler_text] || '') : @status.spoiler_text,
@ -119,12 +123,12 @@ class UpdateStatusService < BaseService
end end
def mention_to_stranger? def mention_to_stranger?
@status.mentions.map(&:account).to_a.any? { |mentioned_account| mentioned_account.id != @status.account.id && !mentioned_account.following?(@status.account) } || @status.mentions.map(&:account).to_a.any? { |mentioned_account| !mentioned_account.following_or_self?(@status.account) } ||
(@status.thread.present? && @status.thread.account.id != @status.account.id && !@status.thread.account.following?(@status.account)) (@status.thread.present? && !@status.thread.account.following_or_self?(@status.account))
end end
def reference_to_stranger? def reference_to_stranger?
referred_statuses.any? { |status| !status.account.following?(@status.account) } referred_statuses.any? { |status| !status.account.following_or_self?(@status.account) }
end end
def referred_statuses def referred_statuses

View file

@ -30,7 +30,7 @@ class ActivityPub::FetchInstanceInfoWorker
update_info!(link) update_info!(link)
true true
rescue Mastodon::UnexpectedResponseError rescue
true true
end end

View file

@ -9,13 +9,13 @@ module Mastodon
end end
def kmyblue_minor def kmyblue_minor
0 4
end end
def kmyblue_flag def kmyblue_flag
# 'LTS' # 'LTS'
'dev' # 'dev'
# nil nil
end end
def major def major

View file

@ -23,6 +23,33 @@ RSpec.describe Trends::Tags do
end end
end end
describe '#register' do
let(:tag) { Fabricate(:tag, usable: true) }
let(:account) { Fabricate(:account) }
let(:status) { Fabricate(:status, account: account, tags: [tag], created_at: at_time, updated_at: at_time) }
it 'records history' do
subject.register(status, at_time)
expect(tag.history.get(at_time).accounts).to eq 1
expect(tag.history.get(at_time).uses).to eq 1
expect(subject.send(:recently_used_ids, at_time)).to eq [tag.id]
end
context 'when account is rejected appending trends' do
let(:account) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/actor') }
before do
Fabricate(:domain_block, domain: 'example.com', block_trends: true, severity: :noop)
end
it 'does not record history' do
subject.register(status, at_time)
expect(tag.history.get(at_time).accounts).to eq 0
expect(tag.history.get(at_time).uses).to eq 0
end
end
end
describe '#query' do describe '#query' do
it 'returns a composable query scope' do it 'returns a composable query scope' do
expect(subject.query).to be_a Trends::Query expect(subject.query).to be_a Trends::Query

View file

@ -663,6 +663,17 @@ RSpec.describe PostStatusService, type: :service do
expect(status.text).to eq text expect(status.text).to eq text
end end
it 'does not hit ng words for mention to self' do
account = Fabricate(:account, username: 'cool', domain: nil)
text = 'ng word test @cool'
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
status = subject.call(account, text: text)
expect(status).to be_persisted
expect(status.text).to eq text
end
it 'hit ng words for reply' do it 'hit ng words for reply' do
account = Fabricate(:account) account = Fabricate(:account)
text = 'ng word test' text = 'ng word test'
@ -721,6 +732,18 @@ RSpec.describe PostStatusService, type: :service do
expect(status.text).to eq text expect(status.text).to eq text
end end
it 'does not hit ng words for reference to self' do
target_status = Fabricate(:status)
account = target_status.account
text = "ng word test BT: #{ActivityPub::TagManager.instance.uri_for(target_status)}"
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
status = subject.call(account, text: text)
expect(status).to be_persisted
expect(status.text).to eq text
end
it 'using hashtag under limit' do it 'using hashtag under limit' do
account = Fabricate(:account) account = Fabricate(:account)
text = '#a #b' text = '#a #b'

View file

@ -277,6 +277,13 @@ RSpec.describe UpdateStatusService, type: :service do
expect { subject.call(status, status.account_id, text: text) }.to raise_error(Mastodon::ValidationError) expect { subject.call(status, status.account_id, text: text) }.to raise_error(Mastodon::ValidationError)
end end
it 'bypass ng words' do
text = 'ng word test'
Form::AdminSettings.new(ng_words: 'test').save
expect { subject.call(status, status.account_id, text: text, bypass_validation: true) }.to_not raise_error
end
it 'not hit ng words' do it 'not hit ng words' do
text = 'ng word aiueo' text = 'ng word aiueo'
Form::AdminSettings.new(ng_words: 'test').save Form::AdminSettings.new(ng_words: 'test').save