diff --git a/app/javascript/mastodon/features/gallery_timeline/components/column_settings.js b/app/javascript/mastodon/features/gallery_timeline/components/column_settings.js
new file mode 100644
index 000000000..0cb6db883
--- /dev/null
+++ b/app/javascript/mastodon/features/gallery_timeline/components/column_settings.js
@@ -0,0 +1,29 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import { injectIntl, FormattedMessage } from 'react-intl';
+import SettingToggle from '../../notifications/components/setting_toggle';
+
+export default @injectIntl
+class ColumnSettings extends React.PureComponent {
+
+ static propTypes = {
+ settings: ImmutablePropTypes.map.isRequired,
+ onChange: PropTypes.func.isRequired,
+ intl: PropTypes.object.isRequired,
+ columnId: PropTypes.string,
+ };
+
+ render () {
+ const { settings, onChange } = this.props;
+
+ return (
+
+ );
+ }
+
+}
diff --git a/app/javascript/mastodon/features/gallery_timeline/containers/column_settings_container.js b/app/javascript/mastodon/features/gallery_timeline/containers/column_settings_container.js
new file mode 100644
index 000000000..405064c3f
--- /dev/null
+++ b/app/javascript/mastodon/features/gallery_timeline/containers/column_settings_container.js
@@ -0,0 +1,28 @@
+import { connect } from 'react-redux';
+import ColumnSettings from '../components/column_settings';
+import { changeSetting } from '../../../actions/settings';
+import { changeColumnParams } from '../../../actions/columns';
+
+const mapStateToProps = (state, { columnId }) => {
+ const uuid = columnId;
+ const columns = state.getIn(['settings', 'columns']);
+ const index = columns.findIndex(c => c.get('uuid') === uuid);
+
+ return {
+ settings: (uuid && index >= 0) ? columns.get(index).get('params') : state.getIn(['settings', 'community']),
+ };
+};
+
+const mapDispatchToProps = (dispatch, { columnId }) => {
+ return {
+ onChange (key, checked) {
+ if (columnId) {
+ dispatch(changeColumnParams(columnId, key, checked));
+ } else {
+ dispatch(changeSetting(['community', ...key], checked));
+ }
+ },
+ };
+};
+
+export default connect(mapStateToProps, mapDispatchToProps)(ColumnSettings);
diff --git a/app/javascript/mastodon/features/gallery_timeline/index.js b/app/javascript/mastodon/features/gallery_timeline/index.js
new file mode 100644
index 000000000..c18cf4f4e
--- /dev/null
+++ b/app/javascript/mastodon/features/gallery_timeline/index.js
@@ -0,0 +1,139 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+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 ColumnSettingsContainer from './containers/column_settings_container';
+import { connectCommunityStream } from '../../actions/streaming';
+
+const messages = defineMessages({
+ title: { id: 'column.community', defaultMessage: 'Local timeline' },
+});
+
+const mapStateToProps = (state, { columnId }) => {
+ const uuid = columnId;
+ const columns = state.getIn(['settings', 'columns']);
+ const index = columns.findIndex(c => c.get('uuid') === uuid);
+ const onlyMedia = (columnId && index >= 0) ? columns.get(index).getIn(['params', 'other', 'onlyMedia']) : state.getIn(['settings', 'community', 'other', 'onlyMedia']);
+ const timelineState = state.getIn(['timelines', `community${onlyMedia ? ':media' : ''}`]);
+
+ return {
+ hasUnread: !!timelineState && timelineState.get('unread') > 0,
+ onlyMedia,
+ };
+};
+
+export default @connect(mapStateToProps)
+@injectIntl
+class GalleryTimeline extends React.PureComponent {
+
+ static contextTypes = {
+ router: PropTypes.object,
+ };
+
+ static defaultProps = {
+ onlyMedia: false,
+ };
+
+ static propTypes = {
+ dispatch: PropTypes.func.isRequired,
+ shouldUpdateScroll: PropTypes.func,
+ columnId: PropTypes.string,
+ intl: PropTypes.object.isRequired,
+ hasUnread: PropTypes.bool,
+ multiColumn: PropTypes.bool,
+ onlyMedia: PropTypes.bool,
+ };
+
+ handlePin = () => {
+ const { columnId, dispatch } = this.props;
+
+ const onlyMedia = true;
+
+ if (columnId) {
+ dispatch(removeColumn(columnId));
+ } else {
+ dispatch(addColumn('COMMUNITY', { other: { onlyMedia } }));
+ }
+ }
+
+ handleMove = (dir) => {
+ const { columnId, dispatch } = this.props;
+ dispatch(moveColumn(columnId, dir));
+ }
+
+ handleHeaderClick = () => {
+ this.column.scrollTop();
+ }
+
+ componentDidMount () {
+ const { dispatch, onlyMedia } = this.props;
+
+ dispatch(expandCommunityTimeline({ onlyMedia }));
+ this.disconnect = dispatch(connectCommunityStream({ onlyMedia }));
+ }
+
+ componentDidUpdate (prevProps) {
+ if (prevProps.onlyMedia !== this.props.onlyMedia) {
+ const { dispatch, onlyMedia } = this.props;
+
+ this.disconnect();
+ dispatch(expandCommunityTimeline({ onlyMedia }));
+ this.disconnect = dispatch(connectCommunityStream({ onlyMedia }));
+ }
+ }
+
+ componentWillUnmount () {
+ if (this.disconnect) {
+ this.disconnect();
+ this.disconnect = null;
+ }
+ }
+
+ setRef = c => {
+ this.column = c;
+ }
+
+ handleLoadMore = maxId => {
+ const { dispatch, onlyMedia } = this.props;
+
+ dispatch(expandCommunityTimeline({ maxId, onlyMedia }));
+ }
+
+ render () {
+ const { intl, shouldUpdateScroll, hasUnread, columnId, multiColumn, onlyMedia } = this.props;
+ const pinned = !!columnId;
+
+ return (
+
+
+
+
+
+ }
+ shouldUpdateScroll={shouldUpdateScroll}
+ bindToDocument={!multiColumn}
+ />
+
+ );
+ }
+
+}
diff --git a/app/javascript/mastodon/features/ui/components/bliss/gallery-tk.js b/app/javascript/mastodon/features/ui/components/bliss/gallery-tk.js
new file mode 100644
index 000000000..3ddc52198
--- /dev/null
+++ b/app/javascript/mastodon/features/ui/components/bliss/gallery-tk.js
@@ -0,0 +1,15 @@
+import React from 'react';
+
+export default class GalleryTk extends React.PureComponent {
+
+
+ render() {
+
+ return (
+
+
La page de gallerie
+
+ );
+ }
+
+}
diff --git a/app/javascript/mastodon/features/ui/components/navigation_panel.js b/app/javascript/mastodon/features/ui/components/navigation_panel.js
index ed4396af1..afda16d11 100644
--- a/app/javascript/mastodon/features/ui/components/navigation_panel.js
+++ b/app/javascript/mastodon/features/ui/components/navigation_panel.js
@@ -52,7 +52,21 @@ const NavigationPanel = () => (
id='tabs_bar.federated_timeline'
defaultMessage='Federated'
/>
-
+
+
ends up in the application bundle.
// Without this it ends up in ~8 very commonly used bundles.
import '../../components/status';
+import GalleryTk from './components/bliss/gallery-tk';
const messages = defineMessages({
beforeUnload: { id: 'ui.beforeunload', defaultMessage: 'Your draft will be lost if you leave Mastodon.' },
@@ -159,6 +161,7 @@ class SwitchingColumnsArea extends React.PureComponent {
+
diff --git a/app/javascript/mastodon/features/ui/util/async-components.js b/app/javascript/mastodon/features/ui/util/async-components.js
index 986efda1e..1f7ce7bb6 100644
--- a/app/javascript/mastodon/features/ui/util/async-components.js
+++ b/app/javascript/mastodon/features/ui/util/async-components.js
@@ -21,6 +21,9 @@ export function PublicTimeline () {
export function CommunityTimeline () {
return import(/* webpackChunkName: "features/community_timeline" */'../../community_timeline');
}
+export function GalleryTimeline () {
+ return import(/* webpackChunkName: "features/gallery_timeline" */'../../gallery_timeline');
+}
export function HashtagTimeline () {
return import(/* webpackChunkName: "features/hashtag_timeline" */'../../hashtag_timeline');