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'
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue