Remove: kmyblue独自機能の引用
This commit is contained in:
parent
620a895184
commit
d845d1e9fb
70 changed files with 812 additions and 1788 deletions
|
@ -56,11 +56,11 @@ class Api::V1::FiltersController < Api::BaseController
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params.permit(:phrase, :expires_in, :irreversible, :exclude_follows, :exclude_localusers, :with_quote, :with_profile, :whole_word, context: [])
|
||||
params.permit(:phrase, :expires_in, :irreversible, :exclude_follows, :exclude_localusers, :with_profile, :whole_word, context: [])
|
||||
end
|
||||
|
||||
def filter_params
|
||||
resource_params.slice(:phrase, :expires_in, :irreversible, :exclude_follows, :exclude_localusers, :with_quote, :with_profile, :context)
|
||||
resource_params.slice(:phrase, :expires_in, :irreversible, :exclude_follows, :exclude_localusers, :with_profile, :context)
|
||||
end
|
||||
|
||||
def keyword_params
|
||||
|
|
|
@ -43,6 +43,6 @@ class Api::V2::FiltersController < Api::BaseController
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params.permit(:title, :expires_in, :filter_action, :exclude_follows, :exclude_localusers, :with_quote, :with_profile, context: [], keywords_attributes: [:id, :keyword, :whole_word, :_destroy])
|
||||
params.permit(:title, :expires_in, :filter_action, :exclude_follows, :exclude_localusers, :with_profile, context: [], keywords_attributes: [:id, :keyword, :whole_word, :_destroy])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -47,6 +47,6 @@ class FiltersController < ApplicationController
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params.expect(custom_filter: [:title, :expires_in, :filter_action, :exclude_follows, :exclude_localusers, :exclude_quote, :exclude_profile, context: [], keywords_attributes: [[:id, :keyword, :whole_word, :_destroy]]])
|
||||
params.expect(custom_filter: [:title, :expires_in, :filter_action, :exclude_follows, :exclude_localusers, :exclude_profile, context: [], keywords_attributes: [[:id, :keyword, :whole_word, :_destroy]]])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,7 +29,6 @@ module ContextHelper
|
|||
limited_scope: { 'kmyblue' => 'http://kmy.blue/ns#', 'limitedScope' => 'kmyblue:limitedScope' },
|
||||
other_setting: { 'fedibird' => 'http://fedibird.com/ns#', 'otherSetting' => 'fedibird:otherSetting' },
|
||||
references: { 'fedibird' => 'http://fedibird.com/ns#', 'references' => { '@id' => 'fedibird:references', '@type' => '@id' } },
|
||||
quote_uri: { 'fedibird' => 'http://fedibird.com/ns#', 'quoteUri' => 'fedibird:quoteUri' },
|
||||
keywords: { 'schema' => 'http://schema.org#', 'keywords' => 'schema:keywords' },
|
||||
license: { 'schema' => 'http://schema.org#', 'license' => 'schema:license' },
|
||||
suspended: { 'toot' => 'http://joinmastodon.org/ns#', 'suspended' => 'toot:suspended' },
|
||||
|
|
|
@ -15,7 +15,6 @@ module KmyblueCapabilitiesHelper
|
|||
kmyblue_limited_scope
|
||||
kmyblue_antenna
|
||||
kmyblue_bookmark_category
|
||||
kmyblue_quote
|
||||
kmyblue_searchability_limited
|
||||
kmyblue_circle_history
|
||||
kmyblue_list_notification
|
||||
|
@ -41,7 +40,6 @@ module KmyblueCapabilitiesHelper
|
|||
capabilities = %i(
|
||||
enable_wide_emoji
|
||||
status_reference
|
||||
quote
|
||||
emoji_keywords
|
||||
circle
|
||||
)
|
||||
|
|
|
@ -70,10 +70,6 @@ export function importFetchedStatuses(statuses) {
|
|||
processStatus(status.reblog);
|
||||
}
|
||||
|
||||
if (status.quote?.id && !getState().getIn(['statuses', status.id])) {
|
||||
processStatus(status.quote);
|
||||
}
|
||||
|
||||
if (status.poll?.id) {
|
||||
pushUnique(polls, createPollFromServerJSON(status.poll, getState().polls[status.poll.id]));
|
||||
}
|
||||
|
|
|
@ -66,11 +66,6 @@ export function normalizeStatus(status, normalOldStatus) {
|
|||
normalStatus.spoiler_text = normalOldStatus.get('spoiler_text');
|
||||
normalStatus.hidden = normalOldStatus.get('hidden');
|
||||
|
||||
// for quoted post
|
||||
if (!normalStatus.filtered && normalOldStatus.get('filtered')) {
|
||||
normalStatus.filtered = normalOldStatus.get('filtered');
|
||||
}
|
||||
|
||||
if (normalOldStatus.get('translation')) {
|
||||
normalStatus.translation = normalOldStatus.get('translation');
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ const messages = defineMessages({
|
|||
message_poll: { id: 'notification.poll', defaultMessage: 'A poll you voted in has ended' },
|
||||
message_reblog: { id: 'notification.reblog', defaultMessage: '{name} boosted your post' },
|
||||
message_status: { id: 'notification.status', defaultMessage: '{name} just posted' },
|
||||
message_status_reference: { id: 'notification.status_reference', defaultMessage: '{name} quoted your post' },
|
||||
message_status_reference: { id: 'notification.status_reference', defaultMessage: '{name} linked your post' },
|
||||
message_update: { id: 'notification.update', defaultMessage: '{name} edited a post' },
|
||||
});
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ export interface ApiAccountOtherSettingsJSON {
|
|||
hide_followers_count: boolean;
|
||||
translatable_private: boolean;
|
||||
link_preview: boolean;
|
||||
allow_quote: boolean;
|
||||
emoji_reaction_policy:
|
||||
| 'allow'
|
||||
| 'outside_only'
|
||||
|
@ -34,7 +33,6 @@ export interface ApiAccountOtherSettingsJSON {
|
|||
export interface ApiServerFeaturesJSON {
|
||||
circle: boolean;
|
||||
emoji_reaction: boolean;
|
||||
quote: boolean;
|
||||
status_reference: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,580 +0,0 @@
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
import { injectIntl, defineMessages, FormattedMessage } from 'react-intl';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
|
||||
import { HotKeys } from 'react-hotkeys';
|
||||
|
||||
import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react';
|
||||
import PushPinIcon from '@/material-icons/400-24px/push_pin.svg?react';
|
||||
import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react';
|
||||
import ReplyIcon from '@/material-icons/400-24px/reply.svg?react';
|
||||
import AttachmentList from 'mastodon/components/attachment_list';
|
||||
import { ContentWarning } from 'mastodon/components/content_warning';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import PictureInPicturePlaceholder from 'mastodon/components/picture_in_picture_placeholder';
|
||||
import { withOptionalRouter, WithOptionalRouterPropTypes } from 'mastodon/utils/react_router';
|
||||
|
||||
import Card from '../features/status/components/card';
|
||||
// We use the component (and not the container) since we do not want
|
||||
// to use the progress bar to show download progress
|
||||
import Bundle from '../features/ui/components/bundle';
|
||||
import { MediaGallery, Video, Audio } from '../features/ui/util/async-components';
|
||||
import { SensitiveMediaContext } from '../features/ui/util/sensitive_media_context';
|
||||
import { displayMedia } from '../initial_state';
|
||||
|
||||
import { Avatar } from './avatar';
|
||||
import { DisplayName } from './display_name';
|
||||
import { getHashtagBarForStatus } from './hashtag_bar';
|
||||
import { RelativeTimestamp } from './relative_timestamp';
|
||||
import StatusContent from './status_content';
|
||||
import { VisibilityIcon } from './visibility_icon';
|
||||
|
||||
const domParser = new DOMParser();
|
||||
|
||||
export const textForScreenReader = (intl, status, rebloggedByText = false) => {
|
||||
const displayName = status.getIn(['account', 'display_name']);
|
||||
|
||||
const spoilerText = status.getIn(['translation', 'spoiler_text']) || status.get('spoiler_text');
|
||||
const contentHtml = status.getIn(['translation', 'contentHtml']) || status.get('contentHtml');
|
||||
const contentText = domParser.parseFromString(contentHtml, 'text/html').documentElement.textContent;
|
||||
|
||||
const values = [
|
||||
displayName.length === 0 ? status.getIn(['account', 'acct']).split('@')[0] : displayName,
|
||||
spoilerText && status.get('hidden') ? spoilerText : contentText,
|
||||
intl.formatDate(status.get('created_at'), { hour: '2-digit', minute: '2-digit', month: 'short', day: 'numeric' }),
|
||||
status.getIn(['account', 'acct']),
|
||||
];
|
||||
|
||||
if (rebloggedByText) {
|
||||
values.push(rebloggedByText);
|
||||
}
|
||||
|
||||
return values.join(', ');
|
||||
};
|
||||
|
||||
export const defaultMediaVisibility = (status) => {
|
||||
if (!status) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') {
|
||||
status = status.get('reblog');
|
||||
}
|
||||
|
||||
return (displayMedia !== 'hide_all' && !status.get('sensitive') || displayMedia === 'show_all');
|
||||
};
|
||||
|
||||
const messages = defineMessages({
|
||||
limited_short: { id: 'privacy.limited.short', defaultMessage: 'Limited' },
|
||||
edited: { id: 'status.edited', defaultMessage: 'Edited {date}' },
|
||||
});
|
||||
|
||||
class CompactedStatus extends ImmutablePureComponent {
|
||||
|
||||
static contextType = SensitiveMediaContext;
|
||||
|
||||
static propTypes = {
|
||||
status: ImmutablePropTypes.map,
|
||||
account: ImmutablePropTypes.record,
|
||||
previousId: PropTypes.string,
|
||||
nextInReplyToId: PropTypes.string,
|
||||
rootId: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
onReply: PropTypes.func,
|
||||
onFavourite: PropTypes.func,
|
||||
onEmojiReact: PropTypes.func,
|
||||
onUnEmojiReact: PropTypes.func,
|
||||
onReblog: PropTypes.func,
|
||||
onReblogForceModal: PropTypes.func,
|
||||
onDelete: PropTypes.func,
|
||||
onDirect: PropTypes.func,
|
||||
onMention: PropTypes.func,
|
||||
onPin: PropTypes.func,
|
||||
onOpenMedia: PropTypes.func,
|
||||
onOpenVideo: PropTypes.func,
|
||||
onBlock: PropTypes.func,
|
||||
onAddFilter: PropTypes.func,
|
||||
onEmbed: PropTypes.func,
|
||||
onHeightChange: PropTypes.func,
|
||||
onToggleHidden: PropTypes.func,
|
||||
onToggleCollapsed: PropTypes.func,
|
||||
onTranslate: PropTypes.func,
|
||||
onInteractionModal: PropTypes.func,
|
||||
muted: PropTypes.bool,
|
||||
hidden: PropTypes.bool,
|
||||
unread: PropTypes.bool,
|
||||
onMoveUp: PropTypes.func,
|
||||
onMoveDown: PropTypes.func,
|
||||
showThread: PropTypes.bool,
|
||||
getScrollPosition: PropTypes.func,
|
||||
updateScrollBottom: PropTypes.func,
|
||||
cacheMediaWidth: PropTypes.func,
|
||||
cachedMediaWidth: PropTypes.number,
|
||||
scrollKey: PropTypes.string,
|
||||
skipPrepend: PropTypes.bool,
|
||||
deployPictureInPicture: PropTypes.func,
|
||||
unfocusable: PropTypes.bool,
|
||||
pictureInPicture: ImmutablePropTypes.contains({
|
||||
inUse: PropTypes.bool,
|
||||
available: PropTypes.bool,
|
||||
}),
|
||||
withoutEmojiReactions: PropTypes.bool,
|
||||
...WithOptionalRouterPropTypes,
|
||||
};
|
||||
|
||||
// Avoid checking props that are functions (and whose equality will always
|
||||
// evaluate to false. See react-immutable-pure-component for usage.
|
||||
updateOnProps = [
|
||||
'status',
|
||||
'account',
|
||||
'muted',
|
||||
'hidden',
|
||||
'unread',
|
||||
'pictureInPicture',
|
||||
];
|
||||
|
||||
state = {
|
||||
showMedia: defaultMediaVisibility(this.props.status) && !(this.context?.hideMediaByDefault),
|
||||
};
|
||||
|
||||
componentDidUpdate (prevProps) {
|
||||
// This will potentially cause a wasteful redraw, but in most cases `Status` components are used
|
||||
// with a `key` directly depending on their `id`, preventing re-use of the component across
|
||||
// different IDs.
|
||||
// But just in case this does change, reset the state on status change.
|
||||
|
||||
if (this.props.status?.get('id') !== prevProps.status?.get('id')) {
|
||||
this.setState({
|
||||
showMedia: defaultMediaVisibility(this.props.status) && !(this.context?.hideMediaByDefault),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleToggleMediaVisibility = () => {
|
||||
this.setState({ showMedia: !this.state.showMedia });
|
||||
};
|
||||
|
||||
handleClick = e => {
|
||||
if (e && (e.button !== 0 || e.ctrlKey || e.metaKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
this.handleHotkeyOpen();
|
||||
};
|
||||
|
||||
handlePrependAccountClick = e => {
|
||||
this.handleAccountClick(e, false);
|
||||
};
|
||||
|
||||
handleAccountClick = (e, proper = true) => {
|
||||
if (e && (e.button !== 0 || e.ctrlKey || e.metaKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
this._openProfile(proper);
|
||||
};
|
||||
|
||||
handleExpandedToggle = () => {
|
||||
this.props.onToggleHidden(this._properStatus());
|
||||
};
|
||||
|
||||
handleCollapsedToggle = isCollapsed => {
|
||||
this.props.onToggleCollapsed(this._properStatus(), isCollapsed);
|
||||
};
|
||||
|
||||
handleTranslate = () => {
|
||||
this.props.onTranslate(this._properStatus());
|
||||
};
|
||||
|
||||
getAttachmentAspectRatio () {
|
||||
const attachments = this._properStatus().get('media_attachments');
|
||||
|
||||
if (attachments.getIn([0, 'type']) === 'video') {
|
||||
return `${attachments.getIn([0, 'meta', 'original', 'width'])} / ${attachments.getIn([0, 'meta', 'original', 'height'])}`;
|
||||
} else if (attachments.getIn([0, 'type']) === 'audio') {
|
||||
return '16 / 9';
|
||||
} else {
|
||||
return (attachments.size === 1 && attachments.getIn([0, 'meta', 'small', 'aspect'])) ? attachments.getIn([0, 'meta', 'small', 'aspect']) : '3 / 2';
|
||||
}
|
||||
}
|
||||
|
||||
renderLoadingMediaGallery = () => {
|
||||
return (
|
||||
<div className='media-gallery' style={{ aspectRatio: this.getAttachmentAspectRatio() }} />
|
||||
);
|
||||
};
|
||||
|
||||
renderLoadingVideoPlayer = () => {
|
||||
return (
|
||||
<div className='video-player' style={{ aspectRatio: this.getAttachmentAspectRatio() }} />
|
||||
);
|
||||
};
|
||||
|
||||
renderLoadingAudioPlayer = () => {
|
||||
return (
|
||||
<div className='audio-player' style={{ aspectRatio: this.getAttachmentAspectRatio() }} />
|
||||
);
|
||||
};
|
||||
|
||||
handleOpenVideo = (options) => {
|
||||
const status = this._properStatus();
|
||||
const lang = status.getIn(['translation', 'language']) || status.get('language');
|
||||
this.props.onOpenVideo(status.get('id'), status.getIn(['media_attachments', 0]), lang, options);
|
||||
};
|
||||
|
||||
handleOpenMedia = (media, index) => {
|
||||
const status = this._properStatus();
|
||||
const lang = status.getIn(['translation', 'language']) || status.get('language');
|
||||
this.props.onOpenMedia(status.get('id'), media, index, lang);
|
||||
};
|
||||
|
||||
handleHotkeyOpenMedia = e => {
|
||||
const { onOpenMedia, onOpenVideo } = this.props;
|
||||
const status = this._properStatus();
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
if (status.get('media_attachments').size > 0) {
|
||||
const lang = status.getIn(['translation', 'language']) || status.get('language');
|
||||
if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
||||
onOpenVideo(status.get('id'), status.getIn(['media_attachments', 0]), lang, { startTime: 0 });
|
||||
} else {
|
||||
onOpenMedia(status.get('id'), status.get('media_attachments'), 0, lang);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleDeployPictureInPicture = (type, mediaProps) => {
|
||||
const { deployPictureInPicture } = this.props;
|
||||
const status = this._properStatus();
|
||||
|
||||
deployPictureInPicture(status, type, mediaProps);
|
||||
};
|
||||
|
||||
handleHotkeyReply = e => {
|
||||
e.preventDefault();
|
||||
this.props.onReply(this._properStatus());
|
||||
};
|
||||
|
||||
handleHotkeyFavourite = () => {
|
||||
this.props.onFavourite(this._properStatus());
|
||||
};
|
||||
|
||||
handleHotkeyBoost = e => {
|
||||
this.props.onReblog(this._properStatus(), e);
|
||||
};
|
||||
|
||||
handleHotkeyMention = e => {
|
||||
e.preventDefault();
|
||||
this.props.onMention(this._properStatus().get('account'));
|
||||
};
|
||||
|
||||
handleHotkeyOpen = () => {
|
||||
if (this.props.onClick) {
|
||||
this.props.onClick();
|
||||
return;
|
||||
}
|
||||
|
||||
const { history } = this.props;
|
||||
const status = this._properStatus();
|
||||
|
||||
if (!history) {
|
||||
return;
|
||||
}
|
||||
|
||||
history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`);
|
||||
};
|
||||
|
||||
handleHotkeyOpenProfile = () => {
|
||||
this._openProfile();
|
||||
};
|
||||
|
||||
_openProfile = (proper = true) => {
|
||||
const { history } = this.props;
|
||||
const status = proper ? this._properStatus() : this.props.status;
|
||||
|
||||
if (!history) {
|
||||
return;
|
||||
}
|
||||
|
||||
history.push(`/@${status.getIn(['account', 'acct'])}`);
|
||||
};
|
||||
|
||||
handleHotkeyMoveUp = e => {
|
||||
this.props.onMoveUp(this.props.status.get('id'), e.target.getAttribute('data-featured'));
|
||||
};
|
||||
|
||||
handleHotkeyMoveDown = e => {
|
||||
this.props.onMoveDown(this.props.status.get('id'), e.target.getAttribute('data-featured'));
|
||||
};
|
||||
|
||||
handleHotkeyToggleHidden = () => {
|
||||
const { onToggleHidden } = this.props;
|
||||
const status = this._properStatus();
|
||||
|
||||
onToggleHidden(status);
|
||||
};
|
||||
|
||||
handleHotkeyToggleSensitive = () => {
|
||||
this.handleToggleMediaVisibility();
|
||||
};
|
||||
|
||||
_properStatus () {
|
||||
const { status } = this.props;
|
||||
|
||||
if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') {
|
||||
return status.get('reblog');
|
||||
} else {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
handleRef = c => {
|
||||
this.node = c;
|
||||
};
|
||||
|
||||
render () {
|
||||
const { intl, hidden, featured, unfocusable, unread, showThread, pictureInPicture, previousId, nextInReplyToId, rootId, skipPrepend } = this.props;
|
||||
|
||||
let { status } = this.props;
|
||||
|
||||
if (status === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const handlers = this.props.muted ? {} : {
|
||||
reply: this.handleHotkeyReply,
|
||||
favourite: this.handleHotkeyFavourite,
|
||||
boost: this.handleHotkeyBoost,
|
||||
mention: this.handleHotkeyMention,
|
||||
open: this.handleHotkeyOpen,
|
||||
openProfile: this.handleHotkeyOpenProfile,
|
||||
moveUp: this.handleHotkeyMoveUp,
|
||||
moveDown: this.handleHotkeyMoveDown,
|
||||
toggleHidden: this.handleHotkeyToggleHidden,
|
||||
toggleSensitive: this.handleHotkeyToggleSensitive,
|
||||
openMedia: this.handleHotkeyOpenMedia,
|
||||
};
|
||||
|
||||
let media, prepend, rebloggedByText;
|
||||
|
||||
if (hidden) {
|
||||
return (
|
||||
<HotKeys handlers={handlers} tabIndex={unfocusable ? null : -1}>
|
||||
<div ref={this.handleRef} className={classNames('status__wrapper', { focusable: !this.props.muted })} tabIndex={unfocusable ? null : 0}>
|
||||
<span>{status.getIn(['account', 'display_name']) || status.getIn(['account', 'username'])}</span>
|
||||
<span>{status.get('content')}</span>
|
||||
</div>
|
||||
</HotKeys>
|
||||
);
|
||||
}
|
||||
|
||||
const connectUp = previousId && previousId === status.get('in_reply_to_id');
|
||||
const connectToRoot = rootId && rootId === status.get('in_reply_to_id');
|
||||
const connectReply = nextInReplyToId && nextInReplyToId === status.get('id');
|
||||
|
||||
let visibilityName = status.get('limited_scope') || status.get('visibility_ex') || status.get('visibility');
|
||||
|
||||
if (featured) {
|
||||
prepend = (
|
||||
<div className='status__prepend'>
|
||||
<div className='status__prepend-icon-wrapper'><Icon id='thumb-tack' icon={PushPinIcon} className='status__prepend-icon' /></div>
|
||||
<FormattedMessage id='status.pinned' defaultMessage='Pinned post' />
|
||||
</div>
|
||||
);
|
||||
} else if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') {
|
||||
const display_name_html = { __html: status.getIn(['account', 'display_name_html']) };
|
||||
|
||||
prepend = (
|
||||
<div className='status__prepend'>
|
||||
<div className='status__prepend-icon-wrapper'><Icon id='retweet' icon={RepeatIcon} className='status__prepend-icon' /></div>
|
||||
<div className='status__prepend-icon-wrapper'><VisibilityIcon visibility={visibilityName} className='status__prepend-icon' /></div>
|
||||
<FormattedMessage id='status.reblogged_by' defaultMessage='{name} boosted' values={{ name: <a onClick={this.handlePrependAccountClick} data-id={status.getIn(['account', 'id'])} data-hover-card-account={status.getIn(['account', 'id'])} href={`/@${status.getIn(['account', 'acct'])}`} className='status__display-name muted'><bdi><strong dangerouslySetInnerHTML={display_name_html} /></bdi></a> }} />
|
||||
</div>
|
||||
);
|
||||
|
||||
rebloggedByText = intl.formatMessage({ id: 'status.reblogged_by', defaultMessage: '{name} boosted' }, { name: status.getIn(['account', 'acct']) });
|
||||
|
||||
status = status.get('reblog');
|
||||
} else if (status.get('visibility') === 'direct') {
|
||||
prepend = (
|
||||
<div className='status__prepend'>
|
||||
<div className='status__prepend-icon-wrapper'><Icon id='at' icon={AlternateEmailIcon} className='status__prepend-icon' /></div>
|
||||
<FormattedMessage id='status.direct_indicator' defaultMessage='Private mention' />
|
||||
</div>
|
||||
);
|
||||
} else if (showThread && status.get('in_reply_to_id') && status.get('in_reply_to_account_id') === status.getIn(['account', 'id'])) {
|
||||
const display_name_html = { __html: status.getIn(['account', 'display_name_html']) };
|
||||
|
||||
prepend = (
|
||||
<div className='status__prepend'>
|
||||
<div className='status__prepend-icon-wrapper'><Icon id='reply' icon={ReplyIcon} className='status__prepend-icon' /></div>
|
||||
<FormattedMessage id='status.replied_to' defaultMessage='Replied to {name}' values={{ name: <a onClick={this.handlePrependAccountClick} data-id={status.getIn(['account', 'id'])} data-hover-card-account={status.getIn(['account', 'id'])} href={`/@${status.getIn(['account', 'acct'])}`} className='status__display-name muted'><bdi><strong dangerouslySetInnerHTML={display_name_html} /></bdi></a> }} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (pictureInPicture.get('inUse')) {
|
||||
media = <PictureInPicturePlaceholder aspectRatio={this.getAttachmentAspectRatio()} />;
|
||||
} else if (status.get('media_attachments').size > 0) {
|
||||
const language = status.getIn(['translation', 'language']) || status.get('language');
|
||||
|
||||
if (this.props.muted) {
|
||||
media = (
|
||||
<AttachmentList
|
||||
compact
|
||||
media={status.get('media_attachments')}
|
||||
/>
|
||||
);
|
||||
} else if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
|
||||
const attachment = status.getIn(['media_attachments', 0]);
|
||||
const description = attachment.getIn(['translation', 'description']) || attachment.get('description');
|
||||
|
||||
media = (
|
||||
<Bundle fetchComponent={Audio} loading={this.renderLoadingAudioPlayer} >
|
||||
{Component => (
|
||||
<Component
|
||||
src={attachment.get('url')}
|
||||
alt={description}
|
||||
lang={language}
|
||||
poster={attachment.get('preview_url') || status.getIn(['account', 'avatar_static'])}
|
||||
backgroundColor={attachment.getIn(['meta', 'colors', 'background'])}
|
||||
foregroundColor={attachment.getIn(['meta', 'colors', 'foreground'])}
|
||||
accentColor={attachment.getIn(['meta', 'colors', 'accent'])}
|
||||
duration={attachment.getIn(['meta', 'original', 'duration'], 0)}
|
||||
width={this.props.cachedMediaWidth}
|
||||
height={110}
|
||||
cacheWidth={this.props.cacheMediaWidth}
|
||||
deployPictureInPicture={pictureInPicture.get('available') ? this.handleDeployPictureInPicture : undefined}
|
||||
sensitive={status.get('sensitive')}
|
||||
blurhash={attachment.get('blurhash')}
|
||||
visible={this.state.showMedia}
|
||||
onToggleVisibility={this.handleToggleMediaVisibility}
|
||||
/>
|
||||
)}
|
||||
</Bundle>
|
||||
);
|
||||
} else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
||||
const attachment = status.getIn(['media_attachments', 0]);
|
||||
const description = attachment.getIn(['translation', 'description']) || attachment.get('description');
|
||||
|
||||
media = (
|
||||
<Bundle fetchComponent={Video} loading={this.renderLoadingVideoPlayer} >
|
||||
{Component => (
|
||||
<Component
|
||||
preview={attachment.get('preview_url')}
|
||||
frameRate={attachment.getIn(['meta', 'original', 'frame_rate'])}
|
||||
aspectRatio={`${attachment.getIn(['meta', 'original', 'width'])} / ${attachment.getIn(['meta', 'original', 'height'])}`}
|
||||
blurhash={attachment.get('blurhash')}
|
||||
src={attachment.get('url')}
|
||||
alt={description}
|
||||
lang={language}
|
||||
sensitive={status.get('sensitive')}
|
||||
onOpenVideo={this.handleOpenVideo}
|
||||
deployPictureInPicture={pictureInPicture.get('available') ? this.handleDeployPictureInPicture : undefined}
|
||||
visible={this.state.showMedia}
|
||||
onToggleVisibility={this.handleToggleMediaVisibility}
|
||||
/>
|
||||
)}
|
||||
</Bundle>
|
||||
);
|
||||
} else {
|
||||
media = (
|
||||
<Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery}>
|
||||
{Component => (
|
||||
<Component
|
||||
media={status.get('media_attachments')}
|
||||
lang={language}
|
||||
sensitive={status.get('sensitive')}
|
||||
height={110}
|
||||
onOpenMedia={this.handleOpenMedia}
|
||||
cacheWidth={this.props.cacheMediaWidth}
|
||||
defaultWidth={this.props.cachedMediaWidth}
|
||||
visible={this.state.showMedia}
|
||||
onToggleVisibility={this.handleToggleMediaVisibility}
|
||||
/>
|
||||
)}
|
||||
</Bundle>
|
||||
);
|
||||
}
|
||||
} else if (status.get('card') && !this.props.muted) {
|
||||
media = (
|
||||
<Card
|
||||
onOpenMedia={this.handleOpenMedia}
|
||||
card={status.get('card')}
|
||||
compact
|
||||
sensitive={status.get('sensitive') && !status.get('spoiler_text')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
visibilityName = status.get('limited_scope') || status.get('visibility_ex') || status.get('visibility');
|
||||
|
||||
const {statusContentProps, hashtagBar} = getHashtagBarForStatus(status);
|
||||
const expanded = !status.get('hidden') || status.get('spoiler_text').length === 0;
|
||||
|
||||
return (
|
||||
<HotKeys handlers={handlers} tabIndex={unfocusable ? null : -1}>
|
||||
<div className={classNames('status__wrapper', 'status__wrapper__compact', 'content-warning', 'content-warning--compacted-status', `status__wrapper-${status.get('visibility_ex')}`, { 'status__wrapper-reply': !!status.get('in_reply_to_id'), unread, focusable: !this.props.muted })} tabIndex={this.props.muted || unfocusable ? null : 0} data-featured={featured ? 'true' : null} aria-label={textForScreenReader(intl, status, rebloggedByText)} ref={this.handleRef} data-nosnippet={status.getIn(['account', 'noindex'], true) || undefined}>
|
||||
{!skipPrepend && prepend}
|
||||
|
||||
<div className={classNames('status', `status-${status.get('visibility_ex')}`, { 'status-reply': !!status.get('in_reply_to_id'), 'status--in-thread': !!rootId, 'status--first-in-thread': previousId && (!connectUp || connectToRoot), muted: this.props.muted })} data-id={status.get('id')}>
|
||||
|
||||
{(connectReply || connectUp || connectToRoot) && <div className={classNames('status__line', { 'status__line--full': connectReply, 'status__line--first': !status.get('in_reply_to_id') && !connectToRoot })} />}
|
||||
|
||||
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
|
||||
<div onClick={this.handleClick} className='status__info'>
|
||||
<a href={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
|
||||
<span className='status__visibility-icon'><VisibilityIcon visibility={visibilityName} /></span>
|
||||
<RelativeTimestamp timestamp={status.get('created_at')} />{status.get('edited_at') && <abbr title={intl.formatMessage(messages.edited, { date: intl.formatDate(status.get('edited_at'), { year: 'numeric', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }) })}> *</abbr>}
|
||||
</a>
|
||||
|
||||
<a onClick={this.handleAccountClick} href={`/@${status.getIn(['account', 'acct'])}`} title={status.getIn(['account', 'acct'])} data-hover-card-account={status.getIn(['account', 'id'])} className='status__display-name' target='_blank' rel='noopener noreferrer'>
|
||||
<div className='status__avatar__compact'>
|
||||
<Avatar account={status.get('account')} size={32} inline />
|
||||
</div>
|
||||
|
||||
<DisplayName account={status.get('account')} />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{status.get('spoiler_text').length > 0 && <ContentWarning text={status.getIn(['translation', 'spoilerHtml']) || status.get('spoilerHtml')} expanded={expanded} onClick={this.handleExpandedToggle} />}
|
||||
|
||||
{expanded && (
|
||||
<>
|
||||
<StatusContent
|
||||
status={status}
|
||||
onClick={this.handleClick}
|
||||
onTranslate={this.handleTranslate}
|
||||
collapsible
|
||||
onCollapsedToggle={this.handleCollapsedToggle}
|
||||
{...statusContentProps}
|
||||
/>
|
||||
|
||||
{media}
|
||||
{hashtagBar}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</HotKeys>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default withOptionalRouter(injectIntl(CompactedStatus));
|
|
@ -12,7 +12,6 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
|||
import { HotKeys } from 'react-hotkeys';
|
||||
|
||||
import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react';
|
||||
import QuoteIcon from '@/material-icons/400-24px/format_quote.svg?react';
|
||||
import ReferenceIcon from '@/material-icons/400-24px/link.svg?react';
|
||||
import PushPinIcon from '@/material-icons/400-24px/push_pin.svg?react';
|
||||
import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react';
|
||||
|
@ -25,7 +24,6 @@ import { Icon } from 'mastodon/components/icon';
|
|||
import PictureInPicturePlaceholder from 'mastodon/components/picture_in_picture_placeholder';
|
||||
import { withOptionalRouter, WithOptionalRouterPropTypes } from 'mastodon/utils/react_router';
|
||||
|
||||
import CompactedStatusContainer from '../containers/compacted_status_container';
|
||||
import Card from '../features/status/components/card';
|
||||
// We use the component (and not the container) since we do not want
|
||||
// to use the progress bar to show download progress
|
||||
|
@ -136,7 +134,6 @@ class Status extends ImmutablePureComponent {
|
|||
available: PropTypes.bool,
|
||||
}),
|
||||
withoutEmojiReactions: PropTypes.bool,
|
||||
withoutQuote: PropTypes.bool,
|
||||
...WithOptionalRouterPropTypes,
|
||||
};
|
||||
|
||||
|
@ -382,7 +379,7 @@ class Status extends ImmutablePureComponent {
|
|||
};
|
||||
|
||||
render () {
|
||||
const { intl, hidden, featured, unfocusable, unread, showThread, scrollKey, pictureInPicture, previousId, rootId, withoutQuote, skipPrepend, avatarSize = 46 } = this.props;
|
||||
const { intl, hidden, featured, unfocusable, unread, showThread, scrollKey, pictureInPicture, previousId, rootId, skipPrepend, avatarSize = 46 } = this.props;
|
||||
|
||||
let { status, account, ...other } = this.props;
|
||||
|
||||
|
@ -582,12 +579,9 @@ class Status extends ImmutablePureComponent {
|
|||
const {statusContentProps, hashtagBar} = getHashtagBarForStatus(status);
|
||||
|
||||
const withLimited = status.get('visibility_ex') === 'limited' && status.get('limited_scope') ? <span className='status__visibility-icon'><Icon id='get-pocket' icon={LimitedIcon} title={intl.formatMessage(messages.limited_short)} /></span> : null;
|
||||
const withQuote = status.get('quote_id') ? <span className='status__visibility-icon'><Icon id='quote-right' icon={QuoteIcon} title='Quote' /></span> : null;
|
||||
const withReference = (!withQuote && status.get('status_references_count') > 0) ? <span className='status__visibility-icon'><Icon id='link' icon={ReferenceIcon} title='Quiet quote' /></span> : null;
|
||||
const withReference = status.get('status_references_count') > 0 ? <span className='status__visibility-icon'><Icon id='link' icon={ReferenceIcon} title='Link' /></span> : null;
|
||||
const withExpiration = status.get('expires_at') ? <span className='status__visibility-icon'><Icon id='clock-o' icon={TimerIcon} title='Expiration' /></span> : null;
|
||||
|
||||
const quote = !this.props.muted && !withoutQuote && status.get('quote_id') && (['public', 'community'].includes(contextType) ? isShowItem('quote_in_public') : isShowItem('quote_in_home')) && <CompactedStatusContainer id={status.get('quote_id')} history={this.props.history} />;
|
||||
|
||||
return (
|
||||
<HotKeys handlers={handlers} tabIndex={unfocusable ? null : -1}>
|
||||
<div className={classNames('status__wrapper', `status__wrapper-${status.get('visibility_ex')}`, { 'status__wrapper-reply': !!status.get('in_reply_to_id'), unread, focusable: !this.props.muted })} tabIndex={this.props.muted || unfocusable ? null : 0} data-featured={featured ? 'true' : null} aria-label={textForScreenReader(intl, status, rebloggedByText)} ref={this.handleRef} data-nosnippet={status.getIn(['account', 'noindex'], true) || undefined}>
|
||||
|
@ -598,7 +592,6 @@ class Status extends ImmutablePureComponent {
|
|||
{(!matchedFilters || expanded || isShowItem('avatar_on_filter')) && (
|
||||
<div onMouseUp={this.handleMouseUp} className='status__info'>
|
||||
<Link to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`} className='status__relative-time'>
|
||||
{withQuote}
|
||||
{withReference}
|
||||
{withExpiration}
|
||||
{withLimited}
|
||||
|
@ -633,7 +626,6 @@ class Status extends ImmutablePureComponent {
|
|||
|
||||
{media}
|
||||
{hashtagBar}
|
||||
{quote}
|
||||
{emojiReactionsBar}
|
||||
</>
|
||||
)}
|
||||
|
|
|
@ -68,8 +68,7 @@ const messages = defineMessages({
|
|||
admin_status: { id: 'status.admin_status', defaultMessage: 'Open this post in the moderation interface' },
|
||||
admin_domain: { id: 'status.admin_domain', defaultMessage: 'Open moderation interface for {domain}' },
|
||||
copy: { id: 'status.copy', defaultMessage: 'Copy link to post' },
|
||||
reference: { id: 'status.reference', defaultMessage: 'Quiet quote' },
|
||||
quote: { id: 'status.quote', defaultMessage: 'Quote' },
|
||||
reference: { id: 'status.reference', defaultMessage: 'Link' },
|
||||
blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
|
||||
unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
|
||||
unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
|
||||
|
@ -110,7 +109,6 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
onFilter: PropTypes.func,
|
||||
onAddFilter: PropTypes.func,
|
||||
onReference: PropTypes.func,
|
||||
onQuote: PropTypes.func,
|
||||
onInteractionModal: PropTypes.func,
|
||||
withDismiss: PropTypes.bool,
|
||||
withCounters: PropTypes.bool,
|
||||
|
@ -288,10 +286,6 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
this.props.onReference(this.props.status, this.props.history);
|
||||
};
|
||||
|
||||
handleQuote = () => {
|
||||
this.props.onQuote(this.props.status, this.props.history);
|
||||
};
|
||||
|
||||
render () {
|
||||
const { status, relationship, intl, withDismiss, withCounters, scrollKey } = this.props;
|
||||
const { signedIn, permissions } = this.props.identity;
|
||||
|
@ -303,7 +297,6 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
const account = status.get('account');
|
||||
const writtenByMe = status.getIn(['account', 'id']) === me;
|
||||
const isRemote = status.getIn(['account', 'username']) !== status.getIn(['account', 'acct']);
|
||||
const allowQuote = status.getIn(['account', 'other_settings', 'allow_quote']);
|
||||
|
||||
let menu = [];
|
||||
|
||||
|
@ -335,10 +328,6 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
if (!boostMenu) {
|
||||
if (publicStatus && allowQuote && (account.getIn(['server_features', 'quote']) || !isHideItem('quote_unavailable_server'))) {
|
||||
menu.push({ text: intl.formatMessage(messages.quote), action: this.handleQuote, tag: 'reblog' });
|
||||
}
|
||||
|
||||
if (account.getIn(['server_features', 'status_reference']) || !isHideItem('status_reference_unavailable_server')) {
|
||||
menu.push({ text: intl.formatMessage(messages.reference), action: this.handleReference, tag: 'reblog' });
|
||||
}
|
||||
|
@ -423,10 +412,6 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
if (publicStatus) {
|
||||
if (allowQuote && (account.getIn(['server_features', 'quote']) || !isHideItem('quote_unavailable_server'))) {
|
||||
reblogMenu.push({ text: intl.formatMessage(messages.quote), action: this.handleQuote });
|
||||
}
|
||||
|
||||
if (account.getIn(['server_features', 'status_reference']) || !isHideItem('status_reference_unavailable_server')) {
|
||||
reblogMenu.push({ text: intl.formatMessage(messages.reference), action: this.handleReference });
|
||||
}
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
import { injectIntl } from 'react-intl';
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { openModal } from '../actions/modal';
|
||||
import {
|
||||
hideStatus,
|
||||
revealStatus,
|
||||
toggleStatusCollapse,
|
||||
translateStatus,
|
||||
undoStatusTranslation,
|
||||
} from '../actions/statuses';
|
||||
import CompactedStatus from '../components/compacted_status';
|
||||
import { makeGetStatus, makeGetPictureInPicture } from '../selectors';
|
||||
|
||||
const makeMapStateToProps = () => {
|
||||
const getStatus = makeGetStatus();
|
||||
const getPictureInPicture = makeGetPictureInPicture();
|
||||
|
||||
const mapStateToProps = (state, props) => ({
|
||||
status: getStatus(state, props),
|
||||
nextInReplyToId: props.nextId ? state.getIn(['statuses', props.nextId, 'in_reply_to_id']) : null,
|
||||
pictureInPicture: getPictureInPicture(state, props),
|
||||
});
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
|
||||
onTranslate (status) {
|
||||
if (status.get('translation')) {
|
||||
dispatch(undoStatusTranslation(status.get('id'), status.get('poll')));
|
||||
} else {
|
||||
dispatch(translateStatus(status.get('id')));
|
||||
}
|
||||
},
|
||||
|
||||
onOpenMedia (statusId, media, index, lang) {
|
||||
dispatch(openModal({
|
||||
modalType: 'MEDIA',
|
||||
modalProps: { statusId, media, index, lang },
|
||||
}));
|
||||
},
|
||||
|
||||
onOpenVideo (statusId, media, lang, options) {
|
||||
dispatch(openModal({
|
||||
modalType: 'VIDEO',
|
||||
modalProps: { statusId, media, lang, options },
|
||||
}));
|
||||
},
|
||||
|
||||
onToggleHidden (status) {
|
||||
if (status.get('hidden')) {
|
||||
dispatch(revealStatus(status.get('id')));
|
||||
} else {
|
||||
dispatch(hideStatus(status.get('id')));
|
||||
}
|
||||
},
|
||||
|
||||
onToggleCollapsed (status, isCollapsed) {
|
||||
dispatch(toggleStatusCollapse(status.get('id'), isCollapsed));
|
||||
},
|
||||
|
||||
onInteractionModal (type, status) {
|
||||
dispatch(openModal({
|
||||
modalType: 'INTERACTION',
|
||||
modalProps: {
|
||||
type,
|
||||
accountId: status.getIn(['account', 'id']),
|
||||
url: status.get('uri'),
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(CompactedStatus));
|
|
@ -152,10 +152,6 @@ const mapDispatchToProps = (dispatch, { contextType }) => ({
|
|||
dispatch(insertReferenceCompose(0, status.get('url'), 'BT', router));
|
||||
},
|
||||
|
||||
onQuote (status, router) {
|
||||
dispatch(insertReferenceCompose(0, status.get('url'), 'QT', router));
|
||||
},
|
||||
|
||||
onTranslate (status) {
|
||||
if (status.get('translation')) {
|
||||
dispatch(undoStatusTranslation(status.get('id'), status.get('poll')));
|
||||
|
|
|
@ -164,7 +164,7 @@ class ColumnSettings extends PureComponent {
|
|||
|
||||
<section>
|
||||
<div role='group' aria-labelledby='notifications-status_reference'>
|
||||
<h3 id='notifications-status_reference'><FormattedMessage id='notifications.column_settings.status_reference' defaultMessage='Quotes:' /></h3>
|
||||
<h3 id='notifications-status_reference'><FormattedMessage id='notifications.column_settings.status_reference' defaultMessage='Links:' /></h3>
|
||||
|
||||
<div className='column-settings__row'>
|
||||
<SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'status_reference']} onChange={onChange} label={alertStr} />
|
||||
|
|
|
@ -42,7 +42,7 @@ const messages = defineMessages({
|
|||
reblog: { id: 'notification.reblog', defaultMessage: '{name} boosted your post' },
|
||||
status: { id: 'notification.status', defaultMessage: '{name} just posted' },
|
||||
listStatus: { id: 'notification.list_status', defaultMessage: '{name} post is added to {listName}' },
|
||||
statusReference: { id: 'notification.status_reference', defaultMessage: '{name} quoted your post' },
|
||||
statusReference: { id: 'notification.status_reference', defaultMessage: '{name} linked your post' },
|
||||
update: { id: 'notification.update', defaultMessage: '{name} edited a post' },
|
||||
adminSignUp: { id: 'notification.admin.sign_up', defaultMessage: '{name} signed up' },
|
||||
adminReport: { id: 'notification.admin.report', defaultMessage: '{name} reported {target}' },
|
||||
|
@ -305,7 +305,7 @@ class Notification extends ImmutablePureComponent {
|
|||
</div>
|
||||
|
||||
<span title={notification.get('created_at')}>
|
||||
<FormattedMessage id='notification.status_reference' defaultMessage='{name} quoted your post' values={{ name: link }} />
|
||||
<FormattedMessage id='notification.status_reference' defaultMessage='{name} linked your post' values={{ name: link }} />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import { NotificationWithStatus } from './notification_with_status';
|
|||
const labelRenderer: LabelRenderer = (displayedName) => (
|
||||
<FormattedMessage
|
||||
id='notification.status_reference'
|
||||
defaultMessage='{name} quoted your post'
|
||||
defaultMessage='{name} linked your post'
|
||||
values={{ name: displayedName }}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -64,8 +64,7 @@ const messages = defineMessages({
|
|||
admin_status: { id: 'status.admin_status', defaultMessage: 'Open this post in the moderation interface' },
|
||||
admin_domain: { id: 'status.admin_domain', defaultMessage: 'Open moderation interface for {domain}' },
|
||||
copy: { id: 'status.copy', defaultMessage: 'Copy link to post' },
|
||||
reference: { id: 'status.reference', defaultMessage: 'Quiet quote' },
|
||||
quote: { id: 'status.quote', defaultMessage: 'Quote' },
|
||||
reference: { id: 'status.reference', defaultMessage: 'Link' },
|
||||
blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
|
||||
unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
|
||||
unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
|
||||
|
@ -89,7 +88,6 @@ class ActionBar extends PureComponent {
|
|||
onFavourite: PropTypes.func.isRequired,
|
||||
onEmojiReact: PropTypes.func.isRequired,
|
||||
onReference: PropTypes.func.isRequired,
|
||||
onQuote: PropTypes.func.isRequired,
|
||||
onBookmark: PropTypes.func.isRequired,
|
||||
onBookmarkCategoryAdder: PropTypes.func.isRequired,
|
||||
onDelete: PropTypes.func.isRequired,
|
||||
|
@ -225,10 +223,6 @@ class ActionBar extends PureComponent {
|
|||
this.props.onReference(this.props.status, this.props.history);
|
||||
};
|
||||
|
||||
handleQuote = () => {
|
||||
this.props.onQuote(this.props.status, this.props.history);
|
||||
};
|
||||
|
||||
handleEmojiPick = (data) => {
|
||||
this.props.onEmojiReact(this.props.status, data);
|
||||
};
|
||||
|
@ -244,7 +238,6 @@ class ActionBar extends PureComponent {
|
|||
const account = status.get('account');
|
||||
const writtenByMe = status.getIn(['account', 'id']) === me;
|
||||
const isRemote = status.getIn(['account', 'username']) !== status.getIn(['account', 'acct']);
|
||||
const allowQuote = status.getIn(['account', 'other_settings', 'allow_quote']);
|
||||
|
||||
let menu = [];
|
||||
|
||||
|
@ -269,10 +262,6 @@ class ActionBar extends PureComponent {
|
|||
menu.push({ text: intl.formatMessage(status.get('reblogged') ? messages.cancel_reblog : messages.reblog), action: this.handleReblogForceModalClick, tag: 'reblog' });
|
||||
|
||||
if (publicStatus) {
|
||||
if (allowQuote && (account.getIn(['server_features', 'quote']) || !isHideItem('quote_unavailable_server'))) {
|
||||
menu.push({ text: intl.formatMessage(messages.quote), action: this.handleQuote, tag: 'reblog' });
|
||||
}
|
||||
|
||||
if (account.getIn(['server_features', 'status_reference']) || !isHideItem('status_reference_unavailable_server')) {
|
||||
menu.push({ text: intl.formatMessage(messages.reference), action: this.handleReference, tag: 'reblog' });
|
||||
}
|
||||
|
@ -350,10 +339,6 @@ class ActionBar extends PureComponent {
|
|||
}
|
||||
|
||||
if (publicStatus) {
|
||||
if (allowQuote && (account.getIn(['server_features', 'quote']) || !isHideItem('quote_unavailable_server'))) {
|
||||
reblogMenu.push({ text: intl.formatMessage(messages.quote), action: this.handleQuote });
|
||||
}
|
||||
|
||||
if (account.getIn(['server_features', 'status_reference']) || !isHideItem('status_reference_unavailable_server')) {
|
||||
reblogMenu.push({ text: intl.formatMessage(messages.reference), action: this.handleReference });
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ import { DisplayName } from '../../../components/display_name';
|
|||
import MediaGallery from '../../../components/media_gallery';
|
||||
import StatusContent from '../../../components/status_content';
|
||||
import StatusEmojiReactionsBar from '../../../components/status_emoji_reactions_bar';
|
||||
import CompactedStatusContainer from '../../../containers/compacted_status_container';
|
||||
import Audio from '../../audio';
|
||||
import scheduleIdleTask from '../../ui/util/schedule_idle_task';
|
||||
|
||||
|
@ -77,7 +76,6 @@ export const DetailedStatus: React.FC<{
|
|||
onToggleHidden,
|
||||
onEmojiReact,
|
||||
onUnEmojiReact,
|
||||
muted,
|
||||
}) => {
|
||||
const properStatus = status?.get('reblog') ?? status;
|
||||
const [height, setHeight] = useState(0);
|
||||
|
@ -330,7 +328,7 @@ export const DetailedStatus: React.FC<{
|
|||
<AnimatedNumber value={status.get('status_referred_by_count')} />
|
||||
</span>
|
||||
<FormattedMessage
|
||||
id='status.quotes'
|
||||
id='status.references'
|
||||
defaultMessage='{count, plural, one {boost} other {boosts}}'
|
||||
values={{ count: status.get('status_referred_by_count') }}
|
||||
/>
|
||||
|
@ -383,13 +381,6 @@ export const DetailedStatus: React.FC<{
|
|||
(!matchedFilters || showDespiteFilter) &&
|
||||
(!status.get('hidden') || status.get('spoiler_text').length === 0);
|
||||
|
||||
const quote = !muted && status.get('quote_id') && (
|
||||
<>
|
||||
{/* @ts-expect-error: CompactedStatusContainer class is not typescript still. */}
|
||||
<CompactedStatusContainer id={status.get('quote_id')} history={history} />
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<div style={outerStyle}>
|
||||
<div ref={handleRef} className={classNames('detailed-status')}>
|
||||
|
@ -459,7 +450,6 @@ export const DetailedStatus: React.FC<{
|
|||
|
||||
{media}
|
||||
{hashtagBar}
|
||||
{quote}
|
||||
{emojiReactionsBar}
|
||||
</>
|
||||
)}
|
||||
|
|
|
@ -156,7 +156,7 @@ const makeMapStateToProps = () => {
|
|||
if (status) {
|
||||
ancestorsIds = getAncestorsIds(state, { id: status.get('in_reply_to_id') });
|
||||
descendantsIds = getDescendantsIds(state, { id: status.get('id') });
|
||||
referenceIds = getReferenceIds(state, { id: status.get('id') }).filter((id) => id !== status.get('quote_id'));
|
||||
referenceIds = getReferenceIds(state, { id: status.get('id') });
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -341,10 +341,6 @@ class Status extends ImmutablePureComponent {
|
|||
this.props.dispatch(insertReferenceCompose(0, status.get('url'), 'BT', router));
|
||||
};
|
||||
|
||||
handleQuote = (status, router) => {
|
||||
this.props.dispatch(insertReferenceCompose(0, status.get('url'), 'QT', router));
|
||||
};
|
||||
|
||||
handleBookmarkClick = (status) => {
|
||||
if (bookmarkCategoryNeeded) {
|
||||
this.handleBookmarkCategoryAdderClick(status);
|
||||
|
@ -774,7 +770,6 @@ class Status extends ImmutablePureComponent {
|
|||
onReblog={this.handleReblogClick}
|
||||
onReblogForceModal={this.handleReblogForceModalClick}
|
||||
onReference={this.handleReference}
|
||||
onQuote={this.handleQuote}
|
||||
onBookmark={this.handleBookmarkClick}
|
||||
onBookmarkCategoryAdder={this.handleBookmarkCategoryAdderClick}
|
||||
onDelete={this.handleDeleteClick}
|
||||
|
|
|
@ -81,7 +81,7 @@ class StatusReferences extends ImmutablePureComponent {
|
|||
bindToDocument={!multiColumn}
|
||||
>
|
||||
{accountIds.map(id =>
|
||||
<StatusContainer key={id} id={id} withNote={false} withoutQuote />,
|
||||
<StatusContainer key={id} id={id} withNote={false} />,
|
||||
)}
|
||||
</ScrollableList>
|
||||
|
||||
|
|
|
@ -2,14 +2,10 @@
|
|||
|
||||
|
||||
/**
|
||||
* @typedef { 'blocking_quote'
|
||||
* | 'emoji_reaction_on_timeline'
|
||||
* @typedef { 'emoji_reaction_on_timeline'
|
||||
* | 'emoji_reaction_unavailable_server'
|
||||
* | 'emoji_reaction_count'
|
||||
* | 'favourite_menu'
|
||||
* | 'quote_in_home'
|
||||
* | 'quote_in_public'
|
||||
* | 'quote_unavailable_server'
|
||||
* | 'recent_emojis'
|
||||
* | 'relationships'
|
||||
* | 'status_reference_unavailable_server'
|
||||
|
|
|
@ -462,7 +462,7 @@
|
|||
"empty_column.notification_requests": "All clear! There is nothing here. When you receive new notifications, they will appear here according to your settings.",
|
||||
"empty_column.notifications": "You don't have any notifications yet. When other people interact with you, you will see it here.",
|
||||
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
|
||||
"empty_column.status_references": "No one has quotes this post yet. When someone does, they will show up here.",
|
||||
"empty_column.status_references": "No one has links this post yet. When someone does, they will show up here.",
|
||||
"error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.",
|
||||
"error.unexpected_crash.explanation_addons": "This page could not be displayed correctly. This error is likely caused by a browser add-on or automatic translation tools.",
|
||||
"error.unexpected_crash.next_steps": "Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.",
|
||||
|
@ -762,7 +762,7 @@
|
|||
"notification.relationships_severance_event.learn_more": "Learn more",
|
||||
"notification.relationships_severance_event.user_domain_block": "You have blocked {target}, removing {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.",
|
||||
"notification.status": "{name} just posted",
|
||||
"notification.status_reference": "{name} quoted your post",
|
||||
"notification.status_reference": "{name} linked your post",
|
||||
"notification.update": "{name} edited a post",
|
||||
"notification_requests.accept": "Accept",
|
||||
"notification_requests.accept_multiple": "{count, plural, one {Accept # request…} other {Accept # requests…}}",
|
||||
|
@ -804,7 +804,7 @@
|
|||
"notifications.column_settings.show": "Show in column",
|
||||
"notifications.column_settings.sound": "Play sound",
|
||||
"notifications.column_settings.status": "New posts:",
|
||||
"notifications.column_settings.status_reference": "Quotes:",
|
||||
"notifications.column_settings.status_reference": "Links:",
|
||||
"notifications.column_settings.unread_notifications.category": "Unread notifications",
|
||||
"notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications",
|
||||
"notifications.column_settings.update": "Edits:",
|
||||
|
@ -815,7 +815,7 @@
|
|||
"notifications.filter.follows": "Follows",
|
||||
"notifications.filter.mentions": "Mentions",
|
||||
"notifications.filter.polls": "Poll results",
|
||||
"notifications.filter.status_references": "Quotes",
|
||||
"notifications.filter.status_references": "Links",
|
||||
"notifications.filter.statuses": "Updates from people you follow",
|
||||
"notifications.grant_permission": "Grant permission.",
|
||||
"notifications.group": "{count} notifications",
|
||||
|
@ -1061,8 +1061,6 @@
|
|||
"status.open": "Expand this post",
|
||||
"status.pin": "Pin on profile",
|
||||
"status.pinned": "Pinned post",
|
||||
"status.quote": "Quote",
|
||||
"status.quotes": "{count, plural, one {quote} other {quotes}}",
|
||||
"status.read_more": "Read more",
|
||||
"status.reblog": "Boost",
|
||||
"status.reblog_private": "Boost with original visibility",
|
||||
|
@ -1071,7 +1069,8 @@
|
|||
"status.reblogs": "{count, plural, one {boost} other {boosts}}",
|
||||
"status.reblogs.empty": "No one has boosted this post yet. When someone does, they will show up here.",
|
||||
"status.redraft": "Delete & re-draft",
|
||||
"status.reference": "Quiet quote",
|
||||
"status.reference": "Link",
|
||||
"status.references": "{count, plural, one {link} other {links}}",
|
||||
"status.remove_bookmark": "Remove bookmark",
|
||||
"status.remove_favourite": "Remove from favorites",
|
||||
"status.replied_in_thread": "Replied in thread",
|
||||
|
|
|
@ -438,7 +438,7 @@
|
|||
"empty_column.notification_requests": "ここに表示するものはありません。新しい通知を受け取ったとき、フィルタリング設定で通知がブロックされたアカウントがある場合はここに表示されます。",
|
||||
"empty_column.notifications": "まだ通知がありません。他の人とふれ合って会話を始めましょう。",
|
||||
"empty_column.public": "ここにはまだ何もありません! 公開で何かを投稿したり、他のサーバーのユーザーをフォローしたりしていっぱいにしましょう",
|
||||
"empty_column.status_references": "まだ誰も引用していません。引用されるとここに表示されます。",
|
||||
"empty_column.status_references": "まだ誰もリンクしていません。リンクされるとここに表示されます。",
|
||||
"error.unexpected_crash.explanation": "不具合かブラウザの互換性問題のため、このページを正しく表示できませんでした。",
|
||||
"error.unexpected_crash.explanation_addons": "このページは正しく表示できませんでした。このエラーはブラウザのアドオンや自動翻訳ツールによって引き起こされることがあります。",
|
||||
"error.unexpected_crash.next_steps": "ページの再読み込みをお試しください。それでも解決しない場合、別のブラウザかアプリを使えば使用できることがあります。",
|
||||
|
@ -733,7 +733,7 @@
|
|||
"notification.relationships_severance_event.learn_more": "詳細を確認",
|
||||
"notification.relationships_severance_event.user_domain_block": "{target} のブロックにより{followersCount}フォロワーと{followingCount, plural, other {#フォロー}}が解除されました。",
|
||||
"notification.status": "{name}さんが投稿しました",
|
||||
"notification.status_reference": "{name}さんがあなたの投稿を引用しました",
|
||||
"notification.status_reference": "{name}さんがあなたの投稿をリンクしました",
|
||||
"notification.update": "{name}さんが投稿を編集しました",
|
||||
"notification_requests.accept": "受け入れる",
|
||||
"notification_requests.accept_multiple": "{count, plural, other {選択中の#件を受け入れる}}",
|
||||
|
@ -774,7 +774,7 @@
|
|||
"notifications.column_settings.show": "カラムに表示",
|
||||
"notifications.column_settings.sound": "通知音を再生",
|
||||
"notifications.column_settings.status": "新しい投稿:",
|
||||
"notifications.column_settings.status_reference": "引用",
|
||||
"notifications.column_settings.status_reference": "リンク",
|
||||
"notifications.column_settings.unread_notifications.category": "未読の通知:",
|
||||
"notifications.column_settings.unread_notifications.highlight": "未読の通知を強調表示",
|
||||
"notifications.column_settings.update": "編集:",
|
||||
|
@ -786,7 +786,7 @@
|
|||
"notifications.filter.mentions": "返信",
|
||||
"notifications.filter.polls": "アンケート結果",
|
||||
"notifications.filter.statuses": "フォローしている人の新着情報",
|
||||
"notifications.filter.status_references": "引用",
|
||||
"notifications.filter.status_references": "リンク",
|
||||
"notifications.grant_permission": "権限の付与",
|
||||
"notifications.group": "{count}件の通知",
|
||||
"notifications.mark_as_read": "すべて既読にする",
|
||||
|
@ -1031,8 +1031,7 @@
|
|||
"status.open": "詳細を表示",
|
||||
"status.pin": "プロフィールに固定表示",
|
||||
"status.pinned": "固定された投稿",
|
||||
"status.quote": "引用",
|
||||
"status.quotes": "{count, plural, one {引用} other {引用}}",
|
||||
"status.quote": "リンク",
|
||||
"status.read_more": "もっと見る",
|
||||
"status.reblog": "ブースト",
|
||||
"status.reblog_private": "ブースト",
|
||||
|
@ -1041,7 +1040,8 @@
|
|||
"status.reblogs": "{count, plural, one {ブースト} other {ブースト}}",
|
||||
"status.reblogs.empty": "まだ誰もブーストしていません。ブーストされるとここに表示されます。",
|
||||
"status.redraft": "削除して下書きに戻す",
|
||||
"status.reference": "ひかえめな引用",
|
||||
"status.reference": "リンク",
|
||||
"status.references": "{count, plural, one {リンク} other {リンク}}",
|
||||
"status.remove_bookmark": "ブックマークを削除",
|
||||
"status.remove_favourite": "お気に入りから削除",
|
||||
"status.replied_in_thread": "ほかのユーザーへ",
|
||||
|
|
|
@ -56,7 +56,6 @@ const AccountOtherSettingsFactory = ImmutableRecord<AccountOtherSettingsShape>({
|
|||
hide_statuses_count: false,
|
||||
translatable_private: false,
|
||||
link_preview: true,
|
||||
allow_quote: true,
|
||||
emoji_reaction_policy: 'allow',
|
||||
subscription_policy: 'allow',
|
||||
});
|
||||
|
@ -69,7 +68,6 @@ const AccountServerFeaturesFactory =
|
|||
ImmutableRecord<AccountServerFeaturesShape>({
|
||||
circle: false,
|
||||
emoji_reaction: false,
|
||||
quote: false,
|
||||
status_reference: false,
|
||||
});
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ const normalizeFilter = (state, filter) => {
|
|||
filter_action: filter.filter_action,
|
||||
keywords: filter.keywords,
|
||||
expires_at: filter.expires_at ? Date.parse(filter.expires_at) : null,
|
||||
with_quote: filter.with_quote,
|
||||
});
|
||||
|
||||
if (is(state.get(filter.id), normalizedFilter)) {
|
||||
|
|
|
@ -13,41 +13,27 @@ export const makeGetStatus = () => {
|
|||
[
|
||||
(state, { id }) => state.getIn(['statuses', id]),
|
||||
(state, { id }) => state.getIn(['statuses', state.getIn(['statuses', id, 'reblog'])]),
|
||||
(state, { id }) => state.getIn(['statuses', state.getIn(['statuses', id, 'quote_id'])]),
|
||||
(state, { id }) => state.getIn(['statuses', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'quote_id'])]),
|
||||
(state, { id }) => state.getIn(['accounts', state.getIn(['statuses', id, 'account'])]),
|
||||
(state, { id }) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'account'])]),
|
||||
getFilters,
|
||||
(_, { contextType }) => ['detailed', 'bookmarks', 'favourites'].includes(contextType),
|
||||
],
|
||||
|
||||
(statusBase, statusReblog, statusQuote, statusReblogQuote, accountBase, accountReblog, filters, warnInsteadOfHide) => {
|
||||
(statusBase, statusReblog, accountBase, accountReblog, filters, warnInsteadOfHide) => {
|
||||
if (!statusBase || statusBase.get('isLoading')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (statusReblog) {
|
||||
statusReblog = statusReblog.set('account', accountReblog);
|
||||
statusQuote = statusReblogQuote;
|
||||
} else {
|
||||
statusReblog = null;
|
||||
}
|
||||
|
||||
if (isHideItem('blocking_quote') && (statusReblog || statusBase).getIn(['quote', 'quote_muted'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let filtered = false;
|
||||
let mediaFiltered = false;
|
||||
if ((accountReblog || accountBase).get('id') !== me && filters) {
|
||||
let filterResults = statusReblog?.get('filtered') || statusBase.get('filtered') || ImmutableList();
|
||||
const quoteFilterResults = statusQuote?.get('filtered');
|
||||
if (quoteFilterResults) {
|
||||
const filterWithQuote = quoteFilterResults.some((result) => filters.getIn([result.get('filter'), 'with_quote']));
|
||||
if (filterWithQuote) {
|
||||
filterResults = filterResults.concat(quoteFilterResults);
|
||||
}
|
||||
}
|
||||
|
||||
if (!warnInsteadOfHide && filterResults.some((result) => filters.getIn([result.get('filter'), 'filter_action']) === 'hide')) {
|
||||
return null;
|
||||
|
@ -66,7 +52,6 @@ export const makeGetStatus = () => {
|
|||
|
||||
return statusBase.withMutations(map => {
|
||||
map.set('reblog', statusReblog);
|
||||
map.set('quote', statusQuote);
|
||||
map.set('account', accountBase);
|
||||
map.set('matched_filters', filtered);
|
||||
map.set('matched_media_filters', mediaFiltered);
|
||||
|
|
|
@ -555,7 +555,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
|
||||
def related_to_local_activity?
|
||||
fetch? || followed_by_local_accounts? || requested_through_relay? ||
|
||||
responds_to_followed_account? || addresses_local_accounts? || quote_local? || free_friend_domain?
|
||||
responds_to_followed_account? || addresses_local_accounts? || free_friend_domain?
|
||||
end
|
||||
|
||||
def responds_to_followed_account?
|
||||
|
@ -621,16 +621,6 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
ProcessReferencesService.call_service_without_error(@status, [], reference_uris, [quote].compact)
|
||||
end
|
||||
|
||||
def quote_local?
|
||||
url = quote
|
||||
|
||||
if url.present?
|
||||
ActivityPub::TagManager.instance.uri_to_resource(url, Status)&.local?
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def free_friend_domain?
|
||||
FriendDomain.free_receivings.exists?(domain: @account.domain)
|
||||
end
|
||||
|
@ -640,15 +630,6 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
end
|
||||
|
||||
def quote
|
||||
@quote ||= quote_from_tags || @object['quote'] || @object['quoteUrl'] || @object['quoteURL'] || @object['_misskey_quote']
|
||||
end
|
||||
|
||||
def quote_from_tags
|
||||
return @quote_from_tags if defined?(@quote_from_tags)
|
||||
|
||||
hit_tag = as_array(@object['tag']).detect do |tag|
|
||||
equals_or_includes?(tag['type'], 'Link') && LINK_MEDIA_TYPES.include?(tag['mediaType']) && tag['href'].present?
|
||||
end
|
||||
@quote_from_tags = hit_tag && hit_tag['href']
|
||||
@quote ||= nil # TODO: quote
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,6 @@ module ActivityPub::CaseTransform
|
|||
NO_CONVERT_VALUES = %w(
|
||||
_misskey_content
|
||||
_misskey_license
|
||||
_misskey_quote
|
||||
).freeze
|
||||
|
||||
def camel_lower_cache
|
||||
|
|
|
@ -78,7 +78,6 @@ class StatusReachFinder
|
|||
reblogs_account_ids,
|
||||
favourites_account_ids,
|
||||
replies_account_ids,
|
||||
quoted_account_id,
|
||||
].tap do |arr|
|
||||
arr.flatten!
|
||||
arr.compact!
|
||||
|
@ -114,10 +113,6 @@ class StatusReachFinder
|
|||
@status.replies.pluck(:account_id) if distributable? || unsafe?
|
||||
end
|
||||
|
||||
def quoted_account_id
|
||||
@status.quote.account_id if @status.quote?
|
||||
end
|
||||
|
||||
def followers_inboxes
|
||||
scope = followers_scope
|
||||
inboxes_without_suspended_for(scope)
|
||||
|
|
|
@ -15,13 +15,6 @@ module Account::OtherSettings
|
|||
false
|
||||
end
|
||||
|
||||
def allow_quote?
|
||||
return user.setting_allow_quote if local? && user.present?
|
||||
return settings['allow_quote'] if settings.present? && settings.key?('allow_quote')
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def hide_statuses_count?
|
||||
return user&.setting_hide_statuses_count if local? && user.present?
|
||||
return settings['hide_statuses_count'] if settings.present? && settings.key?('hide_statuses_count')
|
||||
|
@ -88,7 +81,6 @@ module Account::OtherSettings
|
|||
'hide_following_count' => hide_following_count?,
|
||||
'hide_followers_count' => hide_followers_count?,
|
||||
'translatable_private' => translatable_private?,
|
||||
'allow_quote' => allow_quote?,
|
||||
'emoji_reaction_policy' => Setting.enable_emoji_reaction ? emoji_reaction_policy.to_s : 'block',
|
||||
}
|
||||
end
|
||||
|
|
|
@ -107,18 +107,6 @@ module User::HasSettings
|
|||
settings['web.content_font_size']
|
||||
end
|
||||
|
||||
def setting_show_quote_in_home
|
||||
settings['web.show_quote_in_home']
|
||||
end
|
||||
|
||||
def setting_show_quote_in_public
|
||||
settings['web.show_quote_in_public']
|
||||
end
|
||||
|
||||
def setting_hide_blocking_quote
|
||||
settings['web.hide_blocking_quote']
|
||||
end
|
||||
|
||||
def setting_show_relationships
|
||||
settings['web.show_relationships']
|
||||
end
|
||||
|
@ -127,10 +115,6 @@ module User::HasSettings
|
|||
settings['web.show_avatar_on_filter']
|
||||
end
|
||||
|
||||
def setting_allow_quote
|
||||
settings['allow_quote']
|
||||
end
|
||||
|
||||
def setting_reject_send_limited_to_suspects
|
||||
settings['reject_send_limited_to_suspects']
|
||||
end
|
||||
|
@ -259,10 +243,6 @@ module User::HasSettings
|
|||
settings['use_public_index']
|
||||
end
|
||||
|
||||
def setting_reverse_search_quote
|
||||
settings['reverse_search_quote']
|
||||
end
|
||||
|
||||
def setting_disallow_unlisted_public_searchability
|
||||
settings['disallow_unlisted_public_searchability']
|
||||
end
|
||||
|
@ -275,10 +255,6 @@ module User::HasSettings
|
|||
settings['web.hide_emoji_reaction_unavailable_server']
|
||||
end
|
||||
|
||||
def setting_hide_quote_unavailable_server
|
||||
settings['web.hide_quote_unavailable_server']
|
||||
end
|
||||
|
||||
def setting_hide_status_reference_unavailable_server
|
||||
settings['web.hide_status_reference_unavailable_server']
|
||||
end
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
# expires_at :datetime
|
||||
# phrase :text default(""), not null
|
||||
# with_profile :boolean default(FALSE), not null
|
||||
# with_quote :boolean default(TRUE), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# account_id :bigint(8) not null
|
||||
|
@ -69,14 +68,6 @@ class CustomFilter < ApplicationRecord
|
|||
hide_action?
|
||||
end
|
||||
|
||||
def exclude_quote=(value)
|
||||
self.with_quote = !ActiveModel::Type::Boolean.new.cast(value)
|
||||
end
|
||||
|
||||
def exclude_quote
|
||||
!with_quote
|
||||
end
|
||||
|
||||
def exclude_profile=(value)
|
||||
self.with_profile = !ActiveModel::Type::Boolean.new.cast(value)
|
||||
end
|
||||
|
@ -111,9 +102,6 @@ class CustomFilter < ApplicationRecord
|
|||
end
|
||||
|
||||
def self.apply_cached_filters(cached_filters, status, following: false)
|
||||
references_text_cache = nil
|
||||
references_spoiler_text_cache = nil
|
||||
|
||||
cached_filters.filter_map do |filter, rules|
|
||||
next if filter.exclude_follows && following
|
||||
next if filter.exclude_localusers && status.account.local?
|
||||
|
@ -121,17 +109,10 @@ class CustomFilter < ApplicationRecord
|
|||
if rules[:keywords].present?
|
||||
match = rules[:keywords].match(status.proper.searchable_text)
|
||||
match = rules[:keywords].match([status.account.display_name, status.account.note].join("\n\n")) if !match && filter.with_profile
|
||||
if match.nil? && filter.with_quote && status.proper.reference_objects.exists?
|
||||
references_text_cache = status.proper.references.pluck(:text).join("\n\n") if references_text_cache.nil?
|
||||
references_spoiler_text_cache = status.proper.references.pluck(:spoiler_text).join("\n\n") if references_spoiler_text_cache.nil?
|
||||
match = rules[:keywords].match(references_text_cache)
|
||||
match = rules[:keywords].match(references_spoiler_text_cache) if match.nil?
|
||||
end
|
||||
end
|
||||
keyword_matches = [match.to_s] unless match.nil?
|
||||
|
||||
reference_ids = filter.with_quote ? status.proper.reference_objects.pluck(:target_status_id) : []
|
||||
status_matches = ([status.id, status.reblog_of_id] + reference_ids).compact & rules[:status_ids] if rules[:status_ids].present?
|
||||
status_matches = [status.id, status.reblog_of_id].compact & rules[:status_ids] if rules[:status_ids].present?
|
||||
|
||||
next if keyword_matches.blank? && status_matches.blank?
|
||||
|
||||
|
|
|
@ -35,8 +35,6 @@ class InstanceInfo < ApplicationRecord
|
|||
yojo-art
|
||||
).freeze
|
||||
|
||||
QUOTE_AVAILABLE_SOFTWARES = EMOJI_REACTION_AVAILABLE_SOFTWARES + %w(bridgy-fed).freeze
|
||||
|
||||
STATUS_REFERENCE_AVAILABLE_SOFTWARES = %w(fedibird).freeze
|
||||
|
||||
CIRCLE_AVAILABLE_SOFTWARES = %w(fedibird).freeze
|
||||
|
@ -87,7 +85,6 @@ class InstanceInfo < ApplicationRecord
|
|||
|
||||
{
|
||||
emoji_reaction: feature_available?(info, EMOJI_REACTION_AVAILABLE_SOFTWARES, 'emoji_reaction'),
|
||||
quote: feature_available?(info, QUOTE_AVAILABLE_SOFTWARES, 'quote'),
|
||||
status_reference: feature_available?(info, STATUS_REFERENCE_AVAILABLE_SOFTWARES, 'status_reference'),
|
||||
circle: feature_available?(info, CIRCLE_AVAILABLE_SOFTWARES, 'circle'),
|
||||
}
|
||||
|
@ -96,7 +93,6 @@ class InstanceInfo < ApplicationRecord
|
|||
def local_features
|
||||
{
|
||||
emoji_reaction: Setting.enable_emoji_reaction,
|
||||
quote: true,
|
||||
status_reference: true,
|
||||
circle: true,
|
||||
}
|
||||
|
|
|
@ -205,19 +205,6 @@ class Status < ApplicationRecord
|
|||
account: [:account_stat, user: :role],
|
||||
active_mentions: { account: :account_stat },
|
||||
],
|
||||
quote: [
|
||||
:application,
|
||||
:tags,
|
||||
:media_attachments,
|
||||
:conversation,
|
||||
:status_stat,
|
||||
:preloadable_poll,
|
||||
:reference_objects,
|
||||
:scheduled_expiration_status,
|
||||
preview_cards_status: { preview_card: { author_account: [:account_stat, user: :role] } },
|
||||
account: [:account_stat, user: :role],
|
||||
active_mentions: :account,
|
||||
],
|
||||
thread: :account
|
||||
|
||||
delegate :domain, to: :account, prefix: true
|
||||
|
@ -252,10 +239,6 @@ class Status < ApplicationRecord
|
|||
!reblog_of_id.nil?
|
||||
end
|
||||
|
||||
def quote?
|
||||
!quote_of_id.nil? && !quote.nil?
|
||||
end
|
||||
|
||||
def expires?
|
||||
scheduled_expiration_status.present?
|
||||
end
|
||||
|
|
|
@ -5,12 +5,11 @@
|
|||
# Table name: status_references
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# status_id :bigint(8) not null
|
||||
# target_status_id :bigint(8) not null
|
||||
# attribute_type :string
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# attribute_type :string
|
||||
# quote :boolean default(FALSE), not null
|
||||
# status_id :bigint(8) not null
|
||||
# target_status_id :bigint(8) not null
|
||||
#
|
||||
|
||||
class StatusReference < ApplicationRecord
|
||||
|
@ -22,8 +21,6 @@ class StatusReference < ApplicationRecord
|
|||
has_one :notification, as: :activity, dependent: :destroy
|
||||
|
||||
after_commit :reset_parent_cache
|
||||
after_create_commit :set_quote
|
||||
after_destroy_commit :remove_quote
|
||||
|
||||
private
|
||||
|
||||
|
@ -31,18 +28,4 @@ class StatusReference < ApplicationRecord
|
|||
Rails.cache.delete("statuses/#{status_id}")
|
||||
Rails.cache.delete("statuses/#{target_status_id}")
|
||||
end
|
||||
|
||||
def set_quote
|
||||
return unless quote
|
||||
return if status.quote_of_id.present?
|
||||
|
||||
status.quote_of_id = target_status_id
|
||||
end
|
||||
|
||||
def remove_quote
|
||||
return unless quote
|
||||
return unless status.quote_of_id == target_status_id
|
||||
|
||||
status.quote_of_id = nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,7 +27,6 @@ class UserSettings
|
|||
setting :default_searchability, default: :direct, in: %w(public private direct limited public_unlisted)
|
||||
setting :default_searchability_of_search, default: :public, in: %w(public private direct limited)
|
||||
setting :use_public_index, default: true
|
||||
setting :reverse_search_quote, default: false
|
||||
setting :disallow_unlisted_public_searchability, default: false
|
||||
setting :public_post_to_unlisted, default: false
|
||||
setting :reject_public_unlisted_subscription, default: false
|
||||
|
@ -40,7 +39,6 @@ class UserSettings
|
|||
setting :dtl_force_visibility, default: :unchange, in: %w(unchange public public_unlisted unlisted)
|
||||
setting :dtl_force_searchability, default: :unchange, in: %w(unchange public public_unlisted)
|
||||
setting :lock_follow_from_bot, default: false
|
||||
setting :allow_quote, default: true
|
||||
setting :reject_send_limited_to_suspects, default: false
|
||||
|
||||
setting_inverse_alias :indexable, :noindex
|
||||
|
@ -75,18 +73,12 @@ class UserSettings
|
|||
setting :auto_play, default: true
|
||||
setting :simple_timeline_menu, default: false
|
||||
setting :boost_menu, default: false
|
||||
setting :show_quote_in_home, default: true
|
||||
setting :show_quote_in_public, default: false
|
||||
setting :show_relationships, default: true
|
||||
setting :hide_blocking_quote, default: true
|
||||
setting :hide_emoji_reaction_unavailable_server, default: false
|
||||
setting :hide_quote_unavailable_server, default: false
|
||||
setting :hide_status_reference_unavailable_server, default: false
|
||||
setting :hide_favourite_menu, default: false
|
||||
setting :hide_emoji_reaction_count, default: false
|
||||
setting :show_avatar_on_filter, default: true
|
||||
|
||||
setting_inverse_alias :'web.show_blocking_quote', :'web.hide_blocking_quote'
|
||||
setting_inverse_alias :'web.show_emoji_reaction_count', :'web.hide_emoji_reaction_count'
|
||||
setting_inverse_alias :'web.show_favourite_menu', :'web.hide_favourite_menu'
|
||||
setting_inverse_alias :'web.show_recent_emojis', :'web.hide_recent_emojis'
|
||||
|
|
|
@ -47,10 +47,6 @@ class StatusPolicy < ApplicationPolicy
|
|||
show? && !blocking_author?
|
||||
end
|
||||
|
||||
def quote?
|
||||
%i(public public_unlisted unlisted).include?(record.visibility.to_sym) && show? && !blocking_author?
|
||||
end
|
||||
|
||||
def destroy?
|
||||
owned?
|
||||
end
|
||||
|
|
|
@ -21,7 +21,6 @@ class StatusRelationshipsPresenter
|
|||
@emoji_reaction_allows_map = nil
|
||||
else
|
||||
statuses = statuses.compact
|
||||
statuses += statuses.filter_map(&:quote)
|
||||
status_ids = statuses.flat_map { |s| [s.id, s.reblog_of_id] }.uniq.compact
|
||||
conversation_ids = statuses.filter_map(&:conversation_id).uniq
|
||||
pinnable_status_ids = statuses.map(&:proper).filter_map { |s| s.id if s.account_id == current_account_id && PINNABLE_VISIBILITIES.include?(s.visibility) }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class ActivityPub::NoteSerializer < ActivityPub::Serializer
|
||||
include FormattingHelper
|
||||
|
||||
context_extensions :atom_uri, :conversation, :sensitive, :voters_count, :searchable_by, :references, :limited_scope, :quote_uri
|
||||
context_extensions :atom_uri, :conversation, :sensitive, :voters_count, :searchable_by, :references, :limited_scope
|
||||
|
||||
attributes :id, :type, :summary,
|
||||
:in_reply_to, :published, :url,
|
||||
|
@ -16,9 +16,6 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
|
|||
attribute :updated, if: :edited?
|
||||
attribute :limited_scope, if: :limited_visibility?
|
||||
|
||||
attribute :quote_uri, if: :quote?
|
||||
attribute :misskey_quote, key: :_misskey_quote, if: :quote?
|
||||
|
||||
has_many :virtual_attachments, key: :attachment
|
||||
has_many :virtual_tags, key: :tag
|
||||
|
||||
|
@ -158,30 +155,7 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
|
|||
end
|
||||
|
||||
def virtual_tags
|
||||
object.active_mentions.to_a.sort_by(&:id) + object.tags + object.emojis + virtual_tags_of_quote
|
||||
end
|
||||
|
||||
class NoteLink < ActiveModelSerializers::Model
|
||||
attributes :href
|
||||
end
|
||||
|
||||
class NoteLinkSerializer < ActivityPub::Serializer
|
||||
attributes :type, :href
|
||||
attribute :media_type, key: :mediaType
|
||||
|
||||
def type
|
||||
'Link'
|
||||
end
|
||||
|
||||
def media_type
|
||||
'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
|
||||
end
|
||||
end
|
||||
|
||||
def virtual_tags_of_quote
|
||||
return [] unless object.quote?
|
||||
|
||||
[NoteLink.new(href: quote_uri)]
|
||||
object.active_mentions.to_a.sort_by(&:id) + object.tags + object.emojis
|
||||
end
|
||||
|
||||
def atom_uri
|
||||
|
@ -218,20 +192,6 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
|
|||
object.account.local?
|
||||
end
|
||||
|
||||
delegate :quote?, to: :object
|
||||
|
||||
def quote_post
|
||||
@quote_post ||= object.quote
|
||||
end
|
||||
|
||||
def quote_uri
|
||||
ActivityPub::TagManager.instance.uri_for(quote_post)
|
||||
end
|
||||
|
||||
def misskey_quote
|
||||
quote_uri
|
||||
end
|
||||
|
||||
def poll_options
|
||||
object.preloadable_poll.loaded_options
|
||||
end
|
||||
|
|
|
@ -40,14 +40,10 @@ class InitialStateSerializer < ActiveModel::Serializer
|
|||
store[:hide_items] = [
|
||||
object_account_user.setting_hide_favourite_menu ? 'favourite_menu' : nil,
|
||||
object_account_user.setting_hide_recent_emojis ? 'recent_emojis' : nil,
|
||||
object_account_user.setting_hide_blocking_quote ? 'blocking_quote' : nil,
|
||||
object_account_user.setting_hide_emoji_reaction_unavailable_server ? 'emoji_reaction_unavailable_server' : nil,
|
||||
object_account_user.setting_hide_quote_unavailable_server ? 'quote_unavailable_server' : nil,
|
||||
object_account_user.setting_hide_status_reference_unavailable_server ? 'status_reference_unavailable_server' : nil,
|
||||
object_account_user.setting_hide_emoji_reaction_count ? 'emoji_reaction_count' : nil,
|
||||
object_account_user.setting_show_emoji_reaction_on_timeline ? nil : 'emoji_reaction_on_timeline',
|
||||
object_account_user.setting_show_quote_in_home ? nil : 'quote_in_home',
|
||||
object_account_user.setting_show_quote_in_public ? nil : 'quote_in_public',
|
||||
object_account_user.setting_show_relationships ? nil : 'relationships',
|
||||
object_account_user.setting_show_avatar_on_filter ? nil : 'avatar_on_filter',
|
||||
].compact
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class REST::FilterSerializer < ActiveModel::Serializer
|
||||
attributes :id, :title, :exclude_follows, :exclude_localusers, :with_quote, :with_profile, :context, :expires_at, :filter_action
|
||||
attributes :id, :title, :exclude_follows, :exclude_localusers, :with_profile, :context, :expires_at, :filter_action
|
||||
has_many :keywords, serializer: REST::FilterKeywordSerializer, if: :rules_requested?
|
||||
has_many :statuses, serializer: REST::FilterStatusSerializer, if: :rules_requested?
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
|||
attribute :pinned, if: :pinnable?
|
||||
attribute :reactions, if: :reactions?
|
||||
attribute :expires_at, if: :will_expire?
|
||||
attribute :quote_id, if: :quote?
|
||||
attribute :markdown_opt, key: :markdown
|
||||
has_many :filtered, serializer: REST::FilterResultSerializer, if: :current_user?
|
||||
|
||||
|
@ -37,23 +36,6 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
|||
has_one :preview_card, key: :card, serializer: REST::PreviewCardSerializer
|
||||
has_one :preloadable_poll, key: :poll, serializer: REST::PollSerializer
|
||||
|
||||
class QuotedStatusSerializer < REST::StatusSerializer
|
||||
attribute :quote_muted, if: :current_user?
|
||||
|
||||
def quote
|
||||
nil
|
||||
end
|
||||
|
||||
def quote_muted
|
||||
if relationships
|
||||
muted || relationships.blocks_map[object.account_id] || relationships.domain_blocks_map[object.account.domain] || false
|
||||
else
|
||||
muted || current_user.account.blocking?(object.account_id) || current_user.account.domain_blocking?(object.account.domain)
|
||||
end
|
||||
end
|
||||
end
|
||||
belongs_to :quote, if: :quote?, serializer: QuotedStatusSerializer, relationships: -> { relationships }
|
||||
|
||||
def id
|
||||
object.id.to_s
|
||||
end
|
||||
|
@ -182,12 +164,6 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
|||
end
|
||||
end
|
||||
|
||||
def quote_id
|
||||
object.quote_of_id.to_s
|
||||
end
|
||||
|
||||
delegate :quote?, to: :object
|
||||
|
||||
def reblogged
|
||||
if relationships
|
||||
relationships.reblogs_map[object.id] || false
|
||||
|
|
|
@ -351,7 +351,8 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
|
|||
end
|
||||
|
||||
def quote
|
||||
@json['quote'] || @json['quoteUrl'] || @json['quoteURL'] || @json['_misskey_quote']
|
||||
# TODO: quote
|
||||
nil
|
||||
end
|
||||
|
||||
def local_referred_accounts
|
||||
|
|
|
@ -115,7 +115,7 @@ class FanOutOnWriteService < BaseService
|
|||
end
|
||||
|
||||
def notify_about_update!
|
||||
@status.reblogged_by_accounts.or(@status.quoted_by_accounts).merge(Account.local).select(:id).reorder(nil).find_in_batches do |accounts|
|
||||
@status.reblogged_by_accounts.merge(Account.local).select(:id).reorder(nil).find_in_batches do |accounts|
|
||||
LocalNotificationWorker.push_bulk(accounts) do |account|
|
||||
[account.id, @status.id, 'Status', 'update']
|
||||
end
|
||||
|
|
|
@ -277,6 +277,7 @@ class PostStatusService < BaseService
|
|||
|
||||
def quote_url
|
||||
ProcessReferencesService.extract_quote(@text)
|
||||
# TODO: quote
|
||||
end
|
||||
|
||||
def reference_urls
|
||||
|
|
|
@ -188,7 +188,8 @@ class ProcessReferencesService < BaseService
|
|||
quote = quote_attribute?(attribute_type)
|
||||
@added_objects << @status.reference_objects.new(target_status: status, attribute_type: attribute_type, quote: quote)
|
||||
|
||||
@status.update!(quote_of_id: status_id) if quote
|
||||
# TODO: quote
|
||||
# @status.update!(quote_of_id: status_id) if quote
|
||||
|
||||
status.increment_count!(:status_referred_by_count)
|
||||
@references_count += 1
|
||||
|
@ -214,7 +215,9 @@ class ProcessReferencesService < BaseService
|
|||
@removed_objects = []
|
||||
|
||||
@status.reference_objects.where(target_status: @removed_items.keys).destroy_all
|
||||
@status.update!(quote_of_id: nil) if @status.quote_of_id.present? && @removed_items.key?(@status.quote_of_id)
|
||||
|
||||
# TODO: quote
|
||||
# @status.update!(quote_of_id: nil) if @status.quote_of_id.present? && @removed_items.key?(@status.quote_of_id)
|
||||
|
||||
statuses = Status.where(id: @added_items.keys).to_a
|
||||
@removed_items.each_key do |status_id|
|
||||
|
@ -240,11 +243,12 @@ class ProcessReferencesService < BaseService
|
|||
|
||||
next unless quote_change
|
||||
|
||||
if quote
|
||||
ref.status.update!(quote_of_id: ref.target_status.id)
|
||||
else
|
||||
ref.status.update!(quote_of_id: nil)
|
||||
end
|
||||
# TODO: quote
|
||||
# if quote
|
||||
# ref.status.update!(quote_of_id: ref.target_status.id)
|
||||
# else
|
||||
# ref.status.update!(quote_of_id: nil)
|
||||
# end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -139,6 +139,7 @@ class UpdateStatusService < BaseService
|
|||
|
||||
def quote_url
|
||||
ProcessReferencesService.extract_quote(text)
|
||||
# TODO: quote
|
||||
end
|
||||
|
||||
def reference_urls
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
= f.input :exclude_localusers, wrapper: :with_label, kmyblue: true, label: t('simple_form.labels.filters.options.exclude_localusers')
|
||||
|
||||
.fields-group
|
||||
= f.input :exclude_quote, wrapper: :with_label, as: :boolean, kmyblue: true, label: t('simple_form.labels.filters.options.exclude_quote')
|
||||
= f.input :exclude_profile, wrapper: :with_label, as: :boolean, kmyblue: true, label: t('simple_form.labels.filters.options.exclude_profile')
|
||||
|
||||
%hr.spacer/
|
||||
|
|
|
@ -86,7 +86,6 @@
|
|||
.fields-group
|
||||
- if Setting.enable_emoji_reaction
|
||||
= ff.input :'web.hide_emoji_reaction_unavailable_server', wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_hide_emoji_reaction_unavailable_server')
|
||||
= ff.input :'web.hide_quote_unavailable_server', wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_hide_quote_unavailable_server')
|
||||
= ff.input :'web.hide_status_reference_unavailable_server', wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_hide_status_reference_unavailable_server')
|
||||
|
||||
%h4= t 'appearance.saved_posts'
|
||||
|
@ -95,13 +94,6 @@
|
|||
= ff.input :'web.bookmark_category_needed', wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_bookmark_category_needed'), hint: I18n.t('simple_form.hints.defaults.setting_bookmark_category_needed')
|
||||
= ff.input :'web.show_favourite_menu', wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_show_favourite_menu')
|
||||
|
||||
%h4= t 'appearance.quotes'
|
||||
|
||||
.fields-group
|
||||
= ff.input :'web.show_quote_in_home', wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_show_quote_in_home'), hint: false
|
||||
= ff.input :'web.show_quote_in_public', wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_show_quote_in_public'), hint: false
|
||||
= ff.input :'web.show_blocking_quote', wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_show_blocking_quote'), hint: false
|
||||
|
||||
%h4= t 'appearance.status_action_bar'
|
||||
|
||||
.fields-group
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
.fields-group
|
||||
= ff.input :translatable_private, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_translatable_private')
|
||||
|
||||
.fields-group
|
||||
= ff.input :allow_quote, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_allow_quote'), hint: I18n.t('simple_form.hints.defaults.setting_allow_quote')
|
||||
|
||||
- if Setting.enable_emoji_reaction
|
||||
%h4= t 'preferences.emoji_reaction_permitting'
|
||||
|
||||
|
|
|
@ -484,7 +484,7 @@ en:
|
|||
reject_media_hint: Removes locally stored media files and refuses to download any in the future. Irrelevant for suspensions
|
||||
reject_new_follow: Reject follows
|
||||
reject_new_follow_hint: Reject follows in the future
|
||||
reject_reply_exclude_followers: Reject mentions/quotes exclude followers
|
||||
reject_reply_exclude_followers: Reject mentions exclude followers
|
||||
reject_reply_exclude_followers_hint: Reject replies exclude followers in the future
|
||||
reject_reports: Reject reports
|
||||
reject_reports_hint: Ignore all reports coming from this domain. Irrelevant for suspensions
|
||||
|
@ -629,7 +629,7 @@ en:
|
|||
reject_hashtag: Reject hashtags
|
||||
reject_media: Reject media
|
||||
reject_new_follow: Reject follows
|
||||
reject_reply_exclude_followers: Reject reply/quote exclude followers
|
||||
reject_reply_exclude_followers: Reject reply exclude followers
|
||||
reject_reports: Reject reports
|
||||
reject_send_sensitive: No Sensitive Submission Delivery
|
||||
reject_straight_follow: Reject straight follow
|
||||
|
@ -781,7 +781,7 @@ en:
|
|||
needed: have
|
||||
no_needed: Should not have
|
||||
optional: Optional
|
||||
status_allow_follower_mention: Check posts only if they contain mentions/quotes to non-followers
|
||||
status_allow_follower_mention: Check posts only if they contain mentions to non-followers
|
||||
status_allow_follower_mention_hint: If enabled, mentions between other servers are unconditionally allowed
|
||||
status_cw_state: Has warning or not
|
||||
status_media_state: Has media or not
|
||||
|
@ -791,8 +791,8 @@ en:
|
|||
status_poll_state: Has poll or not
|
||||
status_poll_threshold: Poll items limit
|
||||
status_quote_state: Has quote or not
|
||||
status_reference_state: Has quiet quote or not
|
||||
status_reference_threshold: Has quiet quote or not
|
||||
status_reference_state: Has link or not
|
||||
status_reference_threshold: Has link or not
|
||||
status_reply_state: Is reply or not
|
||||
status_searchability: Searchability
|
||||
status_sensitive_state: Is sensitive or not
|
||||
|
@ -811,7 +811,7 @@ en:
|
|||
phrases:
|
||||
regexp_html: "<strong>Reg</strong> - If the <strong>Reg</strong> checkbox is checked, the comparison is performed using regular expressions."
|
||||
regexp_short: Reg
|
||||
stranger_html: "<strong>UE</strong> - Items checked under <strong>Uem</strong> apply only to mentions, replies, quotes, etc. from accounts with which you have no follow relationship."
|
||||
stranger_html: "<strong>UE</strong> - Items checked under <strong>Uem</strong> apply only to mentions, replies, links, etc. from accounts with which you have no follow relationship."
|
||||
stranger_short: Uem
|
||||
post_hash_tags_max: Hash tags limit of a post
|
||||
post_mentions_max: Mentions limit of a post
|
||||
|
@ -1106,7 +1106,7 @@ en:
|
|||
special_domains:
|
||||
stop_fetch_activity_domains:
|
||||
preamble: On servers with different domains for Web and Activity, you may not be able to retrieve Activity even if you access Web. In citations, this setting suppresses fetching when such a URL is specified in the body of a post. In most cases, this setting is rarely used.
|
||||
title: Domains do not fetch for quotes
|
||||
title: Domains do not fetch for links
|
||||
stop_link_preview_domains:
|
||||
preamble: If a site temporarily restricts connections from IP addresses that have received many hits, your server may be treated unfavorably. This setting suppresses the process of accessing such sites and generating link previews. In most cases, this setting is rarely used.
|
||||
title: Domains do not fetch for link previews
|
||||
|
@ -1435,7 +1435,6 @@ en:
|
|||
body: Mastodon is translated by volunteers.
|
||||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Everyone can contribute.
|
||||
quotes: Quotes
|
||||
remote_server_features: Other server features
|
||||
saved_posts: Saving posts
|
||||
sensitive_content: Sensitive content
|
||||
|
|
|
@ -1389,7 +1389,6 @@ ja:
|
|||
body: Mastodonは有志によって翻訳されています。
|
||||
guide_link: https://ja.crowdin.com/project/mastodon
|
||||
guide_link_text: 誰でも参加することができます。
|
||||
quotes: 引用
|
||||
remote_server_features: 他のサーバーの機能
|
||||
saved_posts: 投稿の記録
|
||||
sensitive_content: 閲覧注意コンテンツ
|
||||
|
|
|
@ -60,7 +60,6 @@ en:
|
|||
phrase: Will be matched regardless of casing in text or content warning of a post
|
||||
scopes: Which APIs the application will be allowed to access. If you select a top-level scope, you don't need to select individual ones.
|
||||
setting_aggregate_reblogs: Do not show new boosts for posts that have been recently boosted (only affects newly-received boosts)
|
||||
setting_allow_quote: Subdued quotes are allowed regardless of this setting; you can quote freely from any source except kmyblue!
|
||||
setting_always_send_emails: Normally e-mail notifications won't be sent when you are actively using Mastodon
|
||||
setting_bookmark_category_needed: When removing from all category, unbookmarked automatically
|
||||
setting_custom_css_lead: 'Be sure to remember: In the unlikely event that you make a mistake in entering your custom CSS and the screen does not display properly, you can disable your custom CSS from the link at the bottom of the sign-in screen. Open the sign-in screen in private mode of your browser, for example, and disable it.'
|
||||
|
@ -80,7 +79,6 @@ en:
|
|||
setting_public_post_to_unlisted: 未対応のサードパーティアプリからもローカル公開で投稿できますが、公開投稿はWeb以外できなくなります
|
||||
setting_reject_send_limited_to_suspects: This applies to "Mutual Only" posts. Circle posts will be delivered without exception. Some Misskey servers have independently supported limited posting, but this is a setting for those who are concerned about it, as mutual-only posting exposes some of the users you are mutual with to Misskey users!
|
||||
setting_reject_unlisted_subscription: Misskey and its forks can **subscribe and search** for "non-following" posts from accounts they do not follow. This differs from kmyblue's behavior. It delivers posts in the specified public range to such servers as "followers only". Please understand, however, that due to its structure, it is difficult to handle perfectly and will occasionally be delivered as non-subscribed.
|
||||
setting_reverse_search_quote: Double-quotes will result in a search with a wider range of notation, which is the opposite of Mastodon's default behavior.
|
||||
setting_show_application: 投稿するのに使用したアプリが投稿の詳細ビューに表示されるようになります
|
||||
setting_stay_privacy: If you choose to enable this setting, please consider manually setting the visibility of the boost
|
||||
setting_stop_emoji_reaction_streaming: Helps to save communication capacity.
|
||||
|
@ -270,7 +268,6 @@ en:
|
|||
phrase: Keyword or phrase
|
||||
setting_advanced_layout: Enable advanced web interface
|
||||
setting_aggregate_reblogs: Group boosts in timelines
|
||||
setting_allow_quote: Allow quote your posts
|
||||
setting_always_send_emails: Always send e-mail notifications
|
||||
setting_auto_play_gif: Auto-play animated GIFs
|
||||
setting_bio_markdown: Enable profile markdown
|
||||
|
@ -315,8 +312,7 @@ en:
|
|||
setting_expand_spoilers: Always expand posts marked with content warnings
|
||||
setting_hide_emoji_reaction_unavailable_server: Hide emoji reaction button from unavailable server
|
||||
setting_hide_network: Hide your social graph
|
||||
setting_hide_quote_unavailable_server: Hide quote menu from unavailable server
|
||||
setting_hide_status_reference_unavailable_server: Hide quiet quote (reference named by Fedibird) menu from unavailable server
|
||||
setting_hide_status_reference_unavailable_server: Hide link (reference named by Fedibird) menu from unavailable server
|
||||
setting_lock_follow_from_bot: Request approval about bot follow
|
||||
setting_missing_alt_text_modal: Show confirmation dialog before posting media without alt text
|
||||
setting_public_post_to_unlisted: Convert public post to public unlisted if not using Web app
|
||||
|
@ -327,14 +323,11 @@ en:
|
|||
setting_reverse_search_quote: Perform word-by-word search when search keywords are not enclosed in double quotes
|
||||
setting_show_application: Disclose application used to send posts
|
||||
setting_show_avatar_on_filter: Show filtered posts with avatar and user profile
|
||||
setting_show_blocking_quote: Show posts which have a quote written by the user you are blocking
|
||||
setting_show_emoji_reaction_count: Show emoji reaction number
|
||||
setting_show_emoji_reaction_on_timeline: Show all emoji reactions on timeline
|
||||
setting_show_favourite_menu: Show favourite menu
|
||||
setting_show_followers_count: Show followers count
|
||||
setting_show_following_count: Show following count
|
||||
setting_show_quote_in_home: Show quotes in home, list or antenna timelines
|
||||
setting_show_quote_in_public: Show quotes in public timelines
|
||||
setting_show_recent_emojis: Show recent emojis
|
||||
setting_show_relationships: Show relationships on account page
|
||||
setting_show_statuses_count: Show statuses count
|
||||
|
@ -386,7 +379,6 @@ en:
|
|||
exclude_follows: Exclude following users
|
||||
exclude_localusers: Exclude local users
|
||||
exclude_profile: Exclude account name and bio
|
||||
exclude_quote: Exclude quote or references
|
||||
form_admin_settings:
|
||||
activity_api_enabled: Publish aggregate statistics about user activity in the API
|
||||
app_icon: App icon
|
||||
|
|
|
@ -60,7 +60,6 @@ ja:
|
|||
phrase: 投稿内容の大文字小文字や閲覧注意に関係なく一致
|
||||
scopes: アプリの API に許可するアクセス権を選択してください。最上位のスコープを選択する場合、個々のスコープを選択する必要はありません。
|
||||
setting_aggregate_reblogs: 最近ブーストされた投稿が新たにブーストされても表示しません (設定後受信したものにのみ影響)
|
||||
setting_allow_quote: ひかえめな引用はこの設定に関わらず可能です。kmyblue以外からは自由に引用できます
|
||||
setting_always_send_emails: 通常、Mastodon からメール通知は行われません。
|
||||
setting_bookmark_category_needed: すべてのカテゴリから削除したとき、ブックマークが自動で外れるようになります
|
||||
setting_custom_css_lead: '必ず覚えてください: 万が一カスタムCSSの入力を誤り、画面が正常に表示されなくなった場合は、サインイン画面の下にあるリンクよりカスタムCSSを無効化することができます。ブラウザのプライベートモードなどでサインイン画面を開き、無効化してください。'
|
||||
|
@ -261,7 +260,6 @@ ja:
|
|||
phrase: キーワードまたはフレーズ
|
||||
setting_advanced_layout: 上級者向けUIを有効にする
|
||||
setting_aggregate_reblogs: ブーストをまとめる
|
||||
setting_allow_quote: 引用を許可する
|
||||
setting_always_send_emails: 常にメール通知を送信する
|
||||
setting_auto_play_gif: アニメーションGIFを自動再生する
|
||||
setting_bio_markdown: プロフィールのMarkdownを有効にする
|
||||
|
@ -306,7 +304,6 @@ ja:
|
|||
setting_expand_spoilers: 閲覧注意としてマークされた投稿を常に展開する
|
||||
setting_hide_emoji_reaction_unavailable_server: 絵文字リアクションに対応していないと思われるサーバーの投稿から絵文字リアクション機能を隠す
|
||||
setting_hide_network: 繋がりを隠す
|
||||
setting_hide_quote_unavailable_server: 引用に対応していないと思われるサーバーの投稿からメニューを隠す
|
||||
setting_hide_status_reference_unavailable_server: ひかえめな引用(Fedibirdの参照)に対応していないと思われるサーバーの投稿からメニューを隠す
|
||||
setting_lock_follow_from_bot: botからのフォローを承認制にする
|
||||
setting_missing_alt_text_modal: 代替テキストなしでメディアを投稿する前に確認ダイアログを表示する
|
||||
|
@ -318,14 +315,11 @@ ja:
|
|||
setting_reverse_search_quote: ダブルクオートで囲まず検索した時、単語単位で検索する
|
||||
setting_show_application: 送信したアプリを開示する
|
||||
setting_show_avatar_on_filter: フィルター対象投稿の投稿者名やアイコンを表示する
|
||||
setting_show_blocking_quote: ブロックしたユーザーの投稿を引用した投稿を表示する
|
||||
setting_show_emoji_reaction_count: 投稿につけられた各絵文字の数を表示する
|
||||
setting_show_emoji_reaction_on_timeline: タイムライン上の投稿に他の人のつけた絵文字を表示する
|
||||
setting_show_favourite_menu: 右サイドメニューに「お気に入り」を表示する
|
||||
setting_show_followers_count: フォロワー数を公開する
|
||||
setting_show_following_count: フォロー数を公開する
|
||||
setting_show_quote_in_home: ホーム・リスト・アンテナなどで引用された投稿を表示する
|
||||
setting_show_quote_in_public: 公開タイムライン(ローカル・連合)で引用された投稿を表示する
|
||||
setting_show_recent_emojis: 絵文字ピッカーで絵文字デッキと一緒に、絵文字の使用履歴も表示する
|
||||
setting_show_relationships: アカウント詳細ベージで、相手からのフォロー状況を表示する
|
||||
setting_show_statuses_count: 投稿数を公開する
|
||||
|
@ -376,7 +370,6 @@ ja:
|
|||
exclude_follows: フォロー中のユーザーをフィルターの対象にしない
|
||||
exclude_localusers: ローカルユーザーをフィルターの対象にしない
|
||||
exclude_profile: アカウント名および紹介文をフィルターの対象にしない
|
||||
exclude_quote: 引用の内容をフィルターの対象にしない
|
||||
form_admin_settings:
|
||||
activity_api_enabled: APIでユーザーアクティビティに関する集計統計を公開する
|
||||
app_icon: アプリアイコン
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveKmyblueQuoteAccessories < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
safety_assured do
|
||||
remove_column :custom_filters, :with_quote, :boolean, default: true, null: false
|
||||
remove_column :status_references, :quote, :boolean, default: false, null: false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.0].define(version: 2025_04_10_144908) do
|
||||
ActiveRecord::Schema[8.0].define(version: 2025_04_23_224935) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pg_catalog.plpgsql"
|
||||
|
||||
|
@ -552,7 +552,6 @@ ActiveRecord::Schema[8.0].define(version: 2025_04_10_144908) do
|
|||
t.integer "action", default: 0, null: false
|
||||
t.boolean "exclude_follows", default: false, null: false
|
||||
t.boolean "exclude_localusers", default: false, null: false
|
||||
t.boolean "with_quote", default: true, null: false
|
||||
t.boolean "with_profile", default: false, null: false
|
||||
t.index ["account_id"], name: "index_custom_filters_on_account_id"
|
||||
end
|
||||
|
@ -1374,7 +1373,6 @@ ActiveRecord::Schema[8.0].define(version: 2025_04_10_144908) do
|
|||
t.datetime "created_at", precision: nil, null: false
|
||||
t.datetime "updated_at", precision: nil, null: false
|
||||
t.string "attribute_type"
|
||||
t.boolean "quote", default: false, null: false
|
||||
t.index ["status_id"], name: "index_status_references_on_status_id"
|
||||
t.index ["target_status_id"], name: "index_status_references_on_target_status_id"
|
||||
end
|
||||
|
|
|
@ -158,7 +158,7 @@ namespace :dangerous do
|
|||
%w(custom_filters exclude_follows),
|
||||
%w(custom_filters exclude_localusers),
|
||||
%w(custom_filters with_profile),
|
||||
%w(custom_filters with_quote),
|
||||
# Removed: custom_filters with_quote,
|
||||
%w(domain_blocks block_trends),
|
||||
%w(domain_blocks detect_invalid_subscription),
|
||||
%w(domain_blocks hidden),
|
||||
|
|
|
@ -4,5 +4,4 @@ Fabricator(:status_reference) do
|
|||
status { Fabricate.build(:status) }
|
||||
target_status { Fabricate.build(:status) }
|
||||
attribute_type 'BT'
|
||||
quote false
|
||||
end
|
||||
|
|
|
@ -1711,104 +1711,10 @@ RSpec.describe ActivityPub::Activity::Create do
|
|||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
expect(status.quote).to be_nil
|
||||
expect(status.references.pluck(:id)).to eq [target_status.id]
|
||||
end
|
||||
end
|
||||
|
||||
context 'with quote' do
|
||||
let(:recipient) { Fabricate(:account) }
|
||||
let!(:target_status) { Fabricate(:status, account: Fabricate(:account, domain: nil)) }
|
||||
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
type: 'Note',
|
||||
content: 'Lorem ipsum',
|
||||
quote: ActivityPub::TagManager.instance.uri_for(target_status),
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
expect(status.references.pluck(:id)).to eq [target_status.id]
|
||||
expect(status.quote).to_not be_nil
|
||||
expect(status.quote.id).to eq target_status.id
|
||||
end
|
||||
end
|
||||
|
||||
context 'with quote as feb-e232 object links' do
|
||||
let(:recipient) { Fabricate(:account) }
|
||||
let!(:target_status) { Fabricate(:status, account: Fabricate(:account, domain: nil)) }
|
||||
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
type: 'Note',
|
||||
content: 'Lorem ipsum',
|
||||
tag: [
|
||||
{
|
||||
type: 'Link',
|
||||
mediaType: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||
href: ActivityPub::TagManager.instance.uri_for(target_status),
|
||||
},
|
||||
],
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
expect(status.references.pluck(:id)).to eq [target_status.id]
|
||||
expect(status.quote).to_not be_nil
|
||||
expect(status.quote.id).to eq target_status.id
|
||||
end
|
||||
end
|
||||
|
||||
context 'with references and quote' do
|
||||
let(:recipient) { Fabricate(:account) }
|
||||
let!(:target_status) { Fabricate(:status, account: Fabricate(:account, domain: nil)) }
|
||||
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
type: 'Note',
|
||||
content: 'Lorem ipsum',
|
||||
quote: ActivityPub::TagManager.instance.uri_for(target_status),
|
||||
references: {
|
||||
id: 'target_status',
|
||||
type: 'Collection',
|
||||
first: {
|
||||
type: 'CollectionPage',
|
||||
next: nil,
|
||||
partOf: 'target_status',
|
||||
items: [
|
||||
ActivityPub::TagManager.instance.uri_for(target_status),
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
expect(status.references.pluck(:id)).to eq [target_status.id]
|
||||
expect(status.quote).to_not be_nil
|
||||
expect(status.quote.id).to eq target_status.id
|
||||
end
|
||||
end
|
||||
|
||||
context 'with language' do
|
||||
let(:to) { 'https://www.w3.org/ns/activitystreams#Public' }
|
||||
let(:object_json) do
|
||||
|
@ -2556,53 +2462,6 @@ RSpec.describe ActivityPub::Activity::Create do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when sender quotes to local status' do
|
||||
subject { described_class.new(json, sender, delivery: true) }
|
||||
|
||||
let!(:local_status) { Fabricate(:status) }
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
type: 'Note',
|
||||
content: 'Lorem ipsum',
|
||||
quote: ActivityPub::TagManager.instance.uri_for(local_status),
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
subject.perform
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
expect(status.text).to eq 'Lorem ipsum'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when sender quotes to non-local status' do
|
||||
subject { described_class.new(json, sender, delivery: true) }
|
||||
|
||||
let!(:remote_status) { Fabricate(:status, uri: 'https://foo.bar/among', account: Fabricate(:account, domain: 'foo.bar', uri: 'https://foo.bar/account')) }
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
type: 'Note',
|
||||
content: 'Lorem ipsum',
|
||||
quote: ActivityPub::TagManager.instance.uri_for(remote_status),
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
subject.perform
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect(sender.statuses.count).to eq 0
|
||||
end
|
||||
end
|
||||
|
||||
context 'when sender targets a local user' do
|
||||
subject { described_class.new(json, sender, delivery: true) }
|
||||
|
||||
|
|
|
@ -8,11 +8,10 @@ RSpec.describe StatusReachFinder do
|
|||
subject { described_class.new(status) }
|
||||
|
||||
let(:parent_status) { nil }
|
||||
let(:quoted_status) { nil }
|
||||
let(:visibility) { :public }
|
||||
let(:searchability) { :public }
|
||||
let(:alice) { Fabricate(:account, username: 'alice') }
|
||||
let(:status) { Fabricate(:status, account: alice, thread: parent_status, quote_of_id: quoted_status&.id, visibility: visibility, searchability: searchability) }
|
||||
let(:status) { Fabricate(:status, account: alice, thread: parent_status, visibility: visibility, searchability: searchability) }
|
||||
|
||||
context 'with a simple case' do
|
||||
let(:bob) { Fabricate(:account, username: 'bob', domain: 'foo.bar', protocol: :activitypub, inbox_url: 'https://foo.bar/inbox') }
|
||||
|
@ -353,15 +352,6 @@ RSpec.describe StatusReachFinder do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it is a quote to a remote account' do
|
||||
let(:bob) { Fabricate(:account, username: 'bob', domain: 'foo.bar', protocol: :activitypub, inbox_url: 'https://foo.bar/inbox') }
|
||||
let(:quoted_status) { Fabricate(:status, account: bob) }
|
||||
|
||||
it 'includes the inbox of the quoted-to account' do
|
||||
expect(subject.inboxes).to include 'https://foo.bar/inbox'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with extended domain block' do
|
||||
|
|
|
@ -397,13 +397,9 @@ RSpec.describe Account do
|
|||
describe '#public_settings_for_local' do
|
||||
subject { account.public_settings_for_local }
|
||||
|
||||
let(:account) { Fabricate(:user, settings: { allow_quote: true, hide_statuses_count: true, emoji_reaction_policy: :followers_only }).account }
|
||||
let(:account) { Fabricate(:user, settings: { hide_statuses_count: true, emoji_reaction_policy: :followers_only }).account }
|
||||
|
||||
shared_examples 'some settings' do |permitted, emoji_reaction_policy|
|
||||
it 'allow_quote is allowed' do
|
||||
expect(subject['allow_quote']).to be permitted.include?(:allow_quote)
|
||||
end
|
||||
|
||||
it 'hide_statuses_count is allowed' do
|
||||
expect(subject['hide_statuses_count']).to be permitted.include?(:hide_statuses_count)
|
||||
end
|
||||
|
@ -417,24 +413,18 @@ RSpec.describe Account do
|
|||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'some settings', %i(allow_quote hide_statuses_count), 'followers_only'
|
||||
it_behaves_like 'some settings', %i(hide_statuses_count), 'followers_only'
|
||||
|
||||
context 'when default true setting is set false' do
|
||||
let(:account) { Fabricate(:user, settings: { allow_quote: false, hide_statuses_count: true, emoji_reaction_policy: :followers_only }).account }
|
||||
let(:account) { Fabricate(:user, settings: { hide_statuses_count: true, emoji_reaction_policy: :followers_only }).account }
|
||||
|
||||
it_behaves_like 'some settings', %i(hide_statuses_count), 'followers_only'
|
||||
end
|
||||
|
||||
context 'when remote user' do
|
||||
let(:account) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/actor', settings: { 'allow_quote' => true, 'hide_statuses_count' => true, 'emoji_reaction_policy' => 'followers_only' }) }
|
||||
let(:account) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/actor', settings: { 'hide_statuses_count' => true, 'emoji_reaction_policy' => 'followers_only' }) }
|
||||
|
||||
it_behaves_like 'some settings', %i(allow_quote hide_statuses_count), 'followers_only'
|
||||
end
|
||||
|
||||
context 'when remote user by server other_settings is not supported' do
|
||||
let(:account) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/actor') }
|
||||
|
||||
it_behaves_like 'some settings', %i(allow_quote), 'allow'
|
||||
it_behaves_like 'some settings', %i(hide_statuses_count), 'followers_only'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -86,39 +86,6 @@ RSpec.describe Status do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#quote' do
|
||||
let(:target_status) { Fabricate(:status) }
|
||||
let(:quote) { true }
|
||||
|
||||
before do
|
||||
Fabricate(:status_reference, status: subject, target_status: target_status, quote: quote)
|
||||
end
|
||||
|
||||
context 'when quoting single' do
|
||||
it 'get quote' do
|
||||
expect(subject.quote).to_not be_nil
|
||||
expect(subject.quote.id).to eq target_status.id
|
||||
end
|
||||
end
|
||||
|
||||
context 'when multiple quotes' do
|
||||
it 'get quote' do
|
||||
target2 = Fabricate(:status)
|
||||
Fabricate(:status_reference, status: subject, quote: quote)
|
||||
expect(subject.quote).to_not be_nil
|
||||
expect([target_status.id, target2.id].include?(subject.quote.id)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no quote but reference' do
|
||||
let(:quote) { false }
|
||||
|
||||
it 'get quote' do
|
||||
expect(subject.quote).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#content' do
|
||||
it 'returns the text of the status if it is not a reblog' do
|
||||
expect(subject.content).to eql subject.text
|
||||
|
|
|
@ -251,30 +251,6 @@ RSpec.describe StatusPolicy, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with the permission of quote?' do
|
||||
permissions :quote? do
|
||||
it 'grants access when viewer is not blocked' do
|
||||
follow = Fabricate(:follow)
|
||||
status.account = follow.target_account
|
||||
|
||||
expect(subject).to permit(follow.account, status)
|
||||
end
|
||||
|
||||
it 'denies when viewer is blocked' do
|
||||
block = Fabricate(:block)
|
||||
status.account = block.target_account
|
||||
|
||||
expect(subject).to_not permit(block.account, status)
|
||||
end
|
||||
|
||||
it 'denies when private visibility' do
|
||||
status.visibility = :private
|
||||
|
||||
expect(subject).to_not permit(Fabricate(:account), status)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with the permission of update?' do
|
||||
permissions :update? do
|
||||
it 'grants access if owner' do
|
||||
|
|
|
@ -170,11 +170,9 @@ RSpec.describe 'Public' do
|
|||
|
||||
let(:exclude_follows) { false }
|
||||
let(:exclude_localusers) { false }
|
||||
let(:include_quotes) { false }
|
||||
let(:account) { user.account }
|
||||
let(:remote_account) { remote_status.account }
|
||||
let!(:filter) { Fabricate(:custom_filter, account: account, exclude_follows: exclude_follows, exclude_localusers: exclude_localusers, with_quote: include_quotes) }
|
||||
let!(:quote_status) { Fabricate(:status, quote: Fabricate(:status, text: 'ohagi')) }
|
||||
let!(:filter) { Fabricate(:custom_filter, account: account, exclude_follows: exclude_follows, exclude_localusers: exclude_localusers) }
|
||||
|
||||
it 'load statuses', :aggregate_failures do
|
||||
ids = subject
|
||||
|
@ -201,16 +199,6 @@ RSpec.describe 'Public' do
|
|||
expect(ids).to_not include(remote_status.id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when include_quotes' do
|
||||
let(:with_quote) { true }
|
||||
|
||||
it 'load statuses', :aggregate_failures do
|
||||
ids = subject
|
||||
expect(ids).to_not include(local_status.id)
|
||||
expect(ids).to include(quote_status.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,14 +16,9 @@ RSpec.describe ActivityPub::NoteSerializer do
|
|||
let!(:reply_by_account_third) { Fabricate(:status, account: account, thread: parent, visibility: :public) }
|
||||
let!(:reply_by_account_visibility_direct) { Fabricate(:status, account: account, thread: parent, visibility: :direct) }
|
||||
let!(:referred) { nil }
|
||||
let!(:quote) { nil }
|
||||
|
||||
before do
|
||||
parent.references << referred if referred.present?
|
||||
if quote.present?
|
||||
parent.references << quote
|
||||
parent.quote = quote
|
||||
end
|
||||
end
|
||||
|
||||
it 'has the expected shape and replies collection' do
|
||||
|
@ -98,23 +93,7 @@ RSpec.describe ActivityPub::NoteSerializer do
|
|||
end
|
||||
|
||||
it 'has as reference' do
|
||||
expect(subject['quoteUri']).to be_nil
|
||||
expect(subject['references']['first']['items']).to include referred.uri
|
||||
end
|
||||
end
|
||||
|
||||
context 'when has a quote' do
|
||||
let(:quote) { Fabricate(:status) }
|
||||
|
||||
it 'has a quote as transitional type' do
|
||||
expect(subject['quoteUri']).to eq ActivityPub::TagManager.instance.uri_for(quote)
|
||||
end
|
||||
|
||||
it 'has a quote as feb-e232 object link' do
|
||||
tag = subject['tag'].detect { |t| t['type'] == 'Link' }
|
||||
expect(tag).to_not be_nil
|
||||
expect(tag['mediaType']).to eq 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
|
||||
expect(tag['href']).to eq ActivityPub::TagManager.instance.uri_for(quote)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,7 +30,6 @@ RSpec.describe NodeInfo::Serializer do
|
|||
end
|
||||
|
||||
it 'returns nodeinfo own features' do
|
||||
expect(serialization['metadata']['features']).to include 'quote'
|
||||
expect(serialization['metadata']['features']).to_not include 'kmyblue_markdown'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -678,7 +678,7 @@ RSpec.describe FanOutOnWriteService do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when updated status is already boosted or quoted' do
|
||||
context 'when updated status is already boosted' do
|
||||
let(:custom_before) { true }
|
||||
|
||||
before do
|
||||
|
@ -695,13 +695,6 @@ RSpec.describe FanOutOnWriteService do
|
|||
expect(notification.activity_id).to eq status.id
|
||||
end
|
||||
|
||||
it 'notified to quoted account', :inline_jobs do
|
||||
notification = Notification.find_by(account: tom, type: 'update')
|
||||
|
||||
expect(notification).to_not be_nil
|
||||
expect(notification.activity_id).to eq status.id
|
||||
end
|
||||
|
||||
it 'notified not to non-boosted account', :inline_jobs do
|
||||
notification = Notification.find_by(account: ohagi, type: 'update')
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ RSpec.describe ProcessReferencesService, type: :service do
|
|||
let(:target_status) { Fabricate(:status, account: Fabricate(:user).account, visibility: target_status_visibility) }
|
||||
let(:target_status_uri) { ActivityPub::TagManager.instance.uri_for(target_status) }
|
||||
let(:quote_urls) { nil }
|
||||
let(:allow_quote) { true }
|
||||
|
||||
def notify?(target_status_id = nil)
|
||||
target_status_id ||= target_status.id
|
||||
|
@ -20,7 +19,6 @@ RSpec.describe ProcessReferencesService, type: :service do
|
|||
|
||||
describe 'posting new status' do
|
||||
subject do
|
||||
target_status.account.user.settings['allow_quote'] = false unless allow_quote
|
||||
target_status.account.user&.save
|
||||
|
||||
described_class.new.call(status, reference_parameters, urls: urls, fetch_remote: fetch_remote, quote_urls: quote_urls)
|
||||
|
@ -42,7 +40,9 @@ RSpec.describe ProcessReferencesService, type: :service do
|
|||
end
|
||||
|
||||
it 'not quote', :inline_jobs do
|
||||
expect(status.quote).to be_nil
|
||||
# TODO: quote
|
||||
expect(status).to_not be_nil # Remove
|
||||
# expect(status.quote).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -89,8 +89,9 @@ RSpec.describe ProcessReferencesService, type: :service do
|
|||
expect(subject.size).to eq 1
|
||||
expect(subject.pluck(0)).to include target_status.id
|
||||
expect(subject.pluck(1)).to include 'QT'
|
||||
expect(status.quote).to_not be_nil
|
||||
expect(status.quote.id).to eq target_status.id
|
||||
# TODO: quote
|
||||
# expect(status.quote).to_not be_nil
|
||||
# expect(status.quote.id).to eq target_status.id
|
||||
expect(notify?).to be true
|
||||
end
|
||||
end
|
||||
|
@ -103,8 +104,9 @@ RSpec.describe ProcessReferencesService, type: :service do
|
|||
expect(subject.size).to eq 1
|
||||
expect(subject.pluck(0)).to include target_status.id
|
||||
expect(subject.pluck(1)).to include 'QT'
|
||||
expect(status.quote).to_not be_nil
|
||||
expect(status.quote.id).to eq target_status.id
|
||||
# TODO: quote
|
||||
# expect(status.quote).to_not be_nil
|
||||
# expect(status.quote.id).to eq target_status.id
|
||||
expect(notify?).to be true
|
||||
end
|
||||
end
|
||||
|
@ -117,8 +119,9 @@ RSpec.describe ProcessReferencesService, type: :service do
|
|||
expect(subject.size).to eq 1
|
||||
expect(subject.pluck(0)).to include target_status.id
|
||||
expect(subject.pluck(1)).to include 'QT'
|
||||
expect(status.quote).to_not be_nil
|
||||
expect(status.quote.id).to eq target_status.id
|
||||
# TODO: quote
|
||||
# expect(status.quote).to_not be_nil
|
||||
# expect(status.quote.id).to eq target_status.id
|
||||
expect(notify?).to be true
|
||||
end
|
||||
end
|
||||
|
@ -131,21 +134,23 @@ RSpec.describe ProcessReferencesService, type: :service do
|
|||
expect(subject.size).to eq 1
|
||||
expect(subject.pluck(0)).to include target_status.id
|
||||
expect(subject.pluck(1)).to include 'QT'
|
||||
expect(status.quote).to_not be_nil
|
||||
expect(status.quote.id).to eq target_status.id
|
||||
# TODO: quote
|
||||
# expect(status.quote).to_not be_nil
|
||||
# expect(status.quote.id).to eq target_status.id
|
||||
expect(notify?).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when quote is rejected' do
|
||||
let(:text) { "Hello QT #{target_status_uri}" }
|
||||
let(:allow_quote) { false }
|
||||
# let(:allow_quote) { false }
|
||||
|
||||
it 'post status', :inline_jobs do
|
||||
expect(subject.size).to eq 1
|
||||
expect(subject.pluck(0)).to include target_status.id
|
||||
expect(subject.pluck(1)).to include 'BT'
|
||||
expect(status.quote).to be_nil
|
||||
# TODO: quote
|
||||
# expect(status.quote).to be_nil
|
||||
expect(notify?).to be true
|
||||
end
|
||||
end
|
||||
|
@ -159,8 +164,9 @@ RSpec.describe ProcessReferencesService, type: :service do
|
|||
expect(subject.size).to eq 2
|
||||
expect(subject).to include [target_status.id, 'QT']
|
||||
expect(subject).to include [target_status2.id, 'BT']
|
||||
expect(status.quote).to_not be_nil
|
||||
expect(status.quote.id).to eq target_status.id
|
||||
# TODO: quote
|
||||
# expect(status.quote).to_not be_nil
|
||||
# expect(status.quote.id).to eq target_status.id
|
||||
expect(notify?).to be true
|
||||
expect(notify?(target_status2.id)).to be true
|
||||
end
|
||||
|
@ -407,7 +413,8 @@ RSpec.describe ProcessReferencesService, type: :service do
|
|||
|
||||
it 'post status', :inline_jobs do
|
||||
expect(subject.size).to eq 0
|
||||
expect(status.quote).to be_nil
|
||||
# TODO: quote
|
||||
# expect(status.quote).to be_nil
|
||||
expect(notify?).to be false
|
||||
end
|
||||
end
|
||||
|
@ -430,8 +437,9 @@ RSpec.describe ProcessReferencesService, type: :service do
|
|||
it 'post status', :inline_jobs do
|
||||
expect(subject.size).to eq 1
|
||||
expect(subject).to include target_status2.id
|
||||
expect(status.quote).to_not be_nil
|
||||
expect(status.quote.id).to eq target_status2.id
|
||||
# TODO: quote
|
||||
# expect(status.quote).to_not be_nil
|
||||
# expect(status.quote.id).to eq target_status2.id
|
||||
expect(notify?(target_status2.id)).to be true
|
||||
end
|
||||
end
|
||||
|
@ -443,7 +451,8 @@ RSpec.describe ProcessReferencesService, type: :service do
|
|||
it 'post status', :inline_jobs do
|
||||
expect(subject.size).to eq 1
|
||||
expect(subject).to include target_status.id
|
||||
expect(status.quote).to be_nil
|
||||
# TODO: quote
|
||||
# expect(status.quote).to be_nil
|
||||
expect(notify?(target_status.id)).to be true
|
||||
end
|
||||
end
|
||||
|
@ -455,8 +464,9 @@ RSpec.describe ProcessReferencesService, type: :service do
|
|||
it 'post status', :inline_jobs do
|
||||
expect(subject.size).to eq 1
|
||||
expect(subject).to include target_status.id
|
||||
expect(status.quote).to_not be_nil
|
||||
expect(status.quote.id).to eq target_status.id
|
||||
# TODO: quote
|
||||
# expect(status.quote).to_not be_nil
|
||||
# expect(status.quote.id).to eq target_status.id
|
||||
expect(notify?(target_status.id)).to be true
|
||||
end
|
||||
end
|
||||
|
|
1159
streaming/index.js
1159
streaming/index.js
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue