[build] upgrade eslint to 9.37.0 (#88)

Co-authored-by: tobi <tobi.smethurst@protonmail.com>
Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/88
Co-authored-by: Zoë Bijl <moiety@noreply.codeberg.org>
Co-committed-by: Zoë Bijl <moiety@noreply.codeberg.org>
This commit is contained in:
Zoë Bijl
2025-10-12 13:42:02 +02:00
committed by tobi
parent 75d7a62693
commit 1ff70886a1
975 changed files with 22196 additions and 21964 deletions
@@ -1,46 +1,46 @@
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import PropTypes from "prop-types";
import { PureComponent } from "react";
import { defineMessages, injectIntl } from 'react-intl';
import { defineMessages, injectIntl } from "react-intl";
import classNames from 'classnames';
import classNames from "classnames";
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePropTypes from "react-immutable-proptypes";
import { IconButton } from 'flavours/glitch/components/icon_button';
import DropdownMenuContainer from 'flavours/glitch/containers/dropdown_menu_container';
import { me } from 'flavours/glitch/initial_state';
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'flavours/glitch/permissions';
import { accountAdminLink, statusAdminLink } from 'flavours/glitch/utils/backend_links';
import { IconButton } from "flavours/glitch/components/icon_button";
import DropdownMenuContainer from "flavours/glitch/containers/dropdown_menu_container";
import { me } from "flavours/glitch/initial_state";
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from "flavours/glitch/permissions";
import { accountAdminLink, statusAdminLink } from "flavours/glitch/utils/backend_links";
const messages = defineMessages({
delete: { id: 'status.delete', defaultMessage: 'Delete' },
redraft: { id: 'status.redraft', defaultMessage: 'Delete & re-draft' },
edit: { id: 'status.edit', defaultMessage: 'Edit' },
direct: { id: 'status.direct', defaultMessage: 'Privately mention @{name}' },
mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' },
reply: { id: 'status.reply', defaultMessage: 'Reply' },
reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
reblog_private: { id: 'status.reblog_private', defaultMessage: 'Boost with original visibility' },
cancel_reblog_private: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' },
cannot_reblog: { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be boosted' },
favourite: { id: 'status.favourite', defaultMessage: 'Favorite' },
bookmark: { id: 'status.bookmark', defaultMessage: 'Bookmark' },
more: { id: 'status.more', defaultMessage: 'More' },
mute: { id: 'status.mute', defaultMessage: 'Mute @{name}' },
muteConversation: { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' },
unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
block: { id: 'status.block', defaultMessage: 'Block @{name}' },
report: { id: 'status.report', defaultMessage: 'Report @{name}' },
share: { id: 'status.share', defaultMessage: 'Share' },
pin: { id: 'status.pin', defaultMessage: 'Pin on profile' },
unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
embed: { id: 'status.embed', defaultMessage: 'Embed' },
admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
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' },
openOriginalPage: { id: 'account.open_original_page', defaultMessage: 'Open original page' },
delete: { id: "status.delete", defaultMessage: "Delete" },
redraft: { id: "status.redraft", defaultMessage: "Delete & re-draft" },
edit: { id: "status.edit", defaultMessage: "Edit" },
direct: { id: "status.direct", defaultMessage: "Privately mention @{name}" },
mention: { id: "status.mention", defaultMessage: "Mention @{name}" },
reply: { id: "status.reply", defaultMessage: "Reply" },
reblog: { id: "status.reblog", defaultMessage: "Boost" },
reblog_private: { id: "status.reblog_private", defaultMessage: "Boost with original visibility" },
cancel_reblog_private: { id: "status.cancel_reblog_private", defaultMessage: "Unboost" },
cannot_reblog: { id: "status.cannot_reblog", defaultMessage: "This post cannot be boosted" },
favourite: { id: "status.favourite", defaultMessage: "Favorite" },
bookmark: { id: "status.bookmark", defaultMessage: "Bookmark" },
more: { id: "status.more", defaultMessage: "More" },
mute: { id: "status.mute", defaultMessage: "Mute @{name}" },
muteConversation: { id: "status.mute_conversation", defaultMessage: "Mute conversation" },
unmuteConversation: { id: "status.unmute_conversation", defaultMessage: "Unmute conversation" },
block: { id: "status.block", defaultMessage: "Block @{name}" },
report: { id: "status.report", defaultMessage: "Report @{name}" },
share: { id: "status.share", defaultMessage: "Share" },
pin: { id: "status.pin", defaultMessage: "Pin on profile" },
unpin: { id: "status.unpin", defaultMessage: "Unpin from profile" },
embed: { id: "status.embed", defaultMessage: "Embed" },
admin_account: { id: "status.admin_account", defaultMessage: "Open moderation interface for @{name}" },
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" },
openOriginalPage: { id: "account.open_original_page", defaultMessage: "Open original page" },
});
class ActionBar extends PureComponent {
@@ -98,15 +98,15 @@ class ActionBar extends PureComponent {
};
handleDirectClick = () => {
this.props.onDirect(this.props.status.get('account'), this.context.router.history);
this.props.onDirect(this.props.status.get("account"), this.context.router.history);
};
handleMentionClick = () => {
this.props.onMention(this.props.status.get('account'), this.context.router.history);
this.props.onMention(this.props.status.get("account"), this.context.router.history);
};
handleMuteClick = () => {
this.props.onMute(this.props.status.get('account'));
this.props.onMute(this.props.status.get("account"));
};
handleConversationMuteClick = () => {
@@ -127,7 +127,7 @@ class ActionBar extends PureComponent {
handleShare = () => {
navigator.share({
url: this.props.status.get('url'),
url: this.props.status.get("url"),
});
};
@@ -136,7 +136,7 @@ class ActionBar extends PureComponent {
};
handleCopy = () => {
const url = this.props.status.get('url');
const url = this.props.status.get("url");
navigator.clipboard.writeText(url);
};
@@ -144,21 +144,21 @@ class ActionBar extends PureComponent {
const { status, intl } = this.props;
const { signedIn, permissions } = this.context.identity;
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'));
const pinnableStatus = ['public', 'unlisted', 'private'].includes(status.get('visibility'));
const mutingConversation = status.get('muted');
const writtenByMe = status.getIn(['account', 'id']) === me;
const isRemote = status.getIn(['account', 'username']) !== status.getIn(['account', 'acct']);
const publicStatus = ["public", "unlisted"].includes(status.get("visibility"));
const pinnableStatus = ["public", "unlisted", "private"].includes(status.get("visibility"));
const mutingConversation = status.get("muted");
const writtenByMe = status.getIn(["account", "id"]) === me;
const isRemote = status.getIn(["account", "username"]) !== status.getIn(["account", "acct"]);
let menu = [];
if (publicStatus && isRemote) {
menu.push({ text: intl.formatMessage(messages.openOriginalPage), href: status.get('url') });
menu.push({ text: intl.formatMessage(messages.openOriginalPage), href: status.get("url") });
}
menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy });
if (publicStatus && 'share' in navigator) {
if (publicStatus && "share" in navigator) {
menu.push({ text: intl.formatMessage(messages.share), action: this.handleShare });
}
@@ -171,7 +171,7 @@ class ActionBar extends PureComponent {
if (writtenByMe) {
if (pinnableStatus) {
menu.push({ text: intl.formatMessage(status.get('pinned') ? messages.unpin : messages.pin), action: this.handlePinClick });
menu.push({ text: intl.formatMessage(status.get("pinned") ? messages.unpin : messages.pin), action: this.handlePinClick });
menu.push(null);
}
@@ -181,34 +181,34 @@ class ActionBar extends PureComponent {
menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick, dangerous: true });
menu.push({ text: intl.formatMessage(messages.redraft), action: this.handleRedraftClick, dangerous: true });
} else {
menu.push({ text: intl.formatMessage(messages.mention, { name: status.getIn(['account', 'username']) }), action: this.handleMentionClick });
menu.push({ text: intl.formatMessage(messages.direct, { name: status.getIn(['account', 'username']) }), action: this.handleDirectClick });
menu.push({ text: intl.formatMessage(messages.mention, { name: status.getIn(["account", "username"]) }), action: this.handleMentionClick });
menu.push({ text: intl.formatMessage(messages.direct, { name: status.getIn(["account", "username"]) }), action: this.handleDirectClick });
menu.push(null);
menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick, dangerous: true });
menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick, dangerous: true });
menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport, dangerous: true });
menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(["account", "username"]) }), action: this.handleMuteClick, dangerous: true });
menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(["account", "username"]) }), action: this.handleBlockClick, dangerous: true });
menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(["account", "username"]) }), action: this.handleReport, dangerous: true });
if (((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS && (accountAdminLink || statusAdminLink)) || (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION)) {
menu.push(null);
if ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) {
if (accountAdminLink !== undefined) {
menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: accountAdminLink(status.getIn(['account', 'id'])) });
menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(["account", "username"]) }), href: accountAdminLink(status.getIn(["account", "id"])) });
}
if (statusAdminLink !== undefined) {
menu.push({ text: intl.formatMessage(messages.admin_status), href: statusAdminLink(status.getIn(['account', 'id']), status.get('id')) });
menu.push({ text: intl.formatMessage(messages.admin_status), href: statusAdminLink(status.getIn(["account", "id"]), status.get("id")) });
}
}
if (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION) {
const domain = status.getIn(['account', 'acct']).split('@')[1];
const domain = status.getIn(["account", "acct"]).split("@")[1];
menu.push({ text: intl.formatMessage(messages.admin_domain, { domain: domain }), href: `/admin/instances/${domain}` });
}
}
}
}
const reblogPrivate = status.getIn(['account', 'id']) === me && status.get('visibility') === 'private';
const reblogPrivate = status.getIn(["account", "id"]) === me && status.get("visibility") === "private";
let reblogTitle;
if (status.get('reblogged')) {
if (status.get("reblogged")) {
reblogTitle = intl.formatMessage(messages.cancel_reblog_private);
} else if (publicStatus) {
reblogTitle = intl.formatMessage(messages.reblog);
@@ -220,10 +220,10 @@ class ActionBar extends PureComponent {
return (
<div className='detailed-status__action-bar'>
<div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.reply)} icon={status.get('in_reply_to_id', null) === null ? 'reply' : 'reply-all'} onClick={this.handleReplyClick} /></div>
<div className='detailed-status__button'><IconButton className={classNames({ reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' onClick={this.handleReblogClick} /></div>
<div className='detailed-status__button'><IconButton className='star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} /></div>
<div className='detailed-status__button'><IconButton className='bookmark-icon' disabled={!signedIn} active={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' onClick={this.handleBookmarkClick} /></div>
<div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.reply)} icon={status.get("in_reply_to_id", null) === null ? "reply" : "reply-all"} onClick={this.handleReplyClick} /></div>
<div className='detailed-status__button'><IconButton className={classNames({ reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get("reblogged")} title={reblogTitle} icon='retweet' onClick={this.handleReblogClick} /></div>
<div className='detailed-status__button'><IconButton className='star-icon' animate active={status.get("favourited")} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} /></div>
<div className='detailed-status__button'><IconButton className='bookmark-icon' disabled={!signedIn} active={status.get("bookmarked")} title={intl.formatMessage(messages.bookmark)} icon='bookmark' onClick={this.handleBookmarkClick} /></div>
<div className='detailed-status__action-bar-dropdown'>
<DropdownMenuContainer size={18} icon='ellipsis-h' items={menu} direction='left' title={intl.formatMessage(messages.more)} />
@@ -1,19 +1,19 @@
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import PropTypes from "prop-types";
import { PureComponent } from "react";
import { FormattedMessage } from 'react-intl';
import { FormattedMessage } from "react-intl";
import classnames from 'classnames';
import classnames from "classnames";
import Immutable from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes';
import Immutable from "immutable";
import ImmutablePropTypes from "react-immutable-proptypes";
import { Blurhash } from 'flavours/glitch/components/blurhash';
import { Icon } from 'flavours/glitch/components/icon';
import { decode as decodeIDNA } from 'flavours/glitch/utils/idna';
import { Blurhash } from "flavours/glitch/components/blurhash";
import { Icon } from "flavours/glitch/components/icon";
import { decode as decodeIDNA } from "flavours/glitch/utils/idna";
const getHostname = url => {
const parser = document.createElement('a');
const parser = document.createElement("a");
parser.href = url;
return parser.hostname;
};
@@ -21,21 +21,21 @@ const getHostname = url => {
const domParser = new DOMParser();
const addAutoPlay = html => {
const document = domParser.parseFromString(html, 'text/html').documentElement;
const iframe = document.querySelector('iframe');
const document = domParser.parseFromString(html, "text/html").documentElement;
const iframe = document.querySelector("iframe");
if (iframe) {
if (iframe.src.indexOf('?') !== -1) {
iframe.src += '&';
if (iframe.src.indexOf("?") !== -1) {
iframe.src += "&";
} else {
iframe.src += '?';
iframe.src += "?";
}
iframe.src += 'autoplay=1&auto_play=1';
iframe.src += "autoplay=1&auto_play=1";
// DOM parser creates html/body elements around original HTML fragment,
// so we need to get innerHTML out of the body and not the entire document
return document.querySelector('body').innerHTML;
return document.querySelector("body").innerHTML;
}
return html;
@@ -71,11 +71,11 @@ export default class Card extends PureComponent {
}
componentDidMount () {
window.addEventListener('resize', this.handleResize, { passive: true });
window.addEventListener("resize", this.handleResize, { passive: true });
}
componentWillUnmount () {
window.removeEventListener('resize', this.handleResize);
window.removeEventListener("resize", this.handleResize);
}
handlePhotoClick = () => {
@@ -84,13 +84,13 @@ export default class Card extends PureComponent {
onOpenMedia(
Immutable.fromJS([
{
type: 'image',
url: card.get('embed_url'),
description: card.get('title'),
type: "image",
url: card.get("embed_url"),
description: card.get("title"),
meta: {
original: {
width: card.get('width'),
height: card.get('height'),
width: card.get("width"),
height: card.get("height"),
},
},
},
@@ -102,7 +102,7 @@ export default class Card extends PureComponent {
handleEmbedClick = () => {
const { card } = this.props;
if (card.get('type') === 'photo') {
if (card.get("type") === "photo") {
this.handlePhotoClick();
} else {
this.setState({ embedded: true });
@@ -125,14 +125,14 @@ export default class Card extends PureComponent {
renderVideo () {
const { card } = this.props;
const content = { __html: addAutoPlay(card.get('html')) };
const content = { __html: addAutoPlay(card.get("html")) };
return (
<div
ref={this.setRef}
className='status-card__image status-card-video'
dangerouslySetInnerHTML={content}
style={{ aspectRatio: `${card.get('width')} / ${card.get('height')}` }}
style={{ aspectRatio: `${card.get("width")} / ${card.get("height")}` }}
/>
);
}
@@ -145,41 +145,41 @@ export default class Card extends PureComponent {
return null;
}
const provider = card.get('provider_name').length === 0 ? decodeIDNA(getHostname(card.get('url'))) : card.get('provider_name');
const horizontal = (!compact && card.get('width') > card.get('height')) || card.get('type') !== 'link' || embedded;
const interactive = card.get('type') !== 'link';
const className = classnames('status-card', { horizontal, compact, interactive });
const title = interactive ? <a className='status-card__title' href={card.get('url')} title={card.get('title')} rel='noopener noreferrer' target='_blank'><strong>{card.get('title')}</strong></a> : <strong className='status-card__title' title={card.get('title')}>{card.get('title')}</strong>;
const language = card.get('language') || '';
const provider = card.get("provider_name").length === 0 ? decodeIDNA(getHostname(card.get("url"))) : card.get("provider_name");
const horizontal = (!compact && card.get("width") > card.get("height")) || card.get("type") !== "link" || embedded;
const interactive = card.get("type") !== "link";
const className = classnames("status-card", { horizontal, compact, interactive });
const title = interactive ? <a className='status-card__title' href={card.get("url")} title={card.get("title")} rel='noopener noreferrer' target='_blank'><strong>{card.get("title")}</strong></a> : <strong className='status-card__title' title={card.get("title")}>{card.get("title")}</strong>;
const language = card.get("language") || "";
const description = (
<div className='status-card__content' lang={language}>
{title}
{!(horizontal || compact) && <p className='status-card__description' title={card.get('description')}>{card.get('description')}</p>}
{!(horizontal || compact) && <p className='status-card__description' title={card.get("description")}>{card.get("description")}</p>}
<span className='status-card__host'>{provider}</span>
</div>
);
const thumbnailStyle = {
visibility: revealed? null : 'hidden',
visibility: revealed? null : "hidden",
};
if (horizontal) {
thumbnailStyle.aspectRatio = (compact && !embedded) ? '16 / 9' : `${card.get('width')} / ${card.get('height')}`;
thumbnailStyle.aspectRatio = (compact && !embedded) ? "16 / 9" : `${card.get("width")} / ${card.get("height")}`;
}
let embed = '';
let embed = "";
let canvas = (
<Blurhash
className={classnames('status-card__image-preview', {
'status-card__image-preview--hidden': revealed && this.state.previewLoaded,
className={classnames("status-card__image-preview", {
"status-card__image-preview--hidden": revealed && this.state.previewLoaded,
})}
hash={card.get('blurhash')}
hash={card.get("blurhash")}
dummy={!useBlurhash}
/>
);
const thumbnailDescription = card.get('image_description');
const thumbnail = <img src={card.get('image')} alt={thumbnailDescription} title={thumbnailDescription} lang={language} style={thumbnailStyle} onLoad={this.handleImageLoad} className='status-card__image-image' />;
const thumbnailDescription = card.get("image_description");
const thumbnail = <img src={card.get("image")} alt={thumbnailDescription} title={thumbnailDescription} lang={language} style={thumbnailStyle} onLoad={this.handleImageLoad} className='status-card__image-image' />;
let spoilerButton = (
<button type='button' onClick={this.handleReveal} className='spoiler-button__overlay'>
<span className='spoiler-button__overlay__label'>
@@ -189,7 +189,7 @@ export default class Card extends PureComponent {
</button>
);
spoilerButton = (
<div className={classnames('spoiler-button', { 'spoiler-button--minified': revealed })}>
<div className={classnames("spoiler-button", { "spoiler-button--minified": revealed })}>
{spoilerButton}
</div>
);
@@ -198,10 +198,10 @@ export default class Card extends PureComponent {
if (embedded) {
embed = this.renderVideo();
} else {
let iconVariant = 'play';
let iconVariant = "play";
if (card.get('type') === 'photo') {
iconVariant = 'search-plus';
if (card.get("type") === "photo") {
iconVariant = "search-plus";
}
embed = (
@@ -213,7 +213,7 @@ export default class Card extends PureComponent {
<div className='status-card__actions'>
<div>
<button onClick={this.handleEmbedClick}><Icon id={iconVariant} /></button>
{horizontal && <a href={card.get('url')} target='_blank' rel='noopener noreferrer'><Icon id='external-link' /></a>}
{horizontal && <a href={card.get("url")} target='_blank' rel='noopener noreferrer'><Icon id='external-link' /></a>}
</div>
</div>
)}
@@ -223,12 +223,12 @@ export default class Card extends PureComponent {
}
return (
<div className={className} ref={this.setRef} onClick={revealed ? null : this.handleReveal} role={revealed ? 'button' : null}>
<div className={className} ref={this.setRef} onClick={revealed ? null : this.handleReveal} role={revealed ? "button" : null}>
{embed}
{!compact && description}
</div>
);
} else if (card.get('image')) {
} else if (card.get("image")) {
embed = (
<div className='status-card__image'>
{canvas}
@@ -244,7 +244,7 @@ export default class Card extends PureComponent {
}
return (
<a href={card.get('url')} className={className} target='_blank' rel='noopener noreferrer' ref={this.setRef}>
<a href={card.get("url")} className={className} target='_blank' rel='noopener noreferrer' ref={this.setRef}>
{embed}
{description}
</a>
@@ -1,30 +1,30 @@
import PropTypes from 'prop-types';
import PropTypes from "prop-types";
import { injectIntl, FormattedDate } from 'react-intl';
import { injectIntl, FormattedDate } from "react-intl";
import classNames from 'classnames';
import { Link } from 'react-router-dom';
import classNames from "classnames";
import { Link } from "react-router-dom";
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import ImmutablePropTypes from "react-immutable-proptypes";
import ImmutablePureComponent from "react-immutable-pure-component";
import { AnimatedNumber } from 'flavours/glitch/components/animated_number';
import AttachmentList from 'flavours/glitch/components/attachment_list';
import { Avatar } from 'flavours/glitch/components/avatar';
import { DisplayName } from 'flavours/glitch/components/display_name';
import EditedTimestamp from 'flavours/glitch/components/edited_timestamp';
import { Icon } from 'flavours/glitch/components/icon';
import MediaGallery from 'flavours/glitch/components/media_gallery';
import PictureInPicturePlaceholder from 'flavours/glitch/components/picture_in_picture_placeholder';
import StatusContent from 'flavours/glitch/components/status_content';
import VisibilityIcon from 'flavours/glitch/components/status_visibility_icon';
import PollContainer from 'flavours/glitch/containers/poll_container';
import Audio from 'flavours/glitch/features/audio';
import Video from 'flavours/glitch/features/video';
import { AnimatedNumber } from "flavours/glitch/components/animated_number";
import AttachmentList from "flavours/glitch/components/attachment_list";
import { Avatar } from "flavours/glitch/components/avatar";
import { DisplayName } from "flavours/glitch/components/display_name";
import EditedTimestamp from "flavours/glitch/components/edited_timestamp";
import { Icon } from "flavours/glitch/components/icon";
import MediaGallery from "flavours/glitch/components/media_gallery";
import PictureInPicturePlaceholder from "flavours/glitch/components/picture_in_picture_placeholder";
import StatusContent from "flavours/glitch/components/status_content";
import VisibilityIcon from "flavours/glitch/components/status_visibility_icon";
import PollContainer from "flavours/glitch/containers/poll_container";
import Audio from "flavours/glitch/features/audio";
import Video from "flavours/glitch/features/video";
import scheduleIdleTask from '../../ui/util/schedule_idle_task';
import scheduleIdleTask from "../../ui/util/schedule_idle_task";
import Card from './card';
import Card from "./card";
@@ -63,7 +63,7 @@ class DetailedStatus extends ImmutablePureComponent {
handleAccountClick = (e) => {
if (e.button === 0 && !(e.ctrlKey || e.altKey || e.metaKey) && this.context.router) {
e.preventDefault();
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
this.context.router.history.push(`/@${this.props.status.getIn(["account", "acct"])}`);
}
e.stopPropagation();
@@ -79,7 +79,7 @@ class DetailedStatus extends ImmutablePureComponent {
};
handleOpenVideo = (options) => {
this.props.onOpenVideo(this.props.status.getIn(['media_attachments', 0]), options);
this.props.onOpenVideo(this.props.status.getIn(["media_attachments", 0]), options);
};
_measureHeight (heightJustChanged) {
@@ -110,13 +110,13 @@ class DetailedStatus extends ImmutablePureComponent {
let href;
if (e.target.nodeName !== 'A') {
if (e.target.nodeName !== "A") {
href = e.target.parentNode.href;
} else {
href = e.target.href;
}
window.open(href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
window.open(href, "mastodon-intent", "width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes");
};
handleTranslate = () => {
@@ -125,19 +125,19 @@ class DetailedStatus extends ImmutablePureComponent {
};
render () {
const status = (this.props.status && this.props.status.get('reblog')) ? this.props.status.get('reblog') : this.props.status;
const outerStyle = { boxSizing: 'border-box' };
const status = (this.props.status && this.props.status.get("reblog")) ? this.props.status.get("reblog") : this.props.status;
const outerStyle = { boxSizing: "border-box" };
const { compact, pictureInPicture, expanded, onToggleHidden, settings } = this.props;
if (!status) {
return null;
}
let applicationLink = '';
let reblogLink = '';
let reblogIcon = 'retweet';
let favouriteLink = '';
let edited = '';
let applicationLink = "";
let reblogLink = "";
let reblogIcon = "retweet";
let favouriteLink = "";
let edited = "";
// Depending on user settings, some media are considered as parts of the
// contents (affected by CW) while other will be displayed outside of the
@@ -149,7 +149,7 @@ class DetailedStatus extends ImmutablePureComponent {
let media = contentMedia;
let mediaIcons = contentMediaIcons;
if (settings.getIn(['content_warnings', 'media_outside'])) {
if (settings.getIn(["content_warnings", "media_outside"])) {
media = extraMedia;
mediaIcons = extraMediaIcons;
}
@@ -158,118 +158,118 @@ class DetailedStatus extends ImmutablePureComponent {
outerStyle.height = `${this.state.height}px`;
}
const language = status.getIn(['translation', 'language']) || status.get('language');
const language = status.getIn(["translation", "language"]) || status.get("language");
if (pictureInPicture.get('inUse')) {
if (pictureInPicture.get("inUse")) {
media.push(<PictureInPicturePlaceholder />);
mediaIcons.push('video-camera');
} else if (status.get('media_attachments').size > 0) {
if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) {
media.push(<AttachmentList 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');
mediaIcons.push("video-camera");
} else if (status.get("media_attachments").size > 0) {
if (status.get("media_attachments").some(item => item.get("type") === "unknown")) {
media.push(<AttachmentList 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.push(
<Audio
src={attachment.get('url')}
src={attachment.get("url")}
alt={description}
lang={language}
duration={attachment.getIn(['meta', 'original', 'duration'], 0)}
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'])}
sensitive={status.get('sensitive')}
duration={attachment.getIn(["meta", "original", "duration"], 0)}
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"])}
sensitive={status.get("sensitive")}
visible={this.props.showMedia}
blurhash={attachment.get('blurhash')}
blurhash={attachment.get("blurhash")}
height={150}
onToggleVisibility={this.props.onToggleMediaVisibility}
useBlurhash={settings.getIn(['media', 'use_blurhash'])}
useBlurhash={settings.getIn(["media", "use_blurhash"])}
/>,
);
mediaIcons.push('music');
} 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');
mediaIcons.push("music");
} 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.push(
<Video
preview={attachment.get('preview_url')}
frameRate={attachment.getIn(['meta', 'original', 'frame_rate'])}
blurhash={attachment.get('blurhash')}
src={attachment.get('url')}
preview={attachment.get("preview_url")}
frameRate={attachment.getIn(["meta", "original", "frame_rate"])}
blurhash={attachment.get("blurhash")}
src={attachment.get("url")}
alt={description}
lang={language}
inline
sensitive={status.get('sensitive')}
letterbox={settings.getIn(['media', 'letterbox'])}
fullwidth={settings.getIn(['media', 'fullwidth'])}
sensitive={status.get("sensitive")}
letterbox={settings.getIn(["media", "letterbox"])}
fullwidth={settings.getIn(["media", "fullwidth"])}
preventPlayback={!expanded}
onOpenVideo={this.handleOpenVideo}
autoplay
visible={this.props.showMedia}
onToggleVisibility={this.props.onToggleMediaVisibility}
useBlurhash={settings.getIn(['media', 'use_blurhash'])}
useBlurhash={settings.getIn(["media", "use_blurhash"])}
/>,
);
mediaIcons.push('video-camera');
mediaIcons.push("video-camera");
} else {
media.push(
<MediaGallery
standalone
sensitive={status.get('sensitive')}
media={status.get('media_attachments')}
sensitive={status.get("sensitive")}
media={status.get("media_attachments")}
lang={language}
letterbox={settings.getIn(['media', 'letterbox'])}
fullwidth={settings.getIn(['media', 'fullwidth'])}
letterbox={settings.getIn(["media", "letterbox"])}
fullwidth={settings.getIn(["media", "fullwidth"])}
hidden={!expanded}
onOpenMedia={this.props.onOpenMedia}
visible={this.props.showMedia}
onToggleVisibility={this.props.onToggleMediaVisibility}
useBlurhash={settings.getIn(['media', 'use_blurhash'])}
useBlurhash={settings.getIn(["media", "use_blurhash"])}
/>,
);
mediaIcons.push('picture-o');
mediaIcons.push("picture-o");
}
} else if (status.get('card')) {
} else if (status.get("card")) {
media.push(
<Card
sensitive={status.get('sensitive')}
sensitive={status.get("sensitive")}
onOpenMedia={this.props.onOpenMedia}
card={status.get('card')}
useBlurhash={settings.getIn(['media', 'use_blurhash'])} />
card={status.get("card")}
useBlurhash={settings.getIn(["media", "use_blurhash"])} />,
);
mediaIcons.push('link');
mediaIcons.push("link");
}
if (status.get('poll')) {
contentMedia.push(<PollContainer pollId={status.get('poll')} lang={status.get('language')} />);
contentMediaIcons.push('tasks');
if (status.get("poll")) {
contentMedia.push(<PollContainer pollId={status.get("poll")} lang={status.get("language")} />);
contentMediaIcons.push("tasks");
}
if (status.get('application')) {
applicationLink = <> · <a className='detailed-status__application' href={status.getIn(['application', 'website'])} target='_blank' rel='noopener noreferrer'>{status.getIn(['application', 'name'])}</a></>;
if (status.get("application")) {
applicationLink = <> · <a className='detailed-status__application' href={status.getIn(["application", "website"])} target='_blank' rel='noopener noreferrer'>{status.getIn(["application", "name"])}</a></>;
}
const visibilityLink = <> · <VisibilityIcon visibility={status.get('visibility')} /></>;
const visibilityLink = <> · <VisibilityIcon visibility={status.get("visibility")} /></>;
if (status.get('visibility') === 'direct') {
reblogIcon = 'envelope';
} else if (status.get('visibility') === 'private') {
reblogIcon = 'lock';
if (status.get("visibility") === "direct") {
reblogIcon = "envelope";
} else if (status.get("visibility") === "private") {
reblogIcon = "lock";
}
if (!['unlisted', 'public'].includes(status.get('visibility'))) {
if (!["unlisted", "public"].includes(status.get("visibility"))) {
reblogLink = null;
} else if (this.context.router) {
reblogLink = (
<>
{' · '}
<Link to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}/reblogs`} className='detailed-status__link'>
{" · "}
<Link to={`/@${status.getIn(["account", "acct"])}/${status.get("id")}/reblogs`} className='detailed-status__link'>
<Icon id={reblogIcon} />
<span className='detailed-status__reblogs'>
<AnimatedNumber value={status.get('reblogs_count')} />
<AnimatedNumber value={status.get("reblogs_count")} />
</span>
</Link>
</>
@@ -277,11 +277,11 @@ class DetailedStatus extends ImmutablePureComponent {
} else {
reblogLink = (
<>
{' · '}
<a href={`/interact/${status.get('id')}?type=reblog`} className='detailed-status__link' onClick={this.handleModalLink}>
{" · "}
<a href={`/interact/${status.get("id")}?type=reblog`} className='detailed-status__link' onClick={this.handleModalLink}>
<Icon id={reblogIcon} />
<span className='detailed-status__reblogs'>
<AnimatedNumber value={status.get('reblogs_count')} />
<AnimatedNumber value={status.get("reblogs_count")} />
</span>
</a>
</>
@@ -290,39 +290,39 @@ class DetailedStatus extends ImmutablePureComponent {
if (this.context.router) {
favouriteLink = (
<Link to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}/favourites`} className='detailed-status__link'>
<Link to={`/@${status.getIn(["account", "acct"])}/${status.get("id")}/favourites`} className='detailed-status__link'>
<Icon id='star' />
<span className='detailed-status__favorites'>
<AnimatedNumber value={status.get('favourites_count')} />
<AnimatedNumber value={status.get("favourites_count")} />
</span>
</Link>
);
} else {
favouriteLink = (
<a href={`/interact/${status.get('id')}?type=favourite`} className='detailed-status__link' onClick={this.handleModalLink}>
<a href={`/interact/${status.get("id")}?type=favourite`} className='detailed-status__link' onClick={this.handleModalLink}>
<Icon id='star' />
<span className='detailed-status__favorites'>
<AnimatedNumber value={status.get('favourites_count')} />
<AnimatedNumber value={status.get("favourites_count")} />
</span>
</a>
);
}
if (status.get('edited_at')) {
if (status.get("edited_at")) {
edited = (
<>
{' · '}
<EditedTimestamp statusId={status.get('id')} timestamp={status.get('edited_at')} />
{" · "}
<EditedTimestamp statusId={status.get("id")} timestamp={status.get("edited_at")} />
</>
);
}
return (
<div style={outerStyle}>
<div ref={this.setRef} className={classNames('detailed-status', `detailed-status-${status.get('visibility')}`, { compact })} data-status-by={status.getIn(['account', 'acct'])}>
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='detailed-status__display-name'>
<div className='detailed-status__display-avatar'><Avatar account={status.get('account')} size={48} /></div>
<DisplayName account={status.get('account')} localDomain={this.props.domain} />
<div ref={this.setRef} className={classNames("detailed-status", `detailed-status-${status.get("visibility")}`, { compact })} data-status-by={status.getIn(["account", "acct"])}>
<a href={status.getIn(["account", "url"])} onClick={this.handleAccountClick} className='detailed-status__display-name'>
<div className='detailed-status__display-avatar'><Avatar account={status.get("account")} size={48} /></div>
<DisplayName account={status.get("account")} localDomain={this.props.domain} />
</a>
<StatusContent
@@ -336,14 +336,14 @@ class DetailedStatus extends ImmutablePureComponent {
onTranslate={this.handleTranslate}
parseClick={this.parseClick}
onUpdate={this.handleChildUpdate}
tagLinks={settings.get('tag_misleading_links')}
rewriteMentions={settings.get('rewrite_mentions')}
tagLinks={settings.get("tag_misleading_links")}
rewriteMentions={settings.get("rewrite_mentions")}
disabled
/>
<div className='detailed-status__meta'>
<a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener noreferrer'>
<FormattedDate value={new Date(status.get('created_at'))} hourCycle='h23' year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
<a className='detailed-status__datetime' href={status.get("url")} target='_blank' rel='noopener noreferrer'>
<FormattedDate value={new Date(status.get("created_at"))} hourCycle='h23' year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
</a>{edited}{visibilityLink}{applicationLink}{reblogLink} · {favouriteLink}
</div>
</div>