1
0
Fork 0
forked from gitea/nas

Merge remote-tracking branch 'parent/main' into upstream-20240913

This commit is contained in:
KMY 2024-09-13 10:31:48 +09:00
commit fc9d27ff91
392 changed files with 3757 additions and 3233 deletions

View file

@ -99,7 +99,7 @@ export const BlockModal = ({ accountId, acct }) => {
<FormattedMessage id='confirmation_modal.cancel' defaultMessage='Cancel' />
</button>
<Button onClick={handleClick}>
<Button onClick={handleClick} autoFocus>
<FormattedMessage id='confirmations.block.confirm' defaultMessage='Block' />
</Button>
</div>

View file

@ -71,7 +71,10 @@ export const ConfirmationModal: React.FC<
/>
</button>
<Button onClick={handleClick}>{confirm}</Button>
{/* eslint-disable-next-line jsx-a11y/no-autofocus -- we are in a modal and thus autofocusing is justified */}
<Button onClick={handleClick} autoFocus>
{confirm}
</Button>
</div>
</div>
</div>

View file

@ -88,7 +88,7 @@ export const DomainBlockModal = ({ domain, accountId, acct }) => {
<FormattedMessage id='confirmation_modal.cancel' defaultMessage='Cancel' />
</button>
<Button onClick={handleClick}>
<Button onClick={handleClick} autoFocus>
<FormattedMessage id='domain_block_modal.block' defaultMessage='Block server' />
</Button>
</div>

View file

@ -1,101 +0,0 @@
import PropTypes from 'prop-types';
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
import api from 'mastodon/api';
import { IconButton } from 'mastodon/components/icon_button';
const messages = defineMessages({
close: { id: 'lightbox.close', defaultMessage: 'Close' },
});
class EmbedModal extends ImmutablePureComponent {
static propTypes = {
id: PropTypes.string.isRequired,
onClose: PropTypes.func.isRequired,
onError: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};
state = {
loading: false,
oembed: null,
};
componentDidMount () {
const { id } = this.props;
this.setState({ loading: true });
api().get(`/api/web/embeds/${id}`).then(res => {
this.setState({ loading: false, oembed: res.data });
const iframeDocument = this.iframe.contentWindow.document;
iframeDocument.open();
iframeDocument.write(res.data.html);
iframeDocument.close();
iframeDocument.body.style.margin = 0;
this.iframe.width = iframeDocument.body.scrollWidth;
this.iframe.height = iframeDocument.body.scrollHeight;
}).catch(error => {
this.props.onError(error);
});
}
setIframeRef = c => {
this.iframe = c;
};
handleTextareaClick = (e) => {
e.target.select();
};
render () {
const { intl, onClose } = this.props;
const { oembed } = this.state;
return (
<div className='modal-root__modal report-modal embed-modal'>
<div className='report-modal__target'>
<IconButton className='media-modal__close' title={intl.formatMessage(messages.close)} icon='times' iconComponent={CloseIcon} onClick={onClose} size={16} />
<FormattedMessage id='status.embed' defaultMessage='Embed' />
</div>
<div className='report-modal__container embed-modal__container' style={{ display: 'block' }}>
<p className='hint'>
<FormattedMessage id='embed.instructions' defaultMessage='Embed this status on your website by copying the code below.' />
</p>
<input
type='text'
className='embed-modal__html'
readOnly
value={oembed && oembed.html || ''}
onClick={this.handleTextareaClick}
/>
<p className='hint'>
<FormattedMessage id='embed.preview' defaultMessage='Here is what it will look like:' />
</p>
<iframe
className='embed-modal__iframe'
frameBorder='0'
ref={this.setIframeRef}
sandbox='allow-scripts allow-same-origin'
title='preview'
/>
</div>
</div>
);
}
}
export default injectIntl(EmbedModal);

View file

@ -0,0 +1,116 @@
import { useRef, useState, useEffect } from 'react';
import { FormattedMessage } from 'react-intl';
import { showAlertForError } from 'mastodon/actions/alerts';
import api from 'mastodon/api';
import { Button } from 'mastodon/components/button';
import { CopyPasteText } from 'mastodon/components/copy_paste_text';
import { useAppDispatch } from 'mastodon/store';
interface OEmbedResponse {
html: string;
}
const EmbedModal: React.FC<{
id: string;
onClose: () => void;
}> = ({ id, onClose }) => {
const iframeRef = useRef<HTMLIFrameElement>(null);
const intervalRef = useRef<ReturnType<typeof setInterval>>();
const [oembed, setOembed] = useState<OEmbedResponse | null>(null);
const dispatch = useAppDispatch();
useEffect(() => {
api()
.get(`/api/web/embeds/${id}`)
.then((res) => {
const data = res.data as OEmbedResponse;
setOembed(data);
const iframeDocument = iframeRef.current?.contentWindow?.document;
if (!iframeDocument) {
return '';
}
iframeDocument.open();
iframeDocument.write(data.html);
iframeDocument.close();
iframeDocument.body.style.margin = '0px';
// This is our best chance to ensure the parent iframe has the correct height...
intervalRef.current = setInterval(
() =>
window.requestAnimationFrame(() => {
if (iframeRef.current) {
iframeRef.current.width = `${iframeDocument.body.scrollWidth}px`;
iframeRef.current.height = `${iframeDocument.body.scrollHeight}px`;
}
}),
100,
);
return '';
})
.catch((error: unknown) => {
dispatch(showAlertForError(error));
});
}, [dispatch, id, setOembed]);
useEffect(
() => () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
}
},
[],
);
return (
<div className='modal-root__modal dialog-modal'>
<div className='dialog-modal__header'>
<Button onClick={onClose}>
<FormattedMessage id='report.close' defaultMessage='Done' />
</Button>
<span className='dialog-modal__header__title'>
<FormattedMessage id='status.embed' defaultMessage='Get embed code' />
</span>
<Button secondary onClick={onClose}>
<FormattedMessage
id='confirmation_modal.cancel'
defaultMessage='Cancel'
/>
</Button>
</div>
<div className='dialog-modal__content'>
<div className='dialog-modal__content__form'>
<FormattedMessage
id='embed.instructions'
defaultMessage='Embed this status on your website by copying the code below.'
/>
<CopyPasteText value={oembed?.html ?? ''} />
<FormattedMessage
id='embed.preview'
defaultMessage='Here is what it will look like:'
/>
<iframe
frameBorder='0'
ref={iframeRef}
sandbox='allow-scripts allow-same-origin'
title='Preview'
/>
</div>
</div>
</div>
);
};
// eslint-disable-next-line import/no-default-export
export default EmbedModal;

