From b18268a0a062c373d4ee4178ef550bb98805d9b9 Mon Sep 17 00:00:00 2001 From: KMY Date: Thu, 6 Apr 2023 20:07:53 +0900 Subject: [PATCH 1/5] Wip: Fix error --- app/services/activitypub/process_account_service.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index 46813efc62..6f08624f69 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -77,6 +77,7 @@ class ActivityPub::ProcessAccountService < BaseService @account.suspended_at = domain_block.created_at if auto_suspend? @account.suspension_origin = :local if auto_suspend? @account.silenced_at = domain_block.created_at if auto_silence? + @account.searchability = :private # not null @account.save end From 7d76d01795f94e2dc1429047115e050eb697e642 Mon Sep 17 00:00:00 2001 From: KMY Date: Thu, 6 Apr 2023 20:28:05 +0900 Subject: [PATCH 2/5] Change visibility to visibility_ex --- app/javascript/mastodon/actions/boosts.js | 2 +- app/javascript/mastodon/actions/compose.js | 4 ++-- app/javascript/mastodon/components/status.jsx | 6 +++--- app/javascript/mastodon/components/status_action_bar.jsx | 6 +++--- .../features/picture_in_picture/components/footer.jsx | 4 ++-- .../features/report/components/status_check_box.jsx | 2 +- .../mastodon/features/status/components/action_bar.jsx | 6 +++--- .../features/status/components/detailed_status.jsx | 6 +++--- .../mastodon/features/ui/components/boost_modal.jsx | 6 +++--- app/javascript/mastodon/reducers/compose.js | 6 +++--- app/serializers/rest/status_serializer.rb | 8 +++++++- 11 files changed, 31 insertions(+), 25 deletions(-) diff --git a/app/javascript/mastodon/actions/boosts.js b/app/javascript/mastodon/actions/boosts.js index c0f0f3acc5..6d3eed1dc5 100644 --- a/app/javascript/mastodon/actions/boosts.js +++ b/app/javascript/mastodon/actions/boosts.js @@ -7,7 +7,7 @@ export function initBoostModal(props) { return (dispatch, getState) => { const default_privacy = getState().getIn(['compose', 'default_privacy']); - const privacy = props.status.get('visibility') === 'private' ? 'private' : default_privacy; + const privacy = props.status.get('visibility_ex') === 'private' ? 'private' : default_privacy; dispatch({ type: BOOSTS_INIT_MODAL, diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index 331c634897..6000970512 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -222,11 +222,11 @@ export function submitCompose(routerHistory) { dispatch(importFetchedStatus({ ...response.data })); } - if (statusId === null && response.data.visibility !== 'direct') { + if (statusId === null && response.data.visibility_ex !== 'direct') { insertIfOnline('home'); } - if (statusId === null && response.data.in_reply_to_id === null && response.data.visibility === 'public') { + if (statusId === null && response.data.in_reply_to_id === null && response.data.visibility_ex === 'public') { insertIfOnline('community'); insertIfOnline('public'); insertIfOnline(`account:${response.data.account.id}`); diff --git a/app/javascript/mastodon/components/status.jsx b/app/javascript/mastodon/components/status.jsx index 78cbd22eae..7f387d29dc 100644 --- a/app/javascript/mastodon/components/status.jsx +++ b/app/javascript/mastodon/components/status.jsx @@ -512,7 +512,7 @@ class Status extends ImmutablePureComponent { 'direct': { icon: 'at', text: intl.formatMessage(messages.direct_short) }, }; - const visibilityIcon = visibilityIconInfo[status.get('visibility')]; + const visibilityIcon = visibilityIconInfo[status.get('visibility_ex')]; let emojiReactionsBar = null; if (!this.props.withoutEmojiReactions && status.get('emoji_reactions')) { @@ -524,10 +524,10 @@ class Status extends ImmutablePureComponent { return ( -
+
{prepend} -
+
diff --git a/app/javascript/mastodon/components/status_action_bar.jsx b/app/javascript/mastodon/components/status_action_bar.jsx index 1a6be65eef..b9509910b8 100644 --- a/app/javascript/mastodon/components/status_action_bar.jsx +++ b/app/javascript/mastodon/components/status_action_bar.jsx @@ -251,8 +251,8 @@ class StatusActionBar extends ImmutablePureComponent { const { signedIn, permissions } = this.context.identity; const anonymousAccess = !signedIn; - const publicStatus = ['public', 'unlisted', 'public_unlisted'].includes(status.get('visibility')); - const pinnableStatus = ['public', 'unlisted', 'public_unlisted', 'private'].includes(status.get('visibility')); + const publicStatus = ['public', 'unlisted', 'public_unlisted'].includes(status.get('visibility_ex')); + const pinnableStatus = ['public', 'unlisted', 'public_unlisted', 'private'].includes(status.get('visibility_ex')); const mutingConversation = status.get('muted'); const account = status.get('account'); const writtenByMe = status.getIn(['account', 'id']) === me; @@ -351,7 +351,7 @@ class StatusActionBar extends ImmutablePureComponent { replyTitle = intl.formatMessage(messages.replyAll); } - const reblogPrivate = status.getIn(['account', 'id']) === me && status.get('visibility') === 'private'; + const reblogPrivate = status.getIn(['account', 'id']) === me && status.get('visibility_ex') === 'private'; let reblogTitle = ''; if (status.get('reblogged')) { diff --git a/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx b/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx index 10e18e504f..3ccd9eb77e 100644 --- a/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx +++ b/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx @@ -154,8 +154,8 @@ class Footer extends ImmutablePureComponent { render () { const { status, intl, withOpenButton } = this.props; - const publicStatus = ['public', 'unlisted', 'public_unlisted'].includes(status.get('visibility')); - const reblogPrivate = status.getIn(['account', 'id']) === me && status.get('visibility') === 'private'; + const publicStatus = ['public', 'unlisted', 'public_unlisted'].includes(status.get('visibility_ex')); + const reblogPrivate = status.getIn(['account', 'id']) === me && status.get('visibility_ex') === 'private'; let replyIcon, replyTitle; diff --git a/app/javascript/mastodon/features/report/components/status_check_box.jsx b/app/javascript/mastodon/features/report/components/status_check_box.jsx index ba44d4a0ed..1ddeaad450 100644 --- a/app/javascript/mastodon/features/report/components/status_check_box.jsx +++ b/app/javascript/mastodon/features/report/components/status_check_box.jsx @@ -49,7 +49,7 @@ class StatusCheckBox extends React.PureComponent { 'direct': { icon: 'at', text: intl.formatMessage(messages.direct_short) }, }; - const visibilityIcon = visibilityIconInfo[status.get('visibility')]; + const visibilityIcon = visibilityIconInfo[status.get('visibility_ex')]; const labelComponent = (
diff --git a/app/javascript/mastodon/features/status/components/action_bar.jsx b/app/javascript/mastodon/features/status/components/action_bar.jsx index 7ae8dc97a3..5c0f36ea10 100644 --- a/app/javascript/mastodon/features/status/components/action_bar.jsx +++ b/app/javascript/mastodon/features/status/components/action_bar.jsx @@ -192,8 +192,8 @@ class ActionBar extends React.PureComponent { const { status, relationship, intl } = this.props; const { signedIn, permissions } = this.context.identity; - const publicStatus = ['public', 'unlisted', 'public_unlisted'].includes(status.get('visibility')); - const pinnableStatus = ['public', 'unlisted', 'public_unlisted', 'private'].includes(status.get('visibility')); + const publicStatus = ['public', 'unlisted', 'public_unlisted'].includes(status.get('visibility_ex')); + const pinnableStatus = ['public', 'unlisted', 'public_unlisted', 'private'].includes(status.get('visibility_ex')); const mutingConversation = status.get('muted'); const account = status.get('account'); const writtenByMe = status.getIn(['account', 'id']) === me; @@ -280,7 +280,7 @@ class ActionBar extends React.PureComponent { replyIcon = 'reply-all'; } - const reblogPrivate = status.getIn(['account', 'id']) === me && status.get('visibility') === 'private'; + const reblogPrivate = status.getIn(['account', 'id']) === me && status.get('visibility_ex') === 'private'; let reblogTitle; if (status.get('reblogged')) { diff --git a/app/javascript/mastodon/features/status/components/detailed_status.jsx b/app/javascript/mastodon/features/status/components/detailed_status.jsx index 1a46c19f95..4a863035ae 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.jsx +++ b/app/javascript/mastodon/features/status/components/detailed_status.jsx @@ -219,7 +219,7 @@ class DetailedStatus extends ImmutablePureComponent { 'direct': { icon: 'at', text: intl.formatMessage(messages.direct_short) }, }; - const visibilityIcon = visibilityIconInfo[status.get('visibility')]; + const visibilityIcon = visibilityIconInfo[status.get('visibility_ex')]; const visibilityLink = · ; const searchabilityIconInfo = { @@ -232,7 +232,7 @@ class DetailedStatus extends ImmutablePureComponent { const searchabilityIcon = searchabilityIconInfo[status.get('searchability')]; const searchabilityLink = · ; - if (['private', 'direct'].includes(status.get('visibility'))) { + if (['private', 'direct'].includes(status.get('visibility_ex'))) { reblogLink = ''; } else if (this.context.router) { reblogLink = ( @@ -307,7 +307,7 @@ class DetailedStatus extends ImmutablePureComponent { return (
-
+
diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.jsx b/app/javascript/mastodon/features/ui/components/boost_modal.jsx index f9b36907c6..0a6347db23 100644 --- a/app/javascript/mastodon/features/ui/components/boost_modal.jsx +++ b/app/javascript/mastodon/features/ui/components/boost_modal.jsx @@ -93,12 +93,12 @@ class BoostModal extends ImmutablePureComponent { 'direct': { icon: 'at', text: intl.formatMessage(messages.direct_short) }, }; - const visibilityIcon = visibilityIconInfo[status.get('visibility')]; + const visibilityIcon = visibilityIconInfo[status.get('visibility_ex')]; return (
-
+
@@ -127,7 +127,7 @@ class BoostModal extends ImmutablePureComponent {
Shift + }} />
- {status.get('visibility') !== 'private' && !status.get('reblogged') && ( + {status.get('visibility_ex') !== 'private' && !status.get('reblogged') && ( { map.set('text', action.raw_text || unescapeHTML(expandMentions(action.status))); map.set('in_reply_to', action.status.get('in_reply_to_id')); - map.set('privacy', action.status.get('visibility')); + map.set('privacy', action.status.get('visibility_ex')); map.set('media_attachments', action.status.get('media_attachments').map((media) => media.set('unattached', true))); map.set('focusDate', new Date()); map.set('caretPosition', null); @@ -511,7 +511,7 @@ export default function compose(state = initialState, action) { map.set('id', action.status.get('id')); map.set('text', action.text); map.set('in_reply_to', action.status.get('in_reply_to_id')); - map.set('privacy', action.status.get('visibility')); + map.set('privacy', action.status.get('visibility_ex')); map.set('media_attachments', action.status.get('media_attachments')); map.set('focusDate', new Date()); map.set('caretPosition', null); diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb index d4677a2dbe..e86e07387b 100644 --- a/app/serializers/rest/status_serializer.rb +++ b/app/serializers/rest/status_serializer.rb @@ -4,7 +4,7 @@ class REST::StatusSerializer < ActiveModel::Serializer include FormattingHelper attributes :id, :created_at, :in_reply_to_id, :in_reply_to_account_id, - :sensitive, :spoiler_text, :visibility, :language, :translatable, + :sensitive, :spoiler_text, :visibility, :visibility_ex, :language, :translatable, :uri, :url, :replies_count, :reblogs_count, :searchability, :favourites_count, :emoji_reactions, :edited_at @@ -60,11 +60,17 @@ class REST::StatusSerializer < ActiveModel::Serializer # UX differences if object.limited_visibility? 'private' + elsif object.public_unlisted_visibility? + 'public' else object.visibility end end + def visibility_ex + object.visibility + end + def searchability object.compute_searchability end From 981d4424f544383508071a728ad5176f933deeff Mon Sep 17 00:00:00 2001 From: KMY Date: Fri, 7 Apr 2023 11:45:43 +0900 Subject: [PATCH 3/5] Disable media_only scope --- app/models/public_feed.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/public_feed.rb b/app/models/public_feed.rb index 6609c193e1..d7db5c3090 100644 --- a/app/models/public_feed.rb +++ b/app/models/public_feed.rb @@ -63,7 +63,7 @@ class PublicFeed end def media_only? - options[:only_media] + !local_only? && options[:only_media] end def public_scope From 498dc2ccce994a37a6b5eac73eddf9ced49873c4 Mon Sep 17 00:00:00 2001 From: KMY Date: Fri, 7 Apr 2023 13:48:44 +0900 Subject: [PATCH 4/5] Remove searchability support from public_feed --- app/models/public_feed.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/models/public_feed.rb b/app/models/public_feed.rb index d7db5c3090..8be8f87553 100644 --- a/app/models/public_feed.rb +++ b/app/models/public_feed.rb @@ -29,7 +29,6 @@ class PublicFeed scope.merge!(account_filters_scope) if account? scope.merge!(media_only_scope) if media_only? scope.merge!(language_scope) if account&.chosen_languages.present? - scope.merge!(public_searchable_scope) if local_only? && !account? scope.cache_ids.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id) end @@ -98,10 +97,6 @@ class PublicFeed Status.where(language: account.chosen_languages) end - def public_searchable_scope - Status.where(searchability: 'public').or(Status.where(searchability: nil).merge(Account.where(searchability: 'public'))) - end - def account_filters_scope Status.not_excluded_by_account(account).tap do |scope| scope.merge!(Status.not_domain_blocked_by_account(account)) unless local_only? From 21899ccf3f3360ceeb03f49a6433b5e46faef9be Mon Sep 17 00:00:00 2001 From: KMY Date: Fri, 7 Apr 2023 17:22:09 +0900 Subject: [PATCH 5/5] Fix removing my reaction flag on status updated --- .../mastodon/actions/importer/normalizer.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/app/javascript/mastodon/actions/importer/normalizer.js b/app/javascript/mastodon/actions/importer/normalizer.js index 6767b5a830..6065ed8ac2 100644 --- a/app/javascript/mastodon/actions/importer/normalizer.js +++ b/app/javascript/mastodon/actions/importer/normalizer.js @@ -1,7 +1,7 @@ import escapeTextContentForBrowser from 'escape-html'; import emojify from '../../features/emoji/emoji'; import { unescapeHTML } from '../../utils/html'; -import { expandSpoilers } from '../../initial_state'; +import { expandSpoilers, me } from '../../initial_state'; const domParser = new DOMParser(); @@ -66,8 +66,8 @@ export function normalizeStatus(status, normalOldStatus) { normalStatus.filtered = status.filtered.map(normalizeFilterResult); } - if (status.emoji_reactions) { - normalStatus.emojiReactions = status.emoji_reactions; + if (status.emoji_reactions && normalOldStatus) { + normalStatus.emoji_reactions = normalizeEmojiReactions(normalOldStatus.get('emoji_reactions').toArray()); } // Only calculate these values when status first encountered and @@ -100,6 +100,17 @@ export function normalizeStatus(status, normalOldStatus) { return normalStatus; } +export function normalizeEmojiReactions(emoji_reactions) { + const myAccountId = me; + let converted = []; + for (let emoji_reaction of emoji_reactions) { + let obj = emoji_reaction.toObject(); + obj.me = obj.account_ids.toArray().some((id) => id === myAccountId); + converted.push(obj); + } + return converted; +} + export function normalizePoll(poll) { const normalPoll = { ...poll }; const emojiMap = makeEmojiMap(normalPoll);