add CI, lint files
Some checks failed
ci/woodpecker/tag/woodpecker Pipeline failed

This commit is contained in:
FloatingGhost 2022-06-17 11:43:45 +01:00
parent d7088dbd06
commit 29278e8802
71 changed files with 254 additions and 186 deletions

49
.woodpecker.yml Normal file
View file

@ -0,0 +1,49 @@
pipeline:
lint:
when:
event:
- push
- pull_request
image: node:16
commands:
- yarn
- yarn test:lint
test:
when:
event:
- push
- pull_request
image: node:16
commands:
- apt update
- apt install firefox-esr -y --no-install-recommends
- yarn
- yarn test
build:
when:
event:
- tag
image: node:16
commands:
- yarn
- TARGET=distribution ./build.sh
release:
when:
event:
- tag
image: node:16
secrets:
- SCW_ACCESS_KEY
- SCW_SECRET_KEY
- SCW_DEFAULT_ORGANIZATION_ID
commands:
- apt-get update && apt-get install -y rclone wget zip
- wget https://github.com/scaleway/scaleway-cli/releases/download/v2.5.1/scaleway-cli_2.5.1_linux_amd64
- mv scaleway-cli_2.5.1_linux_amd64 scaleway-cli
- chmod +x scaleway-cli
- ./scaleway-cli object config install type=rclone
- zip mastofe.zip -r distribution
- rclone copyto akkoma-fe.zip scaleway:akkoma-updates/frontend/$CI_COMMIT_BRANCH/masto-fe.zip

View file

