Merge branch 'master' into glitch-soc/merge-upstream

Conflicts:
- app/controllers/oauth/authorized_applications_controller.rb
  Two changes too close to each other
- app/controllers/settings/sessions_controller.rb
- app/lib/user_settings_decorator.rb
  Two changes too close to each other
- app/models/media_attachment.rb
  New changes too close to glitch-soc only changes.
- app/models/user.rb
  Two changes too close to each other.
- app/services/remove_status_service.rb
  Kept direct timeline code which had been removed upstream.
- app/views/settings/preferences/show.html.haml
  Two changes too close to each other.
- config/locales/en.yml
  Introduction of a new string too close to glitch-soc-only's “flavour”
- config/locales/ja.yml
  Introduction of a new string too close to glitch-soc-only's “flavour”
- config/locales/pl.yml
  Introduction of a new string too close to glitch-soc-only's “flavour”
- config/locales/simple_form.en.yml
  Introduction of a new string too close to glitch-soc-only's “skin”
- config/locales/simple_form.pl.yml
  Introduction of a new string too close to glitch-soc-only's “skin”
- config/settings.yml
  Reverted upstream's decision of enabling posting application by default.
This commit is contained in:
Thibaut Girka
2019-02-10 20:57:51 +01:00
83 changed files with 747 additions and 231 deletions

View File

@ -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();
}
}

View File

@ -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)));
};
};
};

View File

@ -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 {

View File

@ -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 = {

View File

@ -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}

View File

@ -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>

View File

@ -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>
);

View File

@ -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>

View File

@ -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'

View File

@ -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));
}
}

View File

@ -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"
}
]
]

View File

@ -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",

View File

@ -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": "削除",

View File

@ -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ń",

View File

@ -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;
}