diff --git a/app/javascript/mastodon/actions/streaming.js b/app/javascript/mastodon/actions/streaming.js
index 10e68bf3aa..f56853bffb 100644
--- a/app/javascript/mastodon/actions/streaming.js
+++ b/app/javascript/mastodon/actions/streaming.js
@@ -40,10 +40,9 @@ const refreshHomeTimelineAndNotification = (dispatch, done) => {
dispatch(expandHomeTimeline({}, () => dispatch(expandNotifications({}, done))));
};
-export const connectUserStream = () => connectTimelineStream('home', 'user', refreshHomeTimelineAndNotification);
-export const connectCommunityStream = () => connectTimelineStream('community', 'public:local');
-export const connectMediaStream = () => connectTimelineStream('community', 'public:local');
-export const connectPublicStream = () => connectTimelineStream('public', 'public');
-export const connectHashtagStream = (tag) => connectTimelineStream(`hashtag:${tag}`, `hashtag&tag=${tag}`);
-export const connectDirectStream = () => connectTimelineStream('direct', 'direct');
-export const connectListStream = (id) => connectTimelineStream(`list:${id}`, `list&list=${id}`);
+export const connectUserStream = () => connectTimelineStream('home', 'user', refreshHomeTimelineAndNotification);
+export const connectCommunityStream = ({ onlyMedia } = {}) => connectTimelineStream(`community${onlyMedia ? ':media' : ''}`, `public:local${onlyMedia ? ':media' : ''}`);
+export const connectPublicStream = ({ onlyMedia } = {}) => connectTimelineStream(`public${onlyMedia ? ':media' : ''}`, `public${onlyMedia ? ':media' : ''}`);
+export const connectHashtagStream = tag => connectTimelineStream(`hashtag:${tag}`, `hashtag&tag=${tag}`);
+export const connectDirectStream = () => connectTimelineStream('direct', 'direct');
+export const connectListStream = id => connectTimelineStream(`list:${id}`, `list&list=${id}`);
diff --git a/app/javascript/mastodon/actions/timelines.js b/app/javascript/mastodon/actions/timelines.js
index 8bcfe4db9c..8f54dfd8a0 100644
--- a/app/javascript/mastodon/actions/timelines.js
+++ b/app/javascript/mastodon/actions/timelines.js
@@ -93,15 +93,15 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
};
};
-export const expandHomeTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('home', '/api/v1/timelines/home', { max_id: maxId }, done);
-export const expandPublicTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('public', '/api/v1/timelines/public', { max_id: maxId }, done);
-export const expandCommunityTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('community', '/api/v1/timelines/public', { local: true, max_id: maxId }, done);
-export const expandDirectTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('direct', '/api/v1/timelines/direct', { max_id: maxId }, done);
-export const expandAccountTimeline = (accountId, { maxId, withReplies } = {}) => expandTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}`, `/api/v1/accounts/${accountId}/statuses`, { exclude_replies: !withReplies, max_id: maxId });
+export const expandHomeTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('home', '/api/v1/timelines/home', { max_id: maxId }, done);
+export const expandPublicTimeline = ({ maxId, onlyMedia } = {}, done = noOp) => expandTimeline(`public${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { max_id: maxId, only_media: !!onlyMedia }, done);
+export const expandCommunityTimeline = ({ maxId, onlyMedia } = {}, done = noOp) => expandTimeline(`community${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { local: true, max_id: maxId, only_media: !!onlyMedia }, done);
+export const expandDirectTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('direct', '/api/v1/timelines/direct', { max_id: maxId }, done);
+export const expandAccountTimeline = (accountId, { maxId, withReplies } = {}) => expandTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}`, `/api/v1/accounts/${accountId}/statuses`, { exclude_replies: !withReplies, max_id: maxId });
export const expandAccountFeaturedTimeline = accountId => expandTimeline(`account:${accountId}:pinned`, `/api/v1/accounts/${accountId}/statuses`, { pinned: true });
-export const expandAccountMediaTimeline = (accountId, { maxId } = {}) => expandTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { max_id: maxId, only_media: true });
-export const expandHashtagTimeline = (hashtag, { maxId } = {}, done = noOp) => expandTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`, { max_id: maxId }, done);
-export const expandListTimeline = (id, { maxId } = {}, done = noOp) => expandTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`, { max_id: maxId }, done);
+export const expandAccountMediaTimeline = (accountId, { maxId } = {}) => expandTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { max_id: maxId, only_media: true });
+export const expandHashtagTimeline = (hashtag, { maxId } = {}, done = noOp) => expandTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`, { max_id: maxId }, done);
+export const expandListTimeline = (id, { maxId } = {}, done = noOp) => expandTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`, { max_id: maxId }, done);
export function expandTimelineRequest(timeline) {
return {
diff --git a/app/javascript/mastodon/features/community_timeline/index.js b/app/javascript/mastodon/features/community_timeline/index.js
index 870474ed58..8ad1144071 100644
--- a/app/javascript/mastodon/features/community_timeline/index.js
+++ b/app/javascript/mastodon/features/community_timeline/index.js
@@ -1,12 +1,13 @@
import React from 'react';
import { connect } from 'react-redux';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+import { NavLink } from 'react-router-dom';
import PropTypes from 'prop-types';
import StatusListContainer from '../ui/containers/status_list_container';
import Column from '../../components/column';
import ColumnHeader from '../../components/column_header';
import { expandCommunityTimeline } from '../../actions/timelines';
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
-import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import ColumnSettingsContainer from './containers/column_settings_container';
import { connectCommunityStream } from '../../actions/streaming';
@@ -14,20 +15,25 @@ const messages = defineMessages({
title: { id: 'column.community', defaultMessage: 'Local timeline' },
});
-const mapStateToProps = state => ({
- hasUnread: state.getIn(['timelines', 'community', 'unread']) > 0,
+const mapStateToProps = (state, { onlyMedia }) => ({
+ hasUnread: state.getIn(['timelines', `community${onlyMedia ? ':media' : ''}`, 'unread']) > 0,
});
@connect(mapStateToProps)
@injectIntl
export default class CommunityTimeline extends React.PureComponent {
+ static defaultProps = {
+ onlyMedia: false,
+ };
+
static propTypes = {
dispatch: PropTypes.func.isRequired,
columnId: PropTypes.string,
intl: PropTypes.object.isRequired,
hasUnread: PropTypes.bool,
multiColumn: PropTypes.bool,
+ onlyMedia: PropTypes.bool,
};
handlePin = () => {
@@ -50,10 +56,10 @@ export default class CommunityTimeline extends React.PureComponent {
}
componentDidMount () {
- const { dispatch } = this.props;
+ const { dispatch, onlyMedia } = this.props;
- dispatch(expandCommunityTimeline());
- this.disconnect = dispatch(connectCommunityStream());
+ dispatch(expandCommunityTimeline({ onlyMedia }));
+ this.disconnect = dispatch(connectCommunityStream({ onlyMedia }));
}
componentWillUnmount () {
@@ -68,13 +74,22 @@ export default class CommunityTimeline extends React.PureComponent {
}
handleLoadMore = maxId => {
- this.props.dispatch(expandCommunityTimeline({ maxId }));
+ const { dispatch, onlyMedia } = this.props;
+
+ dispatch(expandCommunityTimeline({ maxId, onlyMedia }));
}
render () {
- const { intl, hasUnread, columnId, multiColumn } = this.props;
+ const { intl, hasUnread, columnId, multiColumn, onlyMedia } = this.props;
const pinned = !!columnId;
+ const headline = (
+
+
+
+
+ );
+
return (
}
/>
diff --git a/app/javascript/mastodon/features/public_timeline/index.js b/app/javascript/mastodon/features/public_timeline/index.js
index 5a88f76017..54904c5cfa 100644
--- a/app/javascript/mastodon/features/public_timeline/index.js
+++ b/app/javascript/mastodon/features/public_timeline/index.js
@@ -1,12 +1,13 @@
import React from 'react';
import { connect } from 'react-redux';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+import { NavLink } from 'react-router-dom';
import PropTypes from 'prop-types';
import StatusListContainer from '../ui/containers/status_list_container';
import Column from '../../components/column';
import ColumnHeader from '../../components/column_header';
import { expandPublicTimeline } from '../../actions/timelines';
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
-import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import ColumnSettingsContainer from './containers/column_settings_container';
import { connectPublicStream } from '../../actions/streaming';
@@ -14,20 +15,25 @@ const messages = defineMessages({
title: { id: 'column.public', defaultMessage: 'Federated timeline' },
});
-const mapStateToProps = state => ({
- hasUnread: state.getIn(['timelines', 'public', 'unread']) > 0,
+const mapStateToProps = (state, { onlyMedia }) => ({
+ hasUnread: state.getIn(['timelines', `public${onlyMedia ? ':media' : ''}`, 'unread']) > 0,
});
@connect(mapStateToProps)
@injectIntl
export default class PublicTimeline extends React.PureComponent {
+ static defaultProps = {
+ onlyMedia: false,
+ };
+
static propTypes = {
dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
columnId: PropTypes.string,
multiColumn: PropTypes.bool,
hasUnread: PropTypes.bool,
+ onlyMedia: PropTypes.bool,
};
handlePin = () => {
@@ -50,10 +56,10 @@ export default class PublicTimeline extends React.PureComponent {
}
componentDidMount () {
- const { dispatch } = this.props;
+ const { dispatch, onlyMedia } = this.props;
- dispatch(expandPublicTimeline());
- this.disconnect = dispatch(connectPublicStream());
+ dispatch(expandPublicTimeline({ onlyMedia }));
+ this.disconnect = dispatch(connectPublicStream({ onlyMedia }));
}
componentWillUnmount () {
@@ -68,13 +74,22 @@ export default class PublicTimeline extends React.PureComponent {
}
handleLoadMore = maxId => {
- this.props.dispatch(expandPublicTimeline({ maxId }));
+ const { dispatch, onlyMedia } = this.props;
+
+ dispatch(expandPublicTimeline({ maxId, onlyMedia }));
}
render () {
- const { intl, columnId, hasUnread, multiColumn } = this.props;
+ const { intl, columnId, hasUnread, multiColumn, onlyMedia } = this.props;
const pinned = !!columnId;
+ const headline = (
+
+
+
+
+ );
+
return (
+
+
diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json
index 9827ac5f0e..c8e37a3665 100644
--- a/app/javascript/mastodon/locales/ar.json
+++ b/app/javascript/mastodon/locales/ar.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "المحلي",
"tabs_bar.notifications": "الإخطارات",
"tabs_bar.search": "البحث",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "سوف تفقد مسودتك إن تركت ماستدون.",
"upload_area.title": "إسحب ثم أفلت للرفع",
"upload_button.label": "إضافة وسائط",
diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index caba7703d9..9ac5aad9e7 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Известия",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
"upload_area.title": "Drag & drop to upload",
"upload_button.label": "Добави медия",
diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json
index 7181589ec2..8fd42ca34a 100644
--- a/app/javascript/mastodon/locales/ca.json
+++ b/app/javascript/mastodon/locales/ca.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Notificacions",
"tabs_bar.search": "Cerca",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "El vostre esborrany es perdrà si sortiu de Mastodon.",
"upload_area.title": "Arrossega i deixa anar per carregar",
"upload_button.label": "Afegir multimèdia",
diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json
index c6de9d016b..bc75813ea1 100644
--- a/app/javascript/mastodon/locales/co.json
+++ b/app/javascript/mastodon/locales/co.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Lucale",
"tabs_bar.notifications": "Nutificazione",
"tabs_bar.search": "Cercà",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "A bruttacopia sarà persa s'ellu hè chjosu Mastodon.",
"upload_area.title": "Drag & drop per caricà un fugliale",
"upload_button.label": "Aghjunghje un media",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index 4d89ea7041..29756aff0b 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Lokal",
"tabs_bar.notifications": "Mitteilungen",
"tabs_bar.search": "Suchen",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Dein Entwurf geht verloren, wenn du Mastodon verlässt.",
"upload_area.title": "Zum Hochladen hereinziehen",
"upload_button.label": "Mediendatei hinzufügen",
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index d2ec8e7100..1431346fe5 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -596,6 +596,14 @@
"defaultMessage": "Local timeline",
"id": "column.community"
},
+ {
+ "defaultMessage": "Toots",
+ "id": "timeline.posts"
+ },
+ {
+ "defaultMessage": "Media",
+ "id": "timeline.media"
+ },
{
"defaultMessage": "The local timeline is empty. Write something publicly to get the ball rolling!",
"id": "empty_column.community"
@@ -1393,6 +1401,14 @@
"defaultMessage": "Federated timeline",
"id": "column.public"
},
+ {
+ "defaultMessage": "Toots",
+ "id": "timeline.posts"
+ },
+ {
+ "defaultMessage": "Media",
+ "id": "timeline.media"
+ },
{
"defaultMessage": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
"id": "empty_column.public"
diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json
index c547b2e284..1e7707b4a0 100644
--- a/app/javascript/mastodon/locales/el.json
+++ b/app/javascript/mastodon/locales/el.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Notifications",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
"upload_area.title": "Drag & drop to upload",
"upload_button.label": "Add media",
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index caec0cbd31..7a977673ea 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Notifications",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
"upload_area.title": "Drag & drop to upload",
"upload_button.label": "Add media",
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index 2715b80c9b..04d9dc8d51 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Loka tempolinio",
"tabs_bar.notifications": "Sciigoj",
"tabs_bar.search": "Serĉi",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Via malneto perdiĝos se vi eliras de Mastodon.",
"upload_area.title": "Altreni kaj lasi por alŝuti",
"upload_button.label": "Aldoni aŭdovidaĵon",
diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json
index 668f437b9d..6092630c48 100644
--- a/app/javascript/mastodon/locales/es.json
+++ b/app/javascript/mastodon/locales/es.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Notificaciones",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Tu borrador se perderá si sales de Mastodon.",
"upload_area.title": "Arrastra y suelta para subir",
"upload_button.label": "Subir multimedia",
diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json
index 8ec1407532..a6b1f8e836 100644
--- a/app/javascript/mastodon/locales/eu.json
+++ b/app/javascript/mastodon/locales/eu.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Notifications",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
"upload_area.title": "Drag & drop to upload",
"upload_button.label": "Add media",
diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json
index 605961a018..c45277d82f 100644
--- a/app/javascript/mastodon/locales/fa.json
+++ b/app/javascript/mastodon/locales/fa.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "محلی",
"tabs_bar.notifications": "اعلانها",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "اگر از ماستدون خارج شوید پیشنویس شما پاک خواهد شد.",
"upload_area.title": "برای بارگذاری به اینجا بکشید",
"upload_button.label": "افزودن تصویر",
diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json
index ead1eb8c4b..d04e0230a5 100644
--- a/app/javascript/mastodon/locales/fi.json
+++ b/app/javascript/mastodon/locales/fi.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Paikallinen",
"tabs_bar.notifications": "Ilmoitukset",
"tabs_bar.search": "Hae",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Luonnos häviää, jos poistut Mastodonista.",
"upload_area.title": "Lataa raahaamalla ja pudottamalla tähän",
"upload_button.label": "Lisää mediaa",
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index c05cb40c12..4c2bd39cac 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Fil public local",
"tabs_bar.notifications": "Notifications",
"tabs_bar.search": "Chercher",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Votre brouillon sera perdu si vous quittez Mastodon.",
"upload_area.title": "Glissez et déposez pour envoyer",
"upload_button.label": "Joindre un média",
diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json
index 90447ad4c5..f2f0fc260c 100644
--- a/app/javascript/mastodon/locales/gl.json
+++ b/app/javascript/mastodon/locales/gl.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Notificacións",
"tabs_bar.search": "Buscar",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "O borrador perderase se sae de Mastodon.",
"upload_area.title": "Arrastre e solte para subir",
"upload_button.label": "Engadir medios",
diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json
index 5da3e9ebbc..361beebcca 100644
--- a/app/javascript/mastodon/locales/he.json
+++ b/app/javascript/mastodon/locales/he.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "ציר זמן מקומי",
"tabs_bar.notifications": "התראות",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "הטיוטא תאבד אם תעזבו את מסטודון.",
"upload_area.title": "ניתן להעלות על ידי Drag & drop",
"upload_button.label": "הוספת מדיה",
diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json
index 6486284ec4..93dc1c17d2 100644
--- a/app/javascript/mastodon/locales/hr.json
+++ b/app/javascript/mastodon/locales/hr.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Lokalno",
"tabs_bar.notifications": "Notifikacije",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
"upload_area.title": "Povuci i spusti kako bi uploadao",
"upload_button.label": "Dodaj media",
diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json
index 6c04eced63..158c0fe414 100644
--- a/app/javascript/mastodon/locales/hu.json
+++ b/app/javascript/mastodon/locales/hu.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Értesítések",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "A piszkozata el fog vesztődni ha elhagyja Mastodon-t.",
"upload_area.title": "Húzza ide a feltöltéshez",
"upload_button.label": "Média hozzáadása",
diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json
index f1f4df9688..76b3a9c124 100644
--- a/app/javascript/mastodon/locales/hy.json
+++ b/app/javascript/mastodon/locales/hy.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Տեղական",
"tabs_bar.notifications": "Ծանուցումներ",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Քո սեւագիրը կկորի, եթե լքես Մաստոդոնը։",
"upload_area.title": "Քաշիր ու նետիր՝ վերբեռնելու համար",
"upload_button.label": "Ավելացնել մեդիա",
diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json
index e0fa959b07..00240530d0 100644
--- a/app/javascript/mastodon/locales/id.json
+++ b/app/javascript/mastodon/locales/id.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Lokal",
"tabs_bar.notifications": "Notifikasi",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Naskah anda akan hilang jika anda keluar dari Mastodon.",
"upload_area.title": "Seret & lepaskan untuk mengunggah",
"upload_button.label": "Tambahkan media",
diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json
index 616232c3ec..d20ee0f622 100644
--- a/app/javascript/mastodon/locales/io.json
+++ b/app/javascript/mastodon/locales/io.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Lokala",
"tabs_bar.notifications": "Savigi",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
"upload_area.title": "Tranar faligar por kargar",
"upload_button.label": "Adjuntar kontenajo",
diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json
index 6bf9c73a60..485fe0fad8 100644
--- a/app/javascript/mastodon/locales/it.json
+++ b/app/javascript/mastodon/locales/it.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Locale",
"tabs_bar.notifications": "Notifiche",
"tabs_bar.search": "Cerca",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "La bozza andrà persa se esci da Mastodon.",
"upload_area.title": "Trascina per caricare",
"upload_button.label": "Aggiungi file multimediale",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index 09dc624326..614e526e35 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "ローカル",
"tabs_bar.notifications": "通知",
"tabs_bar.search": "検索",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Mastodonから離れると送信前の投稿は失われます。",
"upload_area.title": "ドラッグ&ドロップでアップロード",
"upload_button.label": "メディアを追加",
diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json
index 66657abcdb..edcf5f8176 100644
--- a/app/javascript/mastodon/locales/ko.json
+++ b/app/javascript/mastodon/locales/ko.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "로컬",
"tabs_bar.notifications": "알림",
"tabs_bar.search": "검색",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "지금 나가면 저장되지 않은 항목을 잃게 됩니다.",
"upload_area.title": "드래그 & 드롭으로 업로드",
"upload_button.label": "미디어 추가",
diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json
index 8ddf47f3f5..1ead2011d7 100644
--- a/app/javascript/mastodon/locales/nl.json
+++ b/app/javascript/mastodon/locales/nl.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Lokaal",
"tabs_bar.notifications": "Meldingen",
"tabs_bar.search": "Zoeken",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Je concept zal verloren gaan als je Mastodon verlaat.",
"upload_area.title": "Hierin slepen om te uploaden",
"upload_button.label": "Media toevoegen",
diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json
index ab755a3e8c..d8de2ad4be 100644
--- a/app/javascript/mastodon/locales/no.json
+++ b/app/javascript/mastodon/locales/no.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Lokal",
"tabs_bar.notifications": "Varslinger",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Din kladd vil bli forkastet om du forlater Mastodon.",
"upload_area.title": "Dra og slipp for å laste opp",
"upload_button.label": "Legg til media",
diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json
index 44bb44e977..e7bc148fa3 100644
--- a/app/javascript/mastodon/locales/oc.json
+++ b/app/javascript/mastodon/locales/oc.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Flux public local",
"tabs_bar.notifications": "Notificacions",
"tabs_bar.search": "Recèrcas",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Vòstre brolhon serà perdut se quitatz Mastodon.",
"upload_area.title": "Lisatz e depausatz per mandar",
"upload_button.label": "Ajustar un mèdia",
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json
index 7bfb7643c6..92c17556f2 100644
--- a/app/javascript/mastodon/locales/pl.json
+++ b/app/javascript/mastodon/locales/pl.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Lokalne",
"tabs_bar.notifications": "Powiadomienia",
"tabs_bar.search": "Szukaj",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"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ą",
diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json
index 82bbd17a35..c69a90e620 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Notificações",
"tabs_bar.search": "Buscar",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Seu rascunho será perdido se você sair do Mastodon.",
"upload_area.title": "Arraste e solte para enviar",
"upload_button.label": "Adicionar mídia",
diff --git a/app/javascript/mastodon/locales/pt.json b/app/javascript/mastodon/locales/pt.json
index 6463d001dd..18d66be7f2 100644
--- a/app/javascript/mastodon/locales/pt.json
+++ b/app/javascript/mastodon/locales/pt.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Notificações",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "O teu rascunho vai ser perdido se abandonares o Mastodon.",
"upload_area.title": "Arraste e solte para enviar",
"upload_button.label": "Adicionar media",
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index 6c7926ffe6..577ec99212 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Локальная",
"tabs_bar.notifications": "Уведомления",
"tabs_bar.search": "Поиск",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Ваш черновик будет утерян, если вы покинете Mastodon.",
"upload_area.title": "Перетащите сюда, чтобы загрузить",
"upload_button.label": "Добавить медиаконтент",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index 6ac646bee1..b85ba13181 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Lokálna",
"tabs_bar.notifications": "Notifikácie",
"tabs_bar.search": "Hľadaj",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Čo máte rozpísané sa stratí, ak opustíte Mastodon.",
"upload_area.title": "Ťahaj a pusti pre nahratie",
"upload_button.label": "Pridať médiá",
diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json
index edd5ab62b4..3cc7389ae3 100644
--- a/app/javascript/mastodon/locales/sl.json
+++ b/app/javascript/mastodon/locales/sl.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Lokalno",
"tabs_bar.notifications": "Obvestila",
"tabs_bar.search": "Poišči",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Vaš osnutek bo izgubljen, če zapustite Mastodona.",
"upload_area.title": "Povlecite in spustite za pošiljanje",
"upload_button.label": "Dodaj medij",
diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json
index 2a9d3737d6..e2b55c1794 100644
--- a/app/javascript/mastodon/locales/sr-Latn.json
+++ b/app/javascript/mastodon/locales/sr-Latn.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Lokalno",
"tabs_bar.notifications": "Obaveštenja",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Ako napustite Mastodont, izgubićete napisani nacrt.",
"upload_area.title": "Prevucite ovde da otpremite",
"upload_button.label": "Dodaj multimediju",
diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json
index b53f1ecc98..09efb985cb 100644
--- a/app/javascript/mastodon/locales/sr.json
+++ b/app/javascript/mastodon/locales/sr.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Локално",
"tabs_bar.notifications": "Обавештења",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Ако напустите Мастодонт, изгубићете написани нацрт.",
"upload_area.title": "Превуците овде да отпремите",
"upload_button.label": "Додај мултимедију",
diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json
index dbe2c182ed..6c396e5250 100644
--- a/app/javascript/mastodon/locales/sv.json
+++ b/app/javascript/mastodon/locales/sv.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Lokal",
"tabs_bar.notifications": "Meddelanden",
"tabs_bar.search": "Sök",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Ditt utkast kommer att förloras om du lämnar Mastodon.",
"upload_area.title": "Dra & släpp för att ladda upp",
"upload_button.label": "Lägg till media",
diff --git a/app/javascript/mastodon/locales/te.json b/app/javascript/mastodon/locales/te.json
index 52bd41935b..ce0d4b9cc2 100644
--- a/app/javascript/mastodon/locales/te.json
+++ b/app/javascript/mastodon/locales/te.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Notifications",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
"upload_area.title": "Drag & drop to upload",
"upload_button.label": "Add media",
diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json
index 32aa240804..f0ba25ec37 100644
--- a/app/javascript/mastodon/locales/th.json
+++ b/app/javascript/mastodon/locales/th.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Notifications",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
"upload_area.title": "Drag & drop to upload",
"upload_button.label": "Add media",
diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json
index b73157e27d..89f00fd3b8 100644
--- a/app/javascript/mastodon/locales/tr.json
+++ b/app/javascript/mastodon/locales/tr.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Yerel",
"tabs_bar.notifications": "Bildirimler",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
"upload_area.title": "Upload için sürükle bırak yapınız",
"upload_button.label": "Görsel ekle",
diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json
index b301c6827c..e81476541b 100644
--- a/app/javascript/mastodon/locales/uk.json
+++ b/app/javascript/mastodon/locales/uk.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "Локальна",
"tabs_bar.notifications": "Сповіщення",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
"upload_area.title": "Перетягніть сюди, щоб завантажити",
"upload_button.label": "Додати медіаконтент",
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index 455f1f828b..05194c9094 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "本站",
"tabs_bar.notifications": "通知",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "如果你现在离开 Mastodon,你的草稿内容将会被丢弃。",
"upload_area.title": "将文件拖放到此处开始上传",
"upload_button.label": "上传媒体文件",
diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json
index 18be177924..cad53c69ac 100644
--- a/app/javascript/mastodon/locales/zh-HK.json
+++ b/app/javascript/mastodon/locales/zh-HK.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "本站",
"tabs_bar.notifications": "通知",
"tabs_bar.search": "搜尋",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "如果你現在離開 Mastodon,你的草稿內容將會被丟棄。",
"upload_area.title": "將檔案拖放至此上載",
"upload_button.label": "上載媒體檔案",
diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json
index 3222c035a5..91b44012f0 100644
--- a/app/javascript/mastodon/locales/zh-TW.json
+++ b/app/javascript/mastodon/locales/zh-TW.json
@@ -280,6 +280,8 @@
"tabs_bar.local_timeline": "本地",
"tabs_bar.notifications": "通知",
"tabs_bar.search": "Search",
+ "timeline.media": "Media",
+ "timeline.posts": "Toots",
"ui.beforeunload": "如果離開 Mastodon,你的草稿將會不見。",
"upload_area.title": "拖放來上傳",
"upload_button.label": "增加媒體",
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 90325be9c4..0765b3ffc5 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -4737,6 +4737,8 @@ a.status-card {
}
}
+.community-timeline__section-headline,
+.public-timeline__section-headline,
.account__section-headline {
background: darken($ui-base-color, 4%);
border-bottom: 1px solid lighten($ui-base-color, 8%);
diff --git a/app/services/batched_remove_status_service.rb b/app/services/batched_remove_status_service.rb
index cb65a22565..425a11d012 100644
--- a/app/services/batched_remove_status_service.rb
+++ b/app/services/batched_remove_status_service.rb
@@ -81,6 +81,11 @@ class BatchedRemoveStatusService < BaseService
redis.publish('timeline:public', payload)
redis.publish('timeline:public:local', payload) if status.local?
+ if status.media_attachments.exists?
+ redis.publish('timeline:public:media', payload)
+ redis.publish('timeline:public:local:media', payload) if status.local?
+ end
+
@tags[status.id].each do |hashtag|
redis.publish("timeline:hashtag:#{hashtag}", payload)
redis.publish("timeline:hashtag:#{hashtag}:local", payload) if status.local?
diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb
index cb82a79ed3..b4b9986f3b 100644
--- a/app/services/fan_out_on_write_service.rb
+++ b/app/services/fan_out_on_write_service.rb
@@ -25,6 +25,7 @@ class FanOutOnWriteService < BaseService
return if status.reply? && status.in_reply_to_account_id != status.account_id
deliver_to_public(status)
+ deliver_to_media(status) if status.media_attachments.exists?
end
private
@@ -85,6 +86,13 @@ class FanOutOnWriteService < BaseService
Redis.current.publish('timeline:public:local', @payload) if status.local?
end
+ def deliver_to_media(status)
+ Rails.logger.debug "Delivering status #{status.id} to media timeline"
+
+ Redis.current.publish('timeline:public:media', @payload)
+ Redis.current.publish('timeline:public:local:media', @payload) if status.local?
+ end
+
def deliver_to_direct_timelines(status)
Rails.logger.debug "Delivering status #{status.id} to direct timelines"
diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb
index e164c03ab1..53f2be6f86 100644
--- a/app/services/remove_status_service.rb
+++ b/app/services/remove_status_service.rb
@@ -20,6 +20,7 @@ class RemoveStatusService < BaseService
remove_reblogs
remove_from_hashtags
remove_from_public
+ remove_from_media if status.media_attachments.exists?
remove_from_direct if status.direct_visibility?
@status.destroy!
@@ -131,6 +132,13 @@ class RemoveStatusService < BaseService
Redis.current.publish('timeline:public:local', @payload) if @status.local?
end
+ def remove_from_media
+ return unless @status.public_visibility?
+
+ Redis.current.publish('timeline:public:media', @payload)
+ Redis.current.publish('timeline:public:local:media', @payload) if @status.local?
+ end
+
def remove_from_direct
@mentions.each do |mention|
Redis.current.publish("timeline:direct:#{mention.account.id}", @payload) if mention.account.local?
diff --git a/streaming/index.js b/streaming/index.js
index 48bab8078e..4eaf668658 100644
--- a/streaming/index.js
+++ b/streaming/index.js
@@ -241,7 +241,9 @@ const startWorker = (workerId) => {
const PUBLIC_STREAMS = [
'public',
+ 'public:media',
'public:local',
+ 'public:local:media',
'hashtag',
'hashtag:local',
];
@@ -459,11 +461,17 @@ const startWorker = (workerId) => {
});
app.get('/api/v1/streaming/public', (req, res) => {
- streamFrom('timeline:public', req, streamToHttp(req, res), streamHttpEnd(req), true);
+ const onlyMedia = req.query.only_media === '1' || req.query.only_media === 'true';
+ const channel = onlyMedia ? 'timeline:public:media' : 'timeline:public';
+
+ streamFrom(channel, req, streamToHttp(req, res), streamHttpEnd(req), true);
});
app.get('/api/v1/streaming/public/local', (req, res) => {
- streamFrom('timeline:public:local', req, streamToHttp(req, res), streamHttpEnd(req), true);
+ const onlyMedia = req.query.only_media === '1' || req.query.only_media === 'true';
+ const channel = onlyMedia ? 'timeline:public:local:media' : 'timeline:public:local';
+
+ streamFrom(channel, req, streamToHttp(req, res), streamHttpEnd(req), true);
});
app.get('/api/v1/streaming/direct', (req, res) => {
@@ -521,6 +529,12 @@ const startWorker = (workerId) => {
case 'public:local':
streamFrom('timeline:public:local', req, streamToWs(req, ws), streamWsEnd(req, ws), true);
break;
+ case 'public:media':
+ streamFrom('timeline:public:media', req, streamToWs(req, ws), streamWsEnd(req, ws), true);
+ break;
+ case 'public:local:media':
+ streamFrom('timeline:public:local:media', req, streamToWs(req, ws), streamWsEnd(req, ws), true);
+ break;
case 'direct':
streamFrom(`timeline:direct:${req.accountId}`, req, streamToWs(req, ws), streamWsEnd(req, ws), true);
break;