mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-15 08:48:53 +00:00
Merge pull request #913 from ThibG/glitch-soc/merge-upstream
Merge upstream changes
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
|
||||
const messages = defineMessages({
|
||||
unexpectedTitle: { id: 'alert.unexpected.title', defaultMessage: 'Oops!' },
|
||||
unexpectedMessage: { id: 'alert.unexpected.message', defaultMessage: 'An unexpected error occurred.' },
|
||||
});
|
||||
|
||||
export const ALERT_SHOW = 'ALERT_SHOW';
|
||||
export const ALERT_DISMISS = 'ALERT_DISMISS';
|
||||
export const ALERT_CLEAR = 'ALERT_CLEAR';
|
||||
@@ -15,10 +22,28 @@ export function clearAlert() {
|
||||
};
|
||||
};
|
||||
|
||||
export function showAlert(title, message) {
|
||||
export function showAlert(title = messages.unexpectedTitle, message = messages.unexpectedMessage) {
|
||||
return {
|
||||
type: ALERT_SHOW,
|
||||
title,
|
||||
message,
|
||||
};
|
||||
};
|
||||
|
||||
export function showAlertForError(error) {
|
||||
if (error.response) {
|
||||
const { data, status, statusText } = error.response;
|
||||
|
||||
let message = statusText;
|
||||
let title = `${status}`;
|
||||
|
||||
if (data.error) {
|
||||
message = data.error;
|
||||
}
|
||||
|
||||
return showAlert(title, message);
|
||||
} else {
|
||||
console.error(error);
|
||||
return showAlert();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import api from 'flavours/glitch/util/api';
|
||||
import { CancelToken } from 'axios';
|
||||
import { CancelToken, isCancel } from 'axios';
|
||||
import { throttle } from 'lodash';
|
||||
import { search as emojiSearch } from 'flavours/glitch/util/emoji/emoji_mart_search_light';
|
||||
import { useEmoji } from './emojis';
|
||||
@@ -8,6 +8,9 @@ import { recoverHashtags } from 'flavours/glitch/util/hashtag';
|
||||
import resizeImage from 'flavours/glitch/util/resize_image';
|
||||
|
||||
import { updateTimeline } from './timelines';
|
||||
import { showAlertForError } from './alerts';
|
||||
import { showAlert } from './alerts';
|
||||
import { defineMessages } from 'react-intl';
|
||||
|
||||
let cancelFetchComposeSuggestionsAccounts;
|
||||
|
||||
@@ -52,6 +55,10 @@ export const COMPOSE_UPLOAD_CHANGE_FAIL = 'COMPOSE_UPLOAD_UPDATE_FAIL';
|
||||
|
||||
export const COMPOSE_DOODLE_SET = 'COMPOSE_DOODLE_SET';
|
||||
|
||||
const messages = defineMessages({
|
||||
uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' },
|
||||
});
|
||||
|
||||
export function changeCompose(text) {
|
||||
return {
|
||||
type: COMPOSE_CHANGE,
|
||||
@@ -207,20 +214,32 @@ export function doodleSet(options) {
|
||||
|
||||
export function uploadCompose(files) {
|
||||
return function (dispatch, getState) {
|
||||
if (getState().getIn(['compose', 'media_attachments']).size > 3) {
|
||||
const uploadLimit = 4;
|
||||
const media = getState().getIn(['compose', 'media_attachments']);
|
||||
const total = Array.from(files).reduce((a, v) => a + v.size, 0);
|
||||
const progress = new Array(files.length).fill(0);
|
||||
|
||||
if (files.length + media.size > uploadLimit) {
|
||||
dispatch(showAlert(undefined, messages.uploadErrorLimit));
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(uploadComposeRequest());
|
||||
|
||||
resizeImage(files[0]).then(file => {
|
||||
const data = new FormData();
|
||||
data.append('file', file);
|
||||
for (const [i, f] of Array.from(files).entries()) {
|
||||
if (media.size + i > 3) break;
|
||||
|
||||
return api(getState).post('/api/v1/media', data, {
|
||||
onUploadProgress: ({ loaded, total }) => dispatch(uploadComposeProgress(loaded, total)),
|
||||
}).then(({ data }) => dispatch(uploadComposeSuccess(data)));
|
||||
}).catch(error => dispatch(uploadComposeFail(error)));
|
||||
resizeImage(f).then(file => {
|
||||
const data = new FormData();
|
||||
data.append('file', file);
|
||||
|
||||
return api(getState).post('/api/v1/media', data, {
|
||||
onUploadProgress: function({ loaded }){
|
||||
progress[i] = loaded;
|
||||
dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
|
||||
},
|
||||
}).then(({ data }) => dispatch(uploadComposeSuccess(data)));
|
||||
}).catch(error => dispatch(uploadComposeFail(error)));
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -320,6 +339,10 @@ const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, token) =>
|
||||
},
|
||||
}).then(response => {
|
||||
dispatch(readyComposeSuggestionsAccounts(token, response.data));
|
||||
}).catch(error => {
|
||||
if (!isCancel(error)) {
|
||||
dispatch(showAlertForError(error));
|
||||
}
|
||||
});
|
||||
}, 200, { leading: true, trailing: true });
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import api from 'flavours/glitch/util/api';
|
||||
import { showAlertForError } from './alerts';
|
||||
|
||||
export const LIST_FETCH_REQUEST = 'LIST_FETCH_REQUEST';
|
||||
export const LIST_FETCH_SUCCESS = 'LIST_FETCH_SUCCESS';
|
||||
@@ -239,7 +240,8 @@ export const fetchListSuggestions = q => (dispatch, getState) => {
|
||||
};
|
||||
|
||||
api(getState).get('/api/v1/accounts/search', { params })
|
||||
.then(({ data }) => dispatch(fetchListSuggestionsReady(q, data)));
|
||||
.then(({ data }) => dispatch(fetchListSuggestionsReady(q, data)))
|
||||
.catch(error => dispatch(showAlertForError(error)));
|
||||
};
|
||||
|
||||
export const fetchListSuggestionsReady = (query, accounts) => ({
|
||||
|
||||
@@ -109,14 +109,11 @@ export function register () {
|
||||
pushNotificationsSetting.remove(me);
|
||||
}
|
||||
|
||||
try {
|
||||
getRegistration()
|
||||
.then(getPushSubscription)
|
||||
.then(unsubscribe);
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
});
|
||||
return getRegistration()
|
||||
.then(getPushSubscription)
|
||||
.then(unsubscribe);
|
||||
})
|
||||
.catch(console.warn);
|
||||
} else {
|
||||
console.warn('Your browser does not support Web Push Notifications.');
|
||||
}
|
||||
@@ -137,6 +134,6 @@ export function saveSettings() {
|
||||
if (me) {
|
||||
pushNotificationsSetting.set(me, data);
|
||||
}
|
||||
});
|
||||
}).catch(console.warn);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import api from 'flavours/glitch/util/api';
|
||||
import { debounce } from 'lodash';
|
||||
import { showAlertForError } from './alerts';
|
||||
|
||||
export const SETTING_CHANGE = 'SETTING_CHANGE';
|
||||
export const SETTING_SAVE = 'SETTING_SAVE';
|
||||
@@ -23,7 +24,9 @@ const debouncedSave = debounce((dispatch, getState) => {
|
||||
|
||||
const data = getState().get('settings').filter((_, path) => path !== 'saved').toJS();
|
||||
|
||||
api(getState).put('/api/web/settings', { data }).then(() => dispatch({ type: SETTING_SAVE }));
|
||||
api(getState).put('/api/web/settings', { data })
|
||||
.then(() => dispatch({ type: SETTING_SAVE }))
|
||||
.catch(error => dispatch(showAlertForError(error)));
|
||||
}, 5000, { trailing: true });
|
||||
|
||||
export function saveSettings() {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { IntlProvider, addLocaleData } from 'react-intl';
|
||||
import { getLocale } from 'mastodon/locales';
|
||||
import Compose from 'flavours/glitch/features/standalone/compose';
|
||||
import initialState from 'flavours/glitch/util/initial_state';
|
||||
import { fetchCustomEmojis } from 'flavours/glitch/actions/custom_emojis';
|
||||
|
||||
const { localeData, messages } = getLocale();
|
||||
addLocaleData(localeData);
|
||||
@@ -17,6 +18,8 @@ if (initialState) {
|
||||
store.dispatch(hydrateStore(initialState));
|
||||
}
|
||||
|
||||
store.dispatch(fetchCustomEmojis());
|
||||
|
||||
export default class TimelineContainer extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
|
||||
@@ -25,6 +25,7 @@ import { openModal } from 'flavours/glitch/actions/modal';
|
||||
import { changeLocalSetting } from 'flavours/glitch/actions/local_settings';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import { boostModal, favouriteModal, deleteModal } from 'flavours/glitch/util/initial_state';
|
||||
import { showAlertForError } from '../actions/alerts';
|
||||
|
||||
const messages = defineMessages({
|
||||
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
|
||||
@@ -134,7 +135,10 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||
},
|
||||
|
||||
onEmbed (status) {
|
||||
dispatch(openModal('EMBED', { url: status.get('url') }));
|
||||
dispatch(openModal('EMBED', {
|
||||
url: status.get('url'),
|
||||
onError: error => dispatch(showAlertForError(error)),
|
||||
}));
|
||||
},
|
||||
|
||||
onDelete (status, history, withRedraft = false) {
|
||||
|
||||
@@ -214,6 +214,7 @@ export default class ComposerOptions extends React.PureComponent {
|
||||
onChange={handleChangeFiles}
|
||||
ref={handleRefFileElement}
|
||||
type='file'
|
||||
multiple
|
||||
{...hiddenComponent}
|
||||
/>
|
||||
<Dropdown
|
||||
|
||||
@@ -166,7 +166,7 @@ export default class GettingStarted extends ImmutablePureComponent {
|
||||
<div className='getting-started__footer'>
|
||||
<ul>
|
||||
{invitesEnabled && <li><a href='/invites' target='_blank'><FormattedMessage id='getting_started.invite' defaultMessage='Invite people' /></a> · </li>}
|
||||
<li><a href='/about/more' target='_blank'><FormattedMessage id='navigation_bar.info' defaultMessage='About this instance' /></a> · </li>
|
||||
<li><a href='/about/more' target='_blank'><FormattedMessage id='navigation_bar.info' defaultMessage='About this server' /></a> · </li>
|
||||
<li><a href='https://joinmastodon.org/apps' target='_blank'><FormattedMessage id='navigation_bar.apps' defaultMessage='Mobile apps' /></a> · </li>
|
||||
<li><a href='/terms' target='_blank'><FormattedMessage id='getting_started.terms' defaultMessage='Terms of service' /></a> · </li>
|
||||
<li><a href='https://docs.joinmastodon.org' target='_blank'><FormattedMessage id='getting_started.documentation' defaultMessage='Documentation' /></a></li>
|
||||
|
||||
@@ -127,7 +127,7 @@ export default class PublicTimeline extends React.PureComponent {
|
||||
onLoadMore={this.handleLoadMore}
|
||||
trackScroll={!pinned}
|
||||
scrollKey={`public_timeline-${columnId}`}
|
||||
emptyMessage={<FormattedMessage id='empty_column.public' defaultMessage='There is nothing here! Write something publicly, or manually follow users from other instances to fill it up' />}
|
||||
emptyMessage={<FormattedMessage id='empty_column.public' defaultMessage='There is nothing here! Write something publicly, or manually follow users from other servers to fill it up' />}
|
||||
/>
|
||||
</Column>
|
||||
);
|
||||
|
||||
@@ -10,6 +10,7 @@ export default class EmbedModal extends ImmutablePureComponent {
|
||||
static propTypes = {
|
||||
url: PropTypes.string.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
onError: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
@@ -35,6 +36,8 @@ export default class EmbedModal extends ImmutablePureComponent {
|
||||
iframeDocument.body.style.margin = 0;
|
||||
this.iframe.width = iframeDocument.body.scrollWidth;
|
||||
this.iframe.height = iframeDocument.body.scrollHeight;
|
||||
}).catch(error => {
|
||||
this.props.onError(error);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ export default class ReportModal extends ImmutablePureComponent {
|
||||
|
||||
<div className='report-modal__container'>
|
||||
<div className='report-modal__comment'>
|
||||
<p><FormattedMessage id='report.hint' defaultMessage='The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:' /></p>
|
||||
<p><FormattedMessage id='report.hint' defaultMessage='The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:' /></p>
|
||||
|
||||
<textarea
|
||||
className='setting-text light'
|
||||
|
||||
@@ -186,7 +186,7 @@ export default class UI extends React.Component {
|
||||
this.setState({ draggingOver: false });
|
||||
this.dragTargets = [];
|
||||
|
||||
if (e.dataTransfer && e.dataTransfer.files.length === 1) {
|
||||
if (e.dataTransfer && e.dataTransfer.files.length >= 1) {
|
||||
this.props.dispatch(uploadCompose(e.dataTransfer.files));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { showAlert } from 'flavours/glitch/actions/alerts';
|
||||
import { showAlertForError } from 'flavours/glitch/actions/alerts';
|
||||
|
||||
const defaultFailSuffix = 'FAIL';
|
||||
|
||||
@@ -8,21 +8,7 @@ export default function errorsMiddleware() {
|
||||
const isFail = new RegExp(`${defaultFailSuffix}$`, 'g');
|
||||
|
||||
if (action.type.match(isFail)) {
|
||||
if (action.error.response) {
|
||||
const { data, status, statusText } = action.error.response;
|
||||
|
||||
let message = statusText;
|
||||
let title = `${status}`;
|
||||
|
||||
if (data.error) {
|
||||
message = data.error;
|
||||
}
|
||||
|
||||
dispatch(showAlert(title, message));
|
||||
} else {
|
||||
console.error(action.error);
|
||||
dispatch(showAlert('Oops!', 'An unexpected error occurred.'));
|
||||
}
|
||||
dispatch(showAlertForError(action.error));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -290,3 +290,7 @@
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.directory__tag .trends__item__current {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
@@ -153,10 +153,15 @@ $content-width: 840px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.directory__tag a {
|
||||
.directory__tag > a,
|
||||
.directory__tag > div {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.directory__tag .table-action-link .fa {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.directory__tag h4 {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
|
||||
@@ -269,7 +269,8 @@
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 10px;
|
||||
|
||||
a {
|
||||
& > a,
|
||||
& > div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
@@ -279,7 +280,9 @@
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||
}
|
||||
|
||||
& > a {
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
@@ -287,7 +290,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.active a {
|
||||
&.active > a {
|
||||
background: $ui-highlight-color;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ const loadImage = inputFile => new Promise((resolve, reject) => {
|
||||
});
|
||||
|
||||
const getOrientation = (img, type = 'image/png') => new Promise(resolve => {
|
||||
if (type !== 'image/jpeg') {
|
||||
if (!['image/jpeg', 'image/webp'].includes(type)) {
|
||||
resolve(1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ export function clearAlert() {
|
||||
};
|
||||
};
|
||||
|
||||
export function showAlert(title, message) {
|
||||
export function showAlert(title = messages.unexpectedTitle, message = messages.unexpectedMessage) {
|
||||
return {
|
||||
type: ALERT_SHOW,
|
||||
title,
|
||||
@@ -44,6 +44,6 @@ export function showAlertForError(error) {
|
||||
return showAlert(title, message);
|
||||
} else {
|
||||
console.error(error);
|
||||
return showAlert(messages.unexpectedTitle, messages.unexpectedMessage);
|
||||
return showAlert();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import resizeImage from '../utils/resize_image';
|
||||
import { importFetchedAccounts } from './importer';
|
||||
import { updateTimeline } from './timelines';
|
||||
import { showAlertForError } from './alerts';
|
||||
import { showAlert } from './alerts';
|
||||
import { defineMessages } from 'react-intl';
|
||||
|
||||
let cancelFetchComposeSuggestionsAccounts;
|
||||
|
||||
@@ -49,6 +51,10 @@ export const COMPOSE_UPLOAD_CHANGE_REQUEST = 'COMPOSE_UPLOAD_UPDATE_REQUEST'
|
||||
export const COMPOSE_UPLOAD_CHANGE_SUCCESS = 'COMPOSE_UPLOAD_UPDATE_SUCCESS';
|
||||
export const COMPOSE_UPLOAD_CHANGE_FAIL = 'COMPOSE_UPLOAD_UPDATE_FAIL';
|
||||
|
||||
const messages = defineMessages({
|
||||
uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' },
|
||||
});
|
||||
|
||||
export function changeCompose(text) {
|
||||
return {
|
||||
type: COMPOSE_CHANGE,
|
||||
@@ -184,20 +190,32 @@ export function submitComposeFail(error) {
|
||||
|
||||
export function uploadCompose(files) {
|
||||
return function (dispatch, getState) {
|
||||
if (getState().getIn(['compose', 'media_attachments']).size > 3) {
|
||||
const uploadLimit = 4;
|
||||
const media = getState().getIn(['compose', 'media_attachments']);
|
||||
const total = Array.from(files).reduce((a, v) => a + v.size, 0);
|
||||
const progress = new Array(files.length).fill(0);
|
||||
|
||||
if (files.length + media.size > uploadLimit) {
|
||||
dispatch(showAlert(undefined, messages.uploadErrorLimit));
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(uploadComposeRequest());
|
||||
|
||||
resizeImage(files[0]).then(file => {
|
||||
const data = new FormData();
|
||||
data.append('file', file);
|
||||
for (const [i, f] of Array.from(files).entries()) {
|
||||
if (media.size + i > 3) break;
|
||||
|
||||
return api(getState).post('/api/v1/media', data, {
|
||||
onUploadProgress: ({ loaded, total }) => dispatch(uploadComposeProgress(loaded, total)),
|
||||
}).then(({ data }) => dispatch(uploadComposeSuccess(data)));
|
||||
}).catch(error => dispatch(uploadComposeFail(error)));
|
||||
resizeImage(f).then(file => {
|
||||
const data = new FormData();
|
||||
data.append('file', file);
|
||||
|
||||
return api(getState).post('/api/v1/media', data, {
|
||||
onUploadProgress: function({ loaded }){
|
||||
progress[i] = loaded;
|
||||
dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
|
||||
},
|
||||
}).then(({ data }) => dispatch(uploadComposeSuccess(data)));
|
||||
}).catch(error => dispatch(uploadComposeFail(error)));
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ export default class IntersectionObserverArticle extends React.Component {
|
||||
}
|
||||
|
||||
updateStateAfterIntersection = (prevState) => {
|
||||
if (prevState.isIntersecting && !this.entry.isIntersecting) {
|
||||
if (prevState.isIntersecting !== false && !this.entry.isIntersecting) {
|
||||
scheduleIdleTask(this.hideIfNotIntersecting);
|
||||
}
|
||||
return {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { IntlProvider, addLocaleData } from 'react-intl';
|
||||
import { getLocale } from '../locales';
|
||||
import Compose from '../features/standalone/compose';
|
||||
import initialState from '../initial_state';
|
||||
import { fetchCustomEmojis } from '../actions/custom_emojis';
|
||||
|
||||
const { localeData, messages } = getLocale();
|
||||
addLocaleData(localeData);
|
||||
@@ -17,6 +18,8 @@ if (initialState) {
|
||||
store.dispatch(hydrateStore(initialState));
|
||||
}
|
||||
|
||||
store.dispatch(fetchCustomEmojis());
|
||||
|
||||
export default class TimelineContainer extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
|
||||
@@ -63,7 +63,7 @@ class UploadButton extends ImmutablePureComponent {
|
||||
key={resetFileKey}
|
||||
ref={this.setRef}
|
||||
type='file'
|
||||
multiple={false}
|
||||
multiple
|
||||
accept={acceptContentTypes.toArray().join(',')}
|
||||
onChange={this.handleChange}
|
||||
disabled={disabled}
|
||||
|
||||
@@ -160,7 +160,7 @@ class GettingStarted extends ImmutablePureComponent {
|
||||
{invitesEnabled && <li><a href='/invites' target='_blank'><FormattedMessage id='getting_started.invite' defaultMessage='Invite people' /></a> · </li>}
|
||||
{multiColumn && <li><Link to='/keyboard-shortcuts'><FormattedMessage id='navigation_bar.keyboard_shortcuts' defaultMessage='Hotkeys' /></Link> · </li>}
|
||||
<li><a href='/auth/edit'><FormattedMessage id='getting_started.security' defaultMessage='Security' /></a> · </li>
|
||||
<li><a href='/about/more' target='_blank'><FormattedMessage id='navigation_bar.info' defaultMessage='About this instance' /></a> · </li>
|
||||
<li><a href='/about/more' target='_blank'><FormattedMessage id='navigation_bar.info' defaultMessage='About this server' /></a> · </li>
|
||||
<li><a href='https://joinmastodon.org/apps' target='_blank'><FormattedMessage id='navigation_bar.apps' defaultMessage='Mobile apps' /></a> · </li>
|
||||
<li><a href='/terms' target='_blank'><FormattedMessage id='getting_started.terms' defaultMessage='Terms of service' /></a> · </li>
|
||||
<li><a href='/settings/applications' target='_blank'><FormattedMessage id='getting_started.developers' defaultMessage='Developers' /></a> · </li>
|
||||
|
||||
@@ -89,7 +89,7 @@ const FrameInteractions = ({ onNext }) => (
|
||||
</div>
|
||||
|
||||
<div className='introduction__action'>
|
||||
<button className='button' onClick={onNext}><FormattedMessage id='introduction.interactions.action' defaultMessage='Finish tutorial!' /></button>
|
||||
<button className='button' onClick={onNext}><FormattedMessage id='introduction.interactions.action' defaultMessage='Finish toot-orial!' /></button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -124,7 +124,7 @@ class PublicTimeline extends React.PureComponent {
|
||||
onLoadMore={this.handleLoadMore}
|
||||
trackScroll={!pinned}
|
||||
scrollKey={`public_timeline-${columnId}`}
|
||||
emptyMessage={<FormattedMessage id='empty_column.public' defaultMessage='There is nothing here! Write something publicly, or manually follow users from other instances to fill it up' />}
|
||||
emptyMessage={<FormattedMessage id='empty_column.public' defaultMessage='There is nothing here! Write something publicly, or manually follow users from other servers to fill it up' />}
|
||||
shouldUpdateScroll={shouldUpdateScroll}
|
||||
/>
|
||||
</Column>
|
||||
|
||||
@@ -97,7 +97,7 @@ class ReportModal extends ImmutablePureComponent {
|
||||
|
||||
<div className='report-modal__container'>
|
||||
<div className='report-modal__comment'>
|
||||
<p><FormattedMessage id='report.hint' defaultMessage='The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:' /></p>
|
||||
<p><FormattedMessage id='report.hint' defaultMessage='The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:' /></p>
|
||||
|
||||
<textarea
|
||||
className='setting-text light'
|
||||
|
||||
@@ -263,7 +263,7 @@ class UI extends React.PureComponent {
|
||||
this.setState({ draggingOver: false });
|
||||
this.dragTargets = [];
|
||||
|
||||
if (e.dataTransfer && e.dataTransfer.files.length === 1) {
|
||||
if (e.dataTransfer && e.dataTransfer.files.length >= 1) {
|
||||
this.props.dispatch(uploadCompose(e.dataTransfer.files));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,15 @@
|
||||
],
|
||||
"path": "app/javascript/mastodon/actions/alerts.json"
|
||||
},
|
||||
{
|
||||
"descriptors": [
|
||||
{
|
||||
"defaultMessage": "File upload limit exceeded.",
|
||||
"id": "upload_error.limit"
|
||||
}
|
||||
],
|
||||
"path": "app/javascript/mastodon/actions/compose.json"
|
||||
},
|
||||
{
|
||||
"descriptors": [
|
||||
{
|
||||
@@ -1275,7 +1284,7 @@
|
||||
"id": "getting_started.security"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "About this instance",
|
||||
"defaultMessage": "About this server",
|
||||
"id": "navigation_bar.info"
|
||||
},
|
||||
{
|
||||
@@ -1448,7 +1457,7 @@
|
||||
"id": "introduction.interactions.favourite.text"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Finish tutorial!",
|
||||
"defaultMessage": "Finish toot-orial!",
|
||||
"id": "introduction.interactions.action"
|
||||
}
|
||||
],
|
||||
@@ -1828,7 +1837,7 @@
|
||||
"id": "column.public"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
|
||||
"defaultMessage": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
|
||||
"id": "empty_column.public"
|
||||
}
|
||||
],
|
||||
@@ -2188,7 +2197,7 @@
|
||||
"id": "report.target"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
|
||||
"defaultMessage": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:",
|
||||
"id": "report.hint"
|
||||
},
|
||||
{
|
||||
@@ -2298,4 +2307,4 @@
|
||||
],
|
||||
"path": "app/javascript/mastodon/features/video/index.json"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
"empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
|
||||
"empty_column.mutes": "You haven't muted any users yet.",
|
||||
"empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
|
||||
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
|
||||
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
|
||||
"follow_request.authorize": "Authorize",
|
||||
"follow_request.reject": "Reject",
|
||||
"getting_started.developers": "Developers",
|
||||
@@ -228,7 +228,7 @@
|
||||
"navigation_bar.favourites": "Favourites",
|
||||
"navigation_bar.filters": "Muted words",
|
||||
"navigation_bar.follow_requests": "Follow requests",
|
||||
"navigation_bar.info": "About this instance",
|
||||
"navigation_bar.info": "About this server",
|
||||
"navigation_bar.keyboard_shortcuts": "Hotkeys",
|
||||
"navigation_bar.lists": "Lists",
|
||||
"navigation_bar.misc": "Misc",
|
||||
@@ -281,7 +281,7 @@
|
||||
"reply_indicator.cancel": "Cancel",
|
||||
"report.forward": "Forward to {target}",
|
||||
"report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
|
||||
"report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
|
||||
"report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:",
|
||||
"report.placeholder": "Additional comments",
|
||||
"report.submit": "Submit",
|
||||
"report.target": "Reporting {target}",
|
||||
@@ -347,6 +347,7 @@
|
||||
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
|
||||
"upload_area.title": "Drag & drop to upload",
|
||||
"upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
|
||||
"upload_error.limit": "File upload limit exceeded.",
|
||||
"upload_form.description": "Describe for the visually impaired",
|
||||
"upload_form.focus": "Change preview",
|
||||
"upload_form.undo": "Delete",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
"empty_column.lists": "まだリストがありません。リストを作るとここに表示されます。",
|
||||
"empty_column.mutes": "まだ誰もミュートしていません。",
|
||||
"empty_column.notifications": "まだ通知がありません。他の人とふれ合って会話を始めましょう。",
|
||||
"empty_column.public": "ここにはまだ何もありません! 公開で何かを投稿したり、他のインスタンスのユーザーをフォローしたりしていっぱいにしましょう",
|
||||
"empty_column.public": "ここにはまだ何もありません! 公開で何かを投稿したり、他のサーバーのユーザーをフォローしたりしていっぱいにしましょう",
|
||||
"follow_request.authorize": "許可",
|
||||
"follow_request.reject": "拒否",
|
||||
"getting_started.developers": "開発",
|
||||
@@ -228,7 +228,7 @@
|
||||
"navigation_bar.favourites": "お気に入り",
|
||||
"navigation_bar.filters": "フィルター設定",
|
||||
"navigation_bar.follow_requests": "フォローリクエスト",
|
||||
"navigation_bar.info": "このインスタンスについて",
|
||||
"navigation_bar.info": "このサーバーについて",
|
||||
"navigation_bar.keyboard_shortcuts": "ホットキー",
|
||||
"navigation_bar.lists": "リスト",
|
||||
"navigation_bar.logout": "ログアウト",
|
||||
@@ -280,8 +280,8 @@
|
||||
"relative_time.seconds": "{number}秒前",
|
||||
"reply_indicator.cancel": "キャンセル",
|
||||
"report.forward": "{target} に転送する",
|
||||
"report.forward_hint": "このアカウントは別のインスタンスに所属しています。通報内容を匿名で転送しますか?",
|
||||
"report.hint": "通報内容はあなたのインスタンスのモデレーターへ送信されます。通報理由を入力してください。:",
|
||||
"report.forward_hint": "このアカウントは別のサーバーに所属しています。通報内容を匿名で転送しますか?",
|
||||
"report.hint": "通報内容はあなたのサーバーのモデレーターへ送信されます。通報理由を入力してください。:",
|
||||
"report.placeholder": "追加コメント",
|
||||
"report.submit": "通報する",
|
||||
"report.target": "{target}さんを通報する",
|
||||
@@ -347,6 +347,7 @@
|
||||
"ui.beforeunload": "Mastodonから離れると送信前の投稿は失われます。",
|
||||
"upload_area.title": "ドラッグ&ドロップでアップロード",
|
||||
"upload_button.label": "メディアを追加 (JPEG, PNG, GIF, WebM, MP4, MOV)",
|
||||
"upload_error.limit": "アップロードできる上限を超えています。",
|
||||
"upload_form.description": "視覚障害者のための説明",
|
||||
"upload_form.focus": "焦点",
|
||||
"upload_form.undo": "削除",
|
||||
|
||||
@@ -347,6 +347,7 @@
|
||||
"ui.beforeunload": "Utracisz tworzony wpis, jeżeli opuścisz Mastodona.",
|
||||
"upload_area.title": "Przeciągnij i upuść aby wysłać",
|
||||
"upload_button.label": "Dodaj zawartość multimedialną (JPEG, PNG, GIF, WebM, MP4, MOV)",
|
||||
"upload_error.limit": "Przekroczono limit plików do wysłania.",
|
||||
"upload_form.description": "Wprowadź opis dla niewidomych i niedowidzących",
|
||||
"upload_form.focus": "Dopasuj podgląd",
|
||||
"upload_form.undo": "Usuń",
|
||||
|
||||
@@ -31,7 +31,7 @@ const loadImage = inputFile => new Promise((resolve, reject) => {
|
||||
});
|
||||
|
||||
const getOrientation = (img, type = 'image/png') => new Promise(resolve => {
|
||||
if (type !== 'image/jpeg') {
|
||||
if (!['image/jpeg', 'image/webp'].includes(type)) {
|
||||
resolve(1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -288,3 +288,7 @@
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.directory__tag .trends__item__current {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
@@ -153,10 +153,15 @@ $content-width: 840px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.directory__tag a {
|
||||
.directory__tag > a,
|
||||
.directory__tag > div {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.directory__tag .table-action-link .fa {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.directory__tag h4 {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
|
||||
@@ -638,7 +638,6 @@
|
||||
font-weight: 400;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: pre-wrap;
|
||||
padding-top: 2px;
|
||||
color: $primary-text-color;
|
||||
|
||||
@@ -662,6 +661,7 @@
|
||||
|
||||
p {
|
||||
margin-bottom: 20px;
|
||||
white-space: pre-wrap;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
|
||||
@@ -269,7 +269,8 @@
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 10px;
|
||||
|
||||
a {
|
||||
& > a,
|
||||
& > div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
@@ -279,7 +280,9 @@
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
|
||||
}
|
||||
|
||||
& > a {
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
@@ -287,7 +290,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.active a {
|
||||
&.active > a {
|
||||
background: $ui-highlight-color;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user