View file

@ -137,7 +137,7 @@ export const MuteModal = ({ accountId, acct }) => {
<FormattedMessage id='confirmation_modal.cancel' defaultMessage='Cancel' />
</button>
<Button onClick={handleClick}>
<Button onClick={handleClick} autoFocus>
<FormattedMessage id='confirmations.mute.confirm' defaultMessage='Mute' />
</Button>
</div>

View file

@ -3,10 +3,12 @@ import { connect } from 'react-redux';
import { openModal, closeModal } from '../../../actions/modal';
import ModalRoot from '../components/modal_root';
const defaultProps = {};
const mapStateToProps = state => ({
ignoreFocus: state.getIn(['modal', 'ignoreFocus']),
type: state.getIn(['modal', 'stack', 0, 'modalType'], null),
props: state.getIn(['modal', 'stack', 0, 'modalProps'], {}),
props: state.getIn(['modal', 'stack', 0, 'modalProps'], defaultProps),
});
const mapDispatchToProps = dispatch => ({

View file

@ -4,24 +4,11 @@ import { connect } from 'react-redux';
import { NotificationStack } from 'react-notification';
import { dismissAlert } from '../../../actions/alerts';
import { getAlerts } from '../../../selectors';
const formatIfNeeded = (intl, message, values) => {
if (typeof message === 'object') {
return intl.formatMessage(message, values);
}
return message;
};
import { dismissAlert } from 'mastodon/actions/alerts';
import { getAlerts } from 'mastodon/selectors';
const mapStateToProps = (state, { intl }) => ({
notifications: getAlerts(state).map(alert => ({
...alert,
action: formatIfNeeded(intl, alert.action, alert.values),
title: formatIfNeeded(intl, alert.title, alert.values),
message: formatIfNeeded(intl, alert.message, alert.values),
})),
notifications: getAlerts(state, { intl }),
});
const mapDispatchToProps = (dispatch) => ({

View file

@ -349,8 +349,8 @@ class UI extends PureComponent {
try {
e.dataTransfer.dropEffect = 'copy';
} catch (err) {
} catch {
// do nothing
}
return false;