@ -1,7 +1,9 @@
// This file will be loaded on settings pages, regardless of theme.
import escapeTextContentForBrowser from 'escape-html';
const { delegate } = require('@rails/ujs');
import emojify from '../mastodon/features/emoji/emoji';
delegate(document, '#account_display_name', 'input', ({ target }) => {
@ -62,7 +64,7 @@ delegate(document, '.input-copy button', 'click', ({ target }) => {
input.blur();
target.parentNode.classList.add('copied');
setTimeout(() => {
setTimeout(() => {
target.parentNode.classList.remove('copied');
}, 700);
}

View file

@ -760,7 +760,7 @@ export function fetchPinnedAccounts() {
return (dispatch, getState) => {
dispatch(fetchPinnedAccountsRequest());
api(getState).get(`/api/v1/endorsements`, { params: { limit: 0 } }).then(response => {
api(getState).get('/api/v1/endorsements', { params: { limit: 0 } }).then(response => {
dispatch(importFetchedAccounts(response.data));
dispatch(fetchPinnedAccountsSuccess(response.data));
}).catch(err => dispatch(fetchPinnedAccountsFail(err)));
@ -822,7 +822,7 @@ export function changePinnedAccountsSuggestions(value) {
return {
type: PINNED_ACCOUNTS_EDITOR_SUGGESTIONS_CHANGE,
value,
}
};
};
export function resetPinnedAccountsEditor() {

View file

@ -246,34 +246,34 @@ export function uploadCompose(files) {
for (const [i, file] of Array.from(files).entries()) {
if (media.size + i > 3) break;
const data = new FormData();
data.append('file', file);
const data = new FormData();
data.append('file', file);
return api(getState).post('/api/v2/media', data, {
onUploadProgress: function({ loaded }){
progress[i] = loaded;
dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
},
}).then(({ status, data }) => {
// If server-side processing of the media attachment has not completed yet,
// poll the server until it is, before showing the media attachment as uploaded
return api(getState).post('/api/v2/media', data, {
onUploadProgress: function({ loaded }){
progress[i] = loaded;
dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
},
}).then(({ status, data }) => {
// If server-side processing of the media attachment has not completed yet,
// poll the server until it is, before showing the media attachment as uploaded
if (status === 200) {
dispatch(uploadComposeSuccess(data, file));
} else if (status === 202) {
const poll = () => {
api(getState).get(`/api/v1/media/${data.id}`).then(response => {
if (response.status === 200) {
dispatch(uploadComposeSuccess(response.data, file));
} else if (response.status === 206) {
setTimeout(() => poll(), 1000);
}
}).catch(error => dispatch(uploadComposeFail(error)));
};
if (status === 200) {
dispatch(uploadComposeSuccess(data, file));
} else if (status === 202) {
const poll = () => {
api(getState).get(`/api/v1/media/${data.id}`).then(response => {
if (response.status === 200) {
dispatch(uploadComposeSuccess(response.data, file));
} else if (response.status === 206) {
setTimeout(() => poll(), 1000);
}
}).catch(error => dispatch(uploadComposeFail(error)));
};
poll();
}
});
poll();
}
});
};
};
};

View file

@ -36,15 +36,15 @@ export const submitMarkers = () => (dispatch, getState) => {
};
export const fetchMarkers = () => (dispatch, getState) => {
const params = { timeline: ['notifications'] };
const params = { timeline: ['notifications'] };
dispatch(fetchMarkersRequest());
dispatch(fetchMarkersRequest());
api(getState).get('/api/v1/markers', { params }).then(response => {
dispatch(fetchMarkersSuccess(response.data));
}).catch(error => {
dispatch(fetchMarkersFail(error));
});
api(getState).get('/api/v1/markers', { params }).then(response => {
dispatch(fetchMarkersSuccess(response.data));
}).catch(error => {
dispatch(fetchMarkersFail(error));
});
};
export function fetchMarkersRequest() {

View file

@ -27,7 +27,7 @@ const debouncedSave = debounce((dispatch, getState) => {
api(getState).put(
'/api/pleroma/notification_settings',
{ exclude_types: excludeTypesFromSettings(getState()) }
{ exclude_types: excludeTypesFromSettings(getState()) },
).catch(error => dispatch(showAlertForError(error)));
api(getState).put('/api/web/settings', { data })

View file

@ -47,7 +47,7 @@ export function updateTimeline(timeline, status, accept) {
timeline,
status,
usePendingItems: preferPendingItems,
filtered
filtered,
});
};
};

View file

@ -87,7 +87,7 @@ export default class DisplayName extends React.PureComponent {
)).reduce((prev, cur) => [prev, ', ', cur]);
if (others.size - 2 > 0) {
displayName.push(` +${others.size - 2}`);
displayName.push(` +${others.size - 2}`);
}
suffix = (

View file

@ -104,16 +104,17 @@ export default class ErrorBoundary extends React.PureComponent {
/>
</li>
)}
<li>
<FormattedMessage
<li>
<FormattedMessage
id='web_app_crash.load_pleromafe'
defaultMessage='Load {pleromafe} instead of mastofe'
values={{ pleromafe: <a href='/main/all'><FormattedMessage id='web_app_crash.pleromafe' defaultMessage='Pleroma Frontend' /></a> }}
/>
</li>
/>
</li>
</ul>
</div>
</div>
);
}
}

View file

@ -121,8 +121,9 @@ export default class IntersectionObserverArticle extends React.Component {
aria-setsize={listLength}
data-id={id}
tabIndex='0'
style={style}>
{children && React.cloneElement(children, { hidden: !isIntersecting && (isHidden || !!cachedHeight) })}
style={style}
>
{children && React.cloneElement(children, { hidden: !isIntersecting && (isHidden || !!cachedHeight) })}
</article>
);
}

View file

@ -233,14 +233,14 @@ class Item extends React.PureComponent {
aria-label={attachment.get('description')}
role='application'
>
<span><p>sound<br/>only</p></span>
<span><p>sound<br />only</p></span>
<span><p>{attachment.get('description')}</p></span>
<audio
src={attachment.get('url')}
controls
/>
</div>
);
);
} else if (attachment.get('type') === 'gifv') {
const autoPlay = !isIOS() && this.getAutoPlay();
@ -367,7 +367,7 @@ class MediaGallery extends React.PureComponent {
} else if (width) {
style.height = width / (16/9);
} else {
return (<div className={computedClass} ref={this.handleRef}></div>);
return (<div className={computedClass} ref={this.handleRef} />);
}
if (this.isStandaloneEligible()) {

View file

@ -4,6 +4,7 @@ import 'wicg-inert';
import { createBrowserHistory } from 'history';
export default class ModalRoot extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
@ -104,7 +105,7 @@ export default class ModalRoot extends React.PureComponent {
handleModalOpen () {
const history = this.history;
const state = {...history.location.state, mastodonModalOpen: true};
const state = { ...history.location.state, mastodonModalOpen: true };
history.push(history.location.pathname, state);
this.unlistenHistory = history.listen(() => {
this.props.onClose();

View file

@ -24,7 +24,7 @@ export default class Permalink extends React.PureComponent {
if (this.context.router) {
e.preventDefault();
let state = {...this.context.router.history.location.state};
let state = { ...this.context.router.history.location.state };
state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
this.context.router.history.push(this.props.to, state);
}

View file

@ -4,6 +4,7 @@ import { FormattedMessage } from 'react-intl';
export default
class Spoilers extends React.PureComponent {
static propTypes = {
spoilerText: PropTypes.string,
children: PropTypes.node,
@ -21,17 +22,17 @@ class Spoilers extends React.PureComponent {
const { spoilerText, children } = this.props;
const { hidden } = this.state;
const toggleText = hidden ?
<FormattedMessage
id='status.show_more'
defaultMessage='Show more'
key='0'
/> :
<FormattedMessage
id='status.show_less'
defaultMessage='Show less'
key='0'
/>;
const toggleText = hidden ?
(<FormattedMessage
id='status.show_more'
defaultMessage='Show more'
key='0'
/>) :
(<FormattedMessage
id='status.show_less'
defaultMessage='Show less'
key='0'
/>);
return ([
<p className='spoiler__text'>
@ -43,8 +44,9 @@ class Spoilers extends React.PureComponent {
</p>,
<div className={`status__content__spoiler ${!hidden ? 'status__content__spoiler--visible' : ''}`}>
{children}
</div>
</div>,
]);
}
}

View file

@ -53,7 +53,7 @@ export const defaultMediaVisibility = (status, settings) => {
}
return (displayMedia !== 'hide_all' && !status.get('sensitive') || displayMedia === 'show_all');
}
};
export default @injectIntl
class Status extends ImmutablePureComponent {
@ -291,7 +291,9 @@ class Status extends ImmutablePureComponent {
if (this.node && this.props.getScrollPosition) {
const position = this.props.getScrollPosition();
if (position !== null && this.node.offsetTop < position.top) {
requestAnimationFrame(() => { this.props.updateScrollBottom(position.height - position.top); });
requestAnimationFrame(() => {
this.props.updateScrollBottom(position.height - position.top);
});
}
}
}
@ -344,7 +346,7 @@ class Status extends ImmutablePureComponent {
status.getIn(['reblog', 'id'], status.get('id'))
}`;
}
let state = {...router.history.location.state};
let state = { ...router.history.location.state };
state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
router.history.push(destination, state);
}
@ -360,7 +362,7 @@ class Status extends ImmutablePureComponent {
if (this.context.router && e.button === 0) {
const id = e.currentTarget.getAttribute('data-id');
e.preventDefault();
let state = {...this.context.router.history.location.state};
let state = { ...this.context.router.history.location.state };
state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
this.context.router.history.push(`/accounts/${id}`, state);
}
@ -415,13 +417,13 @@ class Status extends ImmutablePureComponent {
}
handleHotkeyOpen = () => {
let state = {...this.context.router.history.location.state};
let state = { ...this.context.router.history.location.state };
state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
this.context.router.history.push(`/statuses/${this.props.status.get('id')}`, state);
}
handleHotkeyOpenProfile = () => {
let state = {...this.context.router.history.location.state};
let state = { ...this.context.router.history.location.state };
state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`, state);
}

View file

@ -122,7 +122,7 @@ class StatusActionBar extends ImmutablePureComponent {
_openInteractionDialog = type => {
window.open(`/interact/${this.props.status.get('id')}?type=${type}`, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
}
}
handleDeleteClick = () => {
this.props.onDelete(this.props.status, this.context.router.history);
@ -153,7 +153,7 @@ class StatusActionBar extends ImmutablePureComponent {
}
handleOpen = () => {
let state = {...this.context.router.history.location.state};
let state = { ...this.context.router.history.location.state };
if (state.mastodonModalOpen) {
this.context.router.history.replace(`/statuses/${this.props.status.get('id')}`, { mastodonBackSteps: (state.mastodonBackSteps || 0) + 1 });
} else {

View file

@ -13,7 +13,7 @@ const textMatchesTarget = (text, origin, host) => {
return (text === origin || text === host
|| text.startsWith(origin + '/') || text.startsWith(host + '/')
|| 'www.' + text === host || ('www.' + text).startsWith(host + '/'));
}
};
const isLinkMisleading = (link) => {
let linkTextParts = [];

View file

@ -48,16 +48,16 @@ class StatusIcons extends React.PureComponent {
const { intl, mediaIcon } = this.props;
switch (mediaIcon) {
case 'link':
return intl.formatMessage(messages.previewCard);
case 'picture-o':
return intl.formatMessage(messages.pictures);
case 'tasks':
return intl.formatMessage(messages.poll);
case 'video-camera':
return intl.formatMessage(messages.video);
case 'music':
return intl.formatMessage(messages.audio);
case 'link':
return intl.formatMessage(messages.previewCard);
case 'picture-o':
return intl.formatMessage(messages.pictures);
case 'tasks':
return intl.formatMessage(messages.poll);
case 'video-camera':
return intl.formatMessage(messages.video);
case 'music':
return intl.formatMessage(messages.audio);
}
}

View file

@ -19,8 +19,10 @@ const mapDispatchToProps = (dispatch, { status, items }) => ({
(item, i) => item ? {
...item,
name: `${item.text}-${i}`,
onClick: item.action ? ((e) => { return onItemClick(i, e) }) : null,
} : null
onClick: item.action ? ((e) => {
return onItemClick(i, e);
}) : null,
} : null,
),
}) : openDropdownMenu(id, dropdownPlacement, keyboard));
},

View file

@ -201,7 +201,7 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({
<Spoilers spoilerText={intl.formatMessage(messages.author)}>
<AccountContainer id={status.getIn(['account', 'id'])} />
</Spoilers>
<Spoilers spoilerText={intl.formatMessage(messages.matchingFilters, {count: matchingFilters.size})}>
<Spoilers spoilerText={intl.formatMessage(messages.matchingFilters, { count: matchingFilters.size })}>
<ul>
{matchingFilters.map(filter => (
<li>
@ -221,7 +221,7 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({
))}
</ul>
</Spoilers>
</div>
</div>,
],
confirm: intl.formatMessage(messages.unfilterConfirm),
onConfirm: onConfirm,

View file

@ -128,8 +128,7 @@ class Header extends ImmutablePureComponent {
if (me !== account.get('id') && account.getIn(['relationship', 'followed_by'])) {
info.push(<span className='relationship-tag'><FormattedMessage id='account.follows_you' defaultMessage='Follows you' /></span>);
}
else if (me !== account.get('id') && account.getIn(['relationship', 'blocking'])) {
} else if (me !== account.get('id') && account.getIn(['relationship', 'blocking'])) {
info.push(<span className='relationship-tag'><FormattedMessage id='account.blocked' defaultMessage='Blocked' /></span>);
}
@ -297,7 +296,7 @@ class Header extends ImmutablePureComponent {
{fields.map((pair, i) => (
<dl key={i}>
<dt dangerouslySetInnerHTML={{ __html: pair.get('name_emojified') }} title={pair.get('name')} />
<dd className={pair.get('verified_at') && 'verified'} title={pair.get('value_plain')}>
{pair.get('verified_at') && <span title={intl.formatMessage(messages.linkVerifiedOn, { date: intl.formatDate(pair.get('verified_at'), dateFormatOptions) })}><Icon id='check' className='verified__mark' /></span>} <span dangerouslySetInnerHTML={{ __html: pair.get('value_emojified') }} />
</dd>
@ -308,9 +307,9 @@ class Header extends ImmutablePureComponent {
{account.get('note').length > 0 && account.get('note') !== '<p></p>' && <div className='account__header__content' dangerouslySetInnerHTML={content} />}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
}

View file

@ -21,7 +21,7 @@ export default class MovedNote extends ImmutablePureComponent {
handleAccountClick = e => {
if (e.button === 0) {
e.preventDefault();
let state = {...this.context.router.history.location.state};
let state = { ...this.context.router.history.location.state };
state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
this.context.router.history.push(`/accounts/${this.props.to.get('id')}`, state);
}

View file

@ -12,7 +12,7 @@ import {
} from 'flavours/glitch/actions/accounts';
import {
mentionCompose,
directCompose
directCompose,
} from 'flavours/glitch/actions/compose';
import { initMuteModal } from 'flavours/glitch/actions/mutes';
import { initBlockModal } from 'flavours/glitch/actions/blocks';

View file

@ -12,7 +12,7 @@ const mapStateToProps = (state, { columnId }) => {
settings: (uuid && index >= 0) ? columns.get(index).get('params') : state.getIn(['settings', 'community']),
};
};
const mapDispatchToProps = (dispatch, { columnId }) => {
return {
onChange (key, checked) {

View file

@ -20,9 +20,9 @@ import CharacterCounter from './character_counter';
const messages = defineMessages({
placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' },
missingDescriptionMessage: { id: 'confirmations.missing_media_description.message',
defaultMessage: 'At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.' },
defaultMessage: 'At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.' },
missingDescriptionConfirm: { id: 'confirmations.missing_media_description.confirm',
defaultMessage: 'Send anyway' },
defaultMessage: 'Send anyway' },
spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Write your warning here' },
});

View file

@ -141,7 +141,7 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
onChange(name);
component.setState({ needsModalUpdate: true });
},
})
}),
),
};
}
@ -166,7 +166,7 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
const { items } = this.props;
const { needsModalUpdate } = this.state;
if (needsModalUpdate && items.find(
(item, i) => item.on !== prevProps.items[i].on
(item, i) => item.on !== prevProps.items[i].on,
)) {
this.handleUpdate();
this.setState({ needsModalUpdate: false });

View file

@ -167,7 +167,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
if (on !== null && typeof on !== 'undefined') {
prefix = <Toggle checked={on} onChange={this.handleClick.bind(this, name)} />;
} else if (icon) {
prefix = <Icon className='icon' fixedWidth id={icon} />
prefix = <Icon className='icon' fixedWidth id={icon} />;
}
return (

View file

@ -47,6 +47,7 @@ const messages = defineMessages({
export default @injectIntl
class Header extends ImmutablePureComponent {
static propTypes = {
columns: ImmutablePropTypes.list,
unreadNotifications: PropTypes.number,
@ -71,8 +72,8 @@ class Header extends ImmutablePureComponent {
// Only renders the component if the column isn't being shown.
const renderForColumn = conditionalRender.bind(null,
columnId => !columns || !columns.some(
column => column.get('id') === columnId
)
column => column.get('id') === columnId,
),
);
// The result.
@ -125,10 +126,11 @@ class Header extends ImmutablePureComponent {
<a
aria-label={intl.formatMessage(messages.logout)}
onClick={this.handleLogoutClick}
href={ signOutLink }
href={signOutLink}
title={intl.formatMessage(messages.logout)}
><Icon id='sign-out' /></a>
</nav>
);
};
}

View file

@ -28,11 +28,12 @@ export default class NavigationBar extends ImmutablePureComponent {
{ profileLink !== undefined && (
<a
className='edit'
href={ profileLink }
href={profileLink}
><FormattedMessage id='navigation_bar.edit_profile' defaultMessage='Edit profile' /></a>
)}
</div>
</div>
);
};
}

View file

@ -115,4 +115,5 @@ class Publisher extends ImmutablePureComponent {
</div>
);
};
}

View file

@ -97,7 +97,7 @@ class SearchResults extends ImmutablePureComponent {
<section>
<h5><Icon id='quote-right' fixedWidth /><FormattedMessage id='search_results.statuses' defaultMessage='Toots' /></h5>
{results.get('statuses').map(statusId => <StatusContainer id={statusId} key={statusId}/>)}
{results.get('statuses').map(statusId => <StatusContainer id={statusId} key={statusId} />)}
{results.get('statuses').size >= 5 && <LoadMore visible onClick={this.handleLoadMoreStatuses} />}
</section>
@ -131,4 +131,5 @@ class SearchResults extends ImmutablePureComponent {
</div>
);
};
}

View file

@ -51,9 +51,10 @@ class TextareaIcons extends ImmutablePureComponent {
id={icon}
/>
</span>
) : null
) : null,
) : null}
</div>
);
}
}

View file

@ -40,7 +40,7 @@ export default class Upload extends ImmutablePureComponent {
return (
<div className='composer--upload_form--item' tabIndex='0' role='button'>
<Motion defaultStyle={{ scale: 0.8 }} style={{ scale: spring(1, { stiffness: 180, damping: 12, }) }}>
<Motion defaultStyle={{ scale: 0.8 }} style={{ scale: spring(1, { stiffness: 180, damping: 12 }) }}>
{({ scale }) => (
<div style={{ transform: `scale(${scale})`, backgroundImage: `url(${media.get('preview_url')})`, backgroundPosition: `${x}% ${y}%` }}>
<div className={classNames('composer--upload_form--actions', { active: true })}>

View file

@ -7,6 +7,7 @@ import SensitiveButtonContainer from '../containers/sensitive_button_container';
import { FormattedMessage } from 'react-intl';
export default class UploadForm extends ImmutablePureComponent {
static propTypes = {
mediaIds: ImmutablePropTypes.list.isRequired,
};

View file

@ -30,7 +30,8 @@ export default class UploadProgress extends React.PureComponent {
<div className='backdrop'>
<Motion defaultStyle={{ width: 0 }} style={{ width: spring(progress) }}>
{({ width }) =>
(<div className='tracker' style={{ width: `${width}%` }}
(<div
className='tracker' style={{ width: `${width}%` }}
/>)
}
</Motion>

View file

@ -22,11 +22,11 @@ import { privacyPreference } from 'flavours/glitch/util/privacy_preference';
const messages = defineMessages({
missingDescriptionMessage: { id: 'confirmations.missing_media_description.message',
defaultMessage: 'At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.' },
defaultMessage: 'At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.' },
missingDescriptionConfirm: { id: 'confirmations.missing_media_description.confirm',
defaultMessage: 'Send anyway' },
defaultMessage: 'Send anyway' },
missingDescriptionEdit: { id: 'confirmations.missing_media_description.edit',
defaultMessage: 'Edit media' },
defaultMessage: 'Edit media' },
});
// State mapping.
@ -38,12 +38,12 @@ function mapStateToProps (state) {
const sideArmRestrictedPrivacy = replyPrivacy ? privacyPreference(replyPrivacy, sideArmBasePrivacy) : null;
let sideArmPrivacy = null;
switch (state.getIn(['local_settings', 'side_arm_reply_mode'])) {
case 'copy':
sideArmPrivacy = replyPrivacy;
break;
case 'restrict':
sideArmPrivacy = sideArmRestrictedPrivacy;
break;
case 'copy':
sideArmPrivacy = replyPrivacy;
break;
case 'restrict':
sideArmPrivacy = sideArmRestrictedPrivacy;
break;
}
sideArmPrivacy = sideArmPrivacy || sideArmBasePrivacy;
return {

View file

@ -34,6 +34,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
export default @connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class Compose extends React.PureComponent {
static propTypes = {
multiColumn: PropTypes.bool,
showSearch: PropTypes.bool,

View file

@ -59,7 +59,7 @@ class Conversation extends ImmutablePureComponent {
}
destination = `/statuses/${lastStatus.get('id')}`;
}
let state = {...router.history.location.state};
let state = { ...router.history.location.state };
state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
router.history.push(destination, state);
e.preventDefault();

View file

@ -83,9 +83,9 @@ const badgeDisplay = (number, limit) => {
const NAVIGATION_PANEL_BREAKPOINT = 600 + (285 * 2) + (10 * 2);
export default @connect(makeMapStateToProps, mapDispatchToProps)
export default @connect(makeMapStateToProps, mapDispatchToProps)
@injectIntl
class GettingStarted extends ImmutablePureComponent {
class GettingStarted extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object.isRequired,
@ -172,12 +172,12 @@ const NAVIGATION_PANEL_BREAKPOINT = 600 + (285 * 2) + (10 * 2);
<div key='9'>
<ColumnLink key='10' icon='bars' text={intl.formatMessage(messages.lists)} to='/lists' />
{lists.map(list =>
<ColumnLink key={(11 + Number(list.get('id'))).toString()} to={`/timelines/list/${list.get('id')}`} icon='list-ul' text={list.get('title')} />
<ColumnLink key={(11 + Number(list.get('id'))).toString()} to={`/timelines/list/${list.get('id')}`} icon='list-ul' text={list.get('title')} />,
)}
</div>,
]);
const instance_panel = (customPanelEnabled ? <div className='getting-started getting-started__panel' dangerouslySetInnerHTML={{__html: customPanel}} /> : null);
const instance_panel = (customPanelEnabled ? <div className='getting-started getting-started__panel' dangerouslySetInnerHTML={{ __html: customPanel }} /> : null);
return (
<Column bindToDocument={!multiColumn} name='getting-started' icon='asterisk' heading={intl.formatMessage(messages.heading)} label={intl.formatMessage(messages.menu)} hideHeadingOnMobile>

View file

@ -80,7 +80,7 @@ class LocalSettingsNavigation extends React.PureComponent {
/>
<LocalSettingsNavigationItem
active={index === 6}
href={ preferencesLink }
href={preferencesLink}
index={6}
icon='cog'
title={intl.formatMessage(messages.preferences)}

View file

@ -59,7 +59,7 @@ class LocalSettingsPage extends React.PureComponent {
onChange={onChange}
>
<FormattedMessage id='settings.hicolor_privacy_icons' defaultMessage='High color privacy icons' />
<span className='hint'><FormattedMessage id='settings.hicolor_privacy_icons.hint' defaultMessage="Display privacy icons in bright and easily distinguishable colors" /></span>
<span className='hint'><FormattedMessage id='settings.hicolor_privacy_icons.hint' defaultMessage='Display privacy icons in bright and easily distinguishable colors' /></span>
</LocalSettingsPageItem>
<LocalSettingsPageItem
settings={settings}
@ -76,7 +76,7 @@ class LocalSettingsPage extends React.PureComponent {
onChange={onChange}
>
<FormattedMessage id='settings.tag_misleading_links' defaultMessage='Tag misleading links' />
<span className='hint'><FormattedMessage id='settings.tag_misleading_links.hint' defaultMessage="Add a visual indication with the link target host to every link not mentioning it explicitly" /></span>
<span className='hint'><FormattedMessage id='settings.tag_misleading_links.hint' defaultMessage='Add a visual indication with the link target host to every link not mentioning it explicitly' /></span>
</LocalSettingsPageItem>
<LocalSettingsPageItem
settings={settings}
@ -99,7 +99,7 @@ class LocalSettingsPage extends React.PureComponent {
id='mastodon-settings--notifications-tab_badge'
onChange={onChange}
>
<FormattedMessage id='settings.notifications.tab_badge' defaultMessage="Unread notifications badge" />
<FormattedMessage id='settings.notifications.tab_badge' defaultMessage='Unread notifications badge' />
<span className='hint'><FormattedMessage id='settings.notifications.tab_badge.hint' defaultMessage="Display a badge for unread notifications in the column icons when the notifications column isn't open" /></span>
</LocalSettingsPageItem>
<LocalSettingsPageItem
@ -109,7 +109,7 @@ class LocalSettingsPage extends React.PureComponent {
onChange={onChange}
>
<FormattedMessage id='settings.notifications.favicon_badge' defaultMessage='Unread notifications favicon badge' />
<span className='hint'><FormattedMessage id='settings.notifications.favicon_badge.hint' defaultMessage="Add a badge for unread notifications to the favicon" /></span>
<span className='hint'><FormattedMessage id='settings.notifications.favicon_badge.hint' defaultMessage='Add a badge for unread notifications to the favicon' /></span>
</LocalSettingsPageItem>
</section>
<section>
@ -272,7 +272,7 @@ class LocalSettingsPage extends React.PureComponent {
{ value: 'drop', message: intl.formatMessage(messages.filters_drop) },
{ value: 'upstream', message: intl.formatMessage(messages.filters_upstream) },
{ value: 'hide', message: intl.formatMessage(messages.filters_hide) },
{ value: 'content_warning', message: intl.formatMessage(messages.filters_cw) }
{ value: 'content_warning', message: intl.formatMessage(messages.filters_cw) },
]}
>
<FormattedMessage id='settings.filtering_behavior' defaultMessage='Filtering behavior' />

View file

@ -53,13 +53,14 @@ export default class LocalSettingsPageItem extends React.PureComponent {
let optionId = `${id}--${opt.value}`;
return (
<label htmlFor={optionId}>
<input type='radio'
<input
type='radio'
name={id}
id={optionId}
value={opt.value}
onBlur={handleChange}
onChange={handleChange}
checked={ currentValue === opt.value }
checked={currentValue === opt.value}
disabled={!enabled}
/>
{opt.message}

View file

@ -4,7 +4,7 @@ import { injectIntl } from 'react-intl';
import {
fetchPinnedAccountsSuggestions,
clearPinnedAccountsSuggestions,
changePinnedAccountsSuggestions
changePinnedAccountsSuggestions,
} from '../../../actions/accounts';
import Search from 'flavours/glitch/features/list_editor/components/search';

View file

@ -2,7 +2,7 @@ import { connect } from 'react-redux';
import ColumnSettings from '../components/column_settings';
import { changeSetting } from 'flavours/glitch/actions/settings';
import { changeColumnParams } from 'flavours/glitch/actions/columns';
const mapStateToProps = (state, { columnId }) => {
const uuid = columnId;
const columns = state.getIn(['settings', 'columns']);

View file

@ -46,7 +46,7 @@ class PublicTimeline extends React.PureComponent {
dispatch(local ? expandCommunityTimeline() : expandPublicTimeline());
}
handleLoadMore = () => {
const { dispatch, statusIds, local } = this.props;
const maxId = statusIds.last();

View file

@ -47,7 +47,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
handleAccountClick = (e) => {
if (e.button === 0 && !(e.ctrlKey || e.altKey || e.metaKey) && this.context.router) {
e.preventDefault();
let state = {...this.context.router.history.location.state};
let state = { ...this.context.router.history.location.state };
state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`, state);
}
@ -58,7 +58,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
parseClick = (e, destination) => {
if (e.button === 0 && !(e.ctrlKey || e.altKey || e.metaKey) && this.context.router) {
e.preventDefault();
let state = {...this.context.router.history.location.state};
let state = { ...this.context.router.history.location.state };
state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
this.context.router.history.push(destination, state);
}

View file

@ -402,7 +402,7 @@ class Status extends ImmutablePureComponent {
}
handleHotkeyOpenProfile = () => {
let state = {...this.context.router.history.location.state};
let state = { ...this.context.router.history.location.state };
state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`, state);
}

View file

@ -44,7 +44,7 @@ class BoostModal extends ImmutablePureComponent {
if (e.button === 0) {
e.preventDefault();
this.props.onClose();
let state = {...this.context.router.history.location.state};
let state = { ...this.context.router.history.location.state };
state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`, state);
}
@ -90,9 +90,9 @@ class BoostModal extends ImmutablePureComponent {
<div className='boost-modal__action-bar'>
<div>
{ missingMediaDescription ?
<FormattedMessage id='boost_modal.missing_description' defaultMessage='This toot contains some media without description' />
<FormattedMessage id='boost_modal.missing_description' defaultMessage='This toot contains some media without description' />
:
<FormattedMessage id='boost_modal.combo' defaultMessage='You can press {combo} to skip this next time' values={{ combo: <span>Shift + <Icon id='retweet' /></span> }} />
<FormattedMessage id='boost_modal.combo' defaultMessage='You can press {combo} to skip this next time' values={{ combo: <span>Shift + <Icon id='retweet' /></span> }} />
}
</div>
<Button text={intl.formatMessage(buttonText)} onClick={this.handleReblog} ref={this.setRef} />

View file

@ -27,7 +27,7 @@ const ColumnLink = ({ icon, text, to, onClick, href, method, badge }) => {
e.preventDefault();
e.stopPropagation();
return onClick(e);
}
};
return (
<a href='#' onClick={onClick && handleOnClick} className='column-link' tabIndex='0'>
<Icon id={icon} fixedWidth className='column-link__icon' />

View file

@ -575,7 +575,7 @@ class DoodleModal extends ImmutablePureComponent {
<div>
<select aria-label='Canvas size' onInput={this.changeSize} defaultValue={this.size}>
{ Object.values(mapValues(DOODLE_SIZES, (val, k) =>
<option key={k} value={k}>{val[2]}</option>
<option key={k} value={k}>{val[2]}</option>,
)) }
</select>
</div>
@ -602,7 +602,7 @@ class DoodleModal extends ImmutablePureComponent {
'foreground': this.fg === c[0],
'background': this.bg === c[0],
})}
/>
/>,
)
}
</div>

View file

@ -41,7 +41,7 @@ class FavouriteModal extends ImmutablePureComponent {
if (e.button === 0) {
e.preventDefault();
this.props.onClose();
let state = {...this.context.router.history.location.state};
let state = { ...this.context.router.history.location.state };
state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`, state);
}

View file

@ -21,11 +21,12 @@ class LinkFooter extends React.PureComponent {
mastofe: <a href='https://git.pleroma.social/pleroma/mastofe' rel='noopener noreferrer' target='_blank'>Mastofe</a>,
glitchsoc: <a href='https://github.com/glitch-soc/mastodon' rel='noopener noreferrer' target='_blank'>glitch-soc</a>,
mastodon: <a href='https://github.com/tootsuite/mastodon' rel='noopener noreferrer' target='_blank'>Mastodon</a>,
pleroma: <a href='https://pleroma.social' rel='noopener noreferrer' target='_blank'>Pleroma</a>
pleroma: <a href='https://pleroma.social' rel='noopener noreferrer' target='_blank'>Pleroma</a>,
}}
/>
</p>
</div>
);
}
};

View file

@ -49,7 +49,7 @@ const PageTwo = ({ intl, myAccount }) => (
privacy='public'
text='Awoo! #introductions'
spoilerText=''
suggestions={ [] }
suggestions={[]}
/>
</div>
</div>

View file

@ -386,7 +386,7 @@ class UI extends React.Component {
navigator.serviceWorker.addEventListener('message', this.handleServiceWorkerPostMessage);
}
this.favicon = new Favico({ animation:"none" });
this.favicon = new Favico({ animation:'none' });
this.props.dispatch(fetchMarkers());
this.props.dispatch(expandHomeTimeline());
@ -596,7 +596,7 @@ class UI extends React.Component {
<PermaLink href={moved.get('url')} to={`/accounts/${moved.get('id')}`}>
@{moved.get('acct')}
</PermaLink>
)}}
) }}
/>
</div>)}
<SwitchingColumnsArea location={location} layout={layout} navbarUnder={navbarUnder} onLayoutChange={this.handleLayoutChange}>

View file

@ -429,7 +429,7 @@ class Video extends React.PureComponent {
playerStyle.height = height;
} else if (inline) {
return (<div className={computedClass} ref={this.setPlayerRef} tabindex={0}></div>);
return (<div className={computedClass} ref={this.setPlayerRef} tabindex={0} />);
}
let warning;

View file

@ -84,7 +84,7 @@ const messages = {
'navigation_bar.direct': 'ダイレクトメッセージ',
'navigation_bar.bookmarks': 'ブックマーク',
'column.bookmarks': 'ブックマーク'
'column.bookmarks': 'ブックマーク',
};
export default Object.assign({}, inherited, messages);

View file

@ -67,13 +67,13 @@ const messages = {
'advanced_options.threaded_mode.short': 'Tryb wątków',
'advanced_options.threaded_mode.long': 'Przechodzi do tworzenia odpowiedzi po publikacji wpisu',
'advanced_options.threaded_mode.tooltip': 'Włączono tryb wątków',
'column.bookmarks': 'Zakładki',
'compose_form.sensitive': 'Oznacz zawartość multimedialną jako wrażliwą',
'compose_form.spoiler': 'Ukryj tekst za ostrzeżeniem',
'favourite_modal.combo': 'Możesz nacisnąć {combo}, aby pominąć to następnym razem',
'tabs_bar.compose': 'Napisz',
};
export default Object.assign({}, inherited, messages);

View file

@ -128,16 +128,16 @@ function apiStatusToTextMentions (state, status) {
}
return set.union(status.mentions.filter(
mention => mention.id !== me
mention => mention.id !== me,
).map(
mention => `@${mention.acct} `
mention => `@${mention.acct} `,
)).join('');
}
function apiStatusToTextHashtags (state, status) {
const text = unescapeHTML(status.content);
return ImmutableOrderedSet([]).union(recoverHashtags(status.tags, text).map(
(name) => `#${name} `
(name) => `#${name} `,
)).join('');
}
@ -152,7 +152,7 @@ function clearAll(state) {
map.set('in_reply_to', null);
map.update(
'advanced_options',
map => map.mergeWith(overwrite, state.get('default_advanced_options'))
map => map.mergeWith(overwrite, state.get('default_advanced_options')),
);
map.set('privacy', state.get('default_privacy'));
map.set('sensitive', false);
@ -178,7 +178,7 @@ function continueThread (state, status) {
map.set('in_reply_to', status.id);
map.update(
'advanced_options',
map => map.merge(new ImmutableMap({ do_not_federate: /👁\ufe0f?\u200b?(?:<\/p>)?$/.test(status.content) }))
map => map.merge(new ImmutableMap({ do_not_federate: /👁\ufe0f?\u200b?(?:<\/p>)?$/.test(status.content) })),
);
map.set('privacy', status.visibility);
map.set('sensitive', false);
@ -377,7 +377,7 @@ export default function compose(state = initialState, action) {
map.set('privacy', privacyPreference(action.status.get('visibility'), state.get('default_privacy')));
map.update(
'advanced_options',
map => map.merge(new ImmutableMap({ do_not_federate: /👁\ufe0f?\u200b?(?:<\/p>)?$/.test(action.status.get('content')) }))
map => map.merge(new ImmutableMap({ do_not_federate: /👁\ufe0f?\u200b?(?:<\/p>)?$/.test(action.status.get('content')) })),
);
map.set('focusDate', new Date());
map.set('caretPosition', null);
@ -409,7 +409,7 @@ export default function compose(state = initialState, action) {
map.set('poll', null);
map.update(
'advanced_options',
map => map.mergeWith(overwrite, state.get('default_advanced_options'))
map => map.mergeWith(overwrite, state.get('default_advanced_options')),
);
map.set('idempotencyKey', uuid());
});

View file

@ -67,7 +67,7 @@ const deleteFromContexts = (immutableState, ids) => immutableState.withMutations
const filterContexts = (state, relationship, statuses) => {
const ownedStatusIds = statuses.filter(status => status.get('account') === relationship.id)
.map(status => status.get('id'));
.map(status => status.get('id'));
return deleteFromContexts(state, ownedStatusIds);
};

View file

@ -54,10 +54,10 @@ export default function listEditorReducer(state = initialState, action) {
});
case LIST_CREATE_REQUEST:
case LIST_UPDATE_REQUEST:
return state.withMutations(map => {
map.set('isSubmitting', true);
map.set('isChanged', false);
});
return state.withMutations(map => {
map.set('isSubmitting', true);
map.set('isChanged', false);
});
case LIST_CREATE_FAIL:
case LIST_UPDATE_FAIL:
return state.set('isSubmitting', false);

View file

@ -127,7 +127,7 @@ const clearUnread = (state) => {
state = state.set('unread', state.get('pendingItems').size);
const lastNotification = state.get('items').find(item => item !== null);
return state.set('lastReadId', lastNotification ? lastNotification.get('id') : '0');
}
};
const updateTop = (state, top) => {
state = state.set('top', top);
@ -210,7 +210,7 @@ const recountUnread = (state, last_read_id) => {
mutable.set('unread', mutable.get('pendingItems').count(item => item !== null) + mutable.get('items').count(item => item && compareId(item.get('id'), last_read_id) > 0));
}
});
}
};
export default function notifications(state = initialState, action) {
let st;

View file

@ -3,7 +3,7 @@ import { PANEL_FETCH_SUCCESS, PLEROMA_CONFIG_FETCH_SUCCESS } from 'mastodon/acti
const initialPanel = ImmutableMap({
enabled: false,
panel: ''
panel: '',
});
export default function custom_panel(state = initialPanel, action) {

View file

@ -1,8 +1,8 @@
export function recoverHashtags (recognizedTags, text) {
return recognizedTags.map(tag => {
const re = new RegExp(`(?:^|[^\/\)\w])#(${tag.name})`, 'i');
const matched_hashtag = text.match(re);
return matched_hashtag ? matched_hashtag[1] : null;
}
const re = new RegExp(`(?:^|[^\/\)\w])#(${tag.name})`, 'i');
const matched_hashtag = text.match(re);
return matched_hashtag ? matched_hashtag[1] : null;
},
).filter(x => x !== null);
}

View file

@ -9,7 +9,7 @@ const maybeSetNotificationsSettings = result => {
excludeTypes.forEach(x => showTypes[x] = false);
set(result, ['settings', 'notifications', 'shows'], showTypes);
}
};
const element = document.getElementById('initial-state');
const initialState = element && function () {

View file

@ -3,7 +3,7 @@ import { signOutLink } from 'flavours/glitch/util/backend_links';
export const logOut = () => {
fetch(signOutLink, {
method: 'DELETE'
method: 'DELETE',
}).then(() => {
window.location = '/web/';
});

View file

@ -7,7 +7,7 @@ export function assignHandlers (target, handlers) {
// We just bind each handler to the `target`.
const handle = target.handlers = {};
Object.keys(handlers).forEach(
key => handle[key] = handlers[key].bind(target)
key => handle[key] = handlers[key].bind(target),
);
}

View file

@ -27,6 +27,7 @@ store.dispatch(fetchCustomEmojis());
@connect(mapStateToProps)
class MastodonMount extends React.PureComponent {
shouldUpdateScroll (_, { location }) {
return location.state !== previewMediaState && location.state !== previewVideoState;
}

View file

@ -1,20 +1,20 @@
#!/bin/sh
TARGET="${TARGET:-../pleroma}" # Where pleromas repository is sitting
static_dir="priv/static" # Set this to instance/static when testing production build
TARGET="${TARGET:-./distribution}" # Where pleromas repository is sitting
mkdir -p $TARGET/emoji
die() {
echo "Die: $@"
exit 1
}
[ -d "${TARGET}/priv/static" ] || die "${TARGET}/priv/static directory is missing, are you sure TARGET is set to a pleroma repository? (Info: TARGET=${TARGET} )"
[ -d "${TARGET}" ] || die "${TARGET} directory is missing, are you sure TARGET is set to a pleroma repository? (Info: TARGET=${TARGET} )"
yarn install -D || die "Installing dependencies via yarn failed"
rm -rf public/packs public/assets
env -i "PATH=$PATH" npm run build || die "Building the frontend failed"
cp public/assets/sw.js "${TARGET}/${static_dir}/sw.js" || die "installing sw.js (service-worker) failed"
rm -rf "${TARGET}/${static_dir}/packs" || die "Removing old assets in priv/static/packs failed"
cp -r public/packs "${TARGET}/${static_dir}/packs" || die "Copying new assets in priv/static/packs failed"
rm -rf "${TARGET}/${static_dir}/emoji/*.svg" || die "Removing the old emoji assets failed"
cp -r public/emoji/* "${TARGET}/${static_dir}/emoji" || die "Installing the new emoji assets failed"
cp public/assets/sw.js "${TARGET}/sw.js" || die "installing sw.js (service-worker) failed"
rm -rf "${TARGET}/packs" || die "Removing old assets in priv/static/packs failed"
cp -r public/packs "${TARGET}/packs" || die "Copying new assets in priv/static/packs failed"
rm -rf "${TARGET}/emoji/*.svg" || die "Removing the old emoji assets failed"
cp -r public/emoji/* "${TARGET}/emoji" || die "Installing the new emoji assets failed"

View file

@ -21,7 +21,7 @@ module.exports = Object.keys(flavours).reduce(function (map, entry) {
return map;
}
const locales = readdirSync(flavour.locales).filter(
filename => /\.js(?:on)?$/.test(filename) && !/defaultMessages|whitelist|index/.test(filename)
filename => /\.js(?:on)?$/.test(filename) && !/defaultMessages|whitelist|index/.test(filename),
);
const outPath = resolve('tmp', 'locales', entry);
@ -40,9 +40,9 @@ module.exports = Object.keys(flavours).reduce(function (map, entry) {
// fall back to English (this is what react-intl does anyway)
'node_modules/react-intl/locale-data/en.js',
].filter(
filename => existsSync(filename)
filename => existsSync(filename),
).map(
filename => filename.replace(/(?:node_modules|app\/javascript)\//, '')
filename => filename.replace(/(?:node_modules|app\/javascript)\//, ''),
)[0];
const localeContent = `//
// locales/${entry}/${localeName}.js

View file

@ -50,7 +50,7 @@ const entries = Object.assign(
{ locales: resolve('app', 'javascript', 'locales') },
localePacks,
reducePacks(core),
Object.keys(flavours).reduce((map, entry) => reducePacks(flavours[entry], map), {})
Object.keys(flavours).reduce((map, entry) => reducePacks(flavours[entry], map), {}),
);

View file

@ -2,9 +2,6 @@
"name": "@tootsuite/mastodon",
"description": "mastodon",
"license": "AGPL-3.0-or-later",
"engines": {
"node": ">=10.13 <13"
},
"scripts": {
"postversion": "git push --tags",
"build:development": "cross-env NODE_ENV=development webpack --config config/webpack/development.js",