Remove: kmyblue独自機能の引用
This commit is contained in:
parent
620a895184
commit
d845d1e9fb
70 changed files with 812 additions and 1788 deletions
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue