diff --git a/app/assets/javascripts/components/components/status_list.jsx b/app/assets/javascripts/components/components/status_list.jsx
index 0e64f0ee6a3..69a2354c762 100644
--- a/app/assets/javascripts/components/components/status_list.jsx
+++ b/app/assets/javascripts/components/components/status_list.jsx
@@ -14,7 +14,8 @@ const StatusList = React.createClass({
onScroll: React.PropTypes.func,
trackScroll: React.PropTypes.bool,
isLoading: React.PropTypes.bool,
- prepend: React.PropTypes.node
+ prepend: React.PropTypes.node,
+ emptyMessage: React.PropTypes.node
},
getDefaultProps () {
@@ -71,27 +72,36 @@ const StatusList = React.createClass({
},
render () {
- const { statusIds, onScrollToBottom, trackScroll, isLoading, prepend } = this.props;
+ const { statusIds, onScrollToBottom, trackScroll, isLoading, prepend, emptyMessage } = this.props;
let loadMore = '';
+ let scrollableArea = '';
if (!isLoading && statusIds.size > 0) {
loadMore = ;
}
- const scrollableArea = (
-
-
- {prepend}
+ if (isLoading || statusIds.size > 0 || !emptyMessage) {
+ scrollableArea = (
+
+
+ {prepend}
- {statusIds.map((statusId) => {
- return ;
- })}
+ {statusIds.map((statusId) => {
+ return ;
+ })}
- {loadMore}
+ {loadMore}
+
-
- );
+ );
+ } else {
+ scrollableArea = (
+
+ {emptyMessage}
+
+ );
+ }
if (trackScroll) {
return (
diff --git a/app/assets/javascripts/components/features/hashtag_timeline/index.jsx b/app/assets/javascripts/components/features/hashtag_timeline/index.jsx
index 4a0e7684dce..6cb9e54828f 100644
--- a/app/assets/javascripts/components/features/hashtag_timeline/index.jsx
+++ b/app/assets/javascripts/components/features/hashtag_timeline/index.jsx
@@ -8,6 +8,7 @@ import {
deleteFromTimelines
} from '../../actions/timelines';
import ColumnBackButtonSlim from '../../components/column_back_button_slim';
+import { FormattedMessage } from 'react-intl';
import createStream from '../../stream';
const mapStateToProps = state => ({
@@ -76,7 +77,7 @@ const HashtagTimeline = React.createClass({
return (
-
+ } />
);
},
diff --git a/app/assets/javascripts/components/features/home_timeline/index.jsx b/app/assets/javascripts/components/features/home_timeline/index.jsx
index 5d2263f1562..23e1987018b 100644
--- a/app/assets/javascripts/components/features/home_timeline/index.jsx
+++ b/app/assets/javascripts/components/features/home_timeline/index.jsx
@@ -1,8 +1,9 @@
import PureRenderMixin from 'react-addons-pure-render-mixin';
import StatusListContainer from '../ui/containers/status_list_container';
import Column from '../ui/components/column';
-import { defineMessages, injectIntl } from 'react-intl';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import ColumnSettingsContainer from './containers/column_settings_container';
+import { Link } from 'react-router';
const messages = defineMessages({
title: { id: 'column.home', defaultMessage: 'Home' }
@@ -22,7 +23,7 @@ const HomeTimeline = React.createClass({
return (
-
+ }} />} />
);
},
diff --git a/app/assets/javascripts/components/features/notifications/index.jsx b/app/assets/javascripts/components/features/notifications/index.jsx
index 6d10768ded9..9532b8af823 100644
--- a/app/assets/javascripts/components/features/notifications/index.jsx
+++ b/app/assets/javascripts/components/features/notifications/index.jsx
@@ -5,7 +5,7 @@ import Column from '../ui/components/column';
import { expandNotifications, clearNotifications } from '../../actions/notifications';
import NotificationContainer from './containers/notification_container';
import { ScrollContainer } from 'react-router-scroll';
-import { defineMessages, injectIntl } from 'react-intl';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import ColumnSettingsContainer from './containers/column_settings_container';
import { createSelector } from 'reselect';
import Immutable from 'immutable';
@@ -76,20 +76,29 @@ const Notifications = React.createClass({
render () {
const { intl, notifications, trackScroll, isLoading } = this.props;
- let loadMore = '';
+ let loadMore = '';
+ let scrollableArea = '';
if (!isLoading && notifications.size > 0) {
loadMore =
;
}
- const scrollableArea = (
-
-
- {notifications.map(item =>
)}
- {loadMore}
+ if (isLoading || notifications.size > 0) {
+ scrollableArea = (
+
+
+ {notifications.map(item => )}
+ {loadMore}
+
-
- );
+ );
+ } else {
+ scrollableArea = (
+
+
+
+ );
+ }
if (trackScroll) {
return (
diff --git a/app/assets/javascripts/components/features/status/index.jsx b/app/assets/javascripts/components/features/status/index.jsx
index 40c0460a594..e17c078d275 100644
--- a/app/assets/javascripts/components/features/status/index.jsx
+++ b/app/assets/javascripts/components/features/status/index.jsx
@@ -1,29 +1,34 @@
-import { connect } from 'react-redux';
-import PureRenderMixin from 'react-addons-pure-render-mixin';
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import { fetchStatus } from '../../actions/statuses';
-import Immutable from 'immutable';
-import EmbeddedStatus from '../../components/status';
-import LoadingIndicator from '../../components/loading_indicator';
-import DetailedStatus from './components/detailed_status';
-import ActionBar from './components/action_bar';
-import Column from '../ui/components/column';
-import { favourite, reblog } from '../../actions/interactions';
+import { connect } from 'react-redux';
+import PureRenderMixin from 'react-addons-pure-render-mixin';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import { fetchStatus } from '../../actions/statuses';
+import Immutable from 'immutable';
+import EmbeddedStatus from '../../components/status';
+import LoadingIndicator from '../../components/loading_indicator';
+import DetailedStatus from './components/detailed_status';
+import ActionBar from './components/action_bar';
+import Column from '../ui/components/column';
+import {
+ favourite,
+ unfavourite,
+ reblog,
+ unreblog
+} from '../../actions/interactions';
import {
replyCompose,
mentionCompose
-} from '../../actions/compose';
-import { deleteStatus } from '../../actions/statuses';
+} from '../../actions/compose';
+import { deleteStatus } from '../../actions/statuses';
import { initReport } from '../../actions/reports';
import {
makeGetStatus,
getStatusAncestors,
getStatusDescendants
-} from '../../selectors';
-import { ScrollContainer } from 'react-router-scroll';
-import ColumnBackButton from '../../components/column_back_button';
-import StatusContainer from '../../containers/status_container';
-import { openMedia } from '../../actions/modal';
+} from '../../selectors';
+import { ScrollContainer } from 'react-router-scroll';
+import ColumnBackButton from '../../components/column_back_button';
+import StatusContainer from '../../containers/status_container';
+import { openMedia } from '../../actions/modal';
import { isMobile } from '../../is_mobile'
const makeMapStateToProps = () => {
diff --git a/app/assets/javascripts/components/reducers/compose.jsx b/app/assets/javascripts/components/reducers/compose.jsx
index 77ec2705f08..8d281048e1b 100644
--- a/app/assets/javascripts/components/reducers/compose.jsx
+++ b/app/assets/javascripts/components/reducers/compose.jsx
@@ -126,8 +126,8 @@ export default function compose(state = initialState, action) {
return state.withMutations(map => {
map.set('in_reply_to', action.status.get('id'));
map.set('text', statusToTextMentions(state, action.status));
- map.set('unlisted', action.status.get('visibility') === 'unlisted');
- map.set('private', action.status.get('visibility') === 'private');
+ map.set('unlisted', action.status.get('visibility') === 'unlisted' || state.get('default_privacy') === 'unlisted');
+ map.set('private', action.status.get('visibility') === 'private' || state.get('default_privacy') === 'private');
});
case COMPOSE_REPLY_CANCEL:
return state.withMutations(map => {
diff --git a/app/assets/stylesheets/components.scss b/app/assets/stylesheets/components.scss
index 912405a9f63..bc56891f39f 100644
--- a/app/assets/stylesheets/components.scss
+++ b/app/assets/stylesheets/components.scss
@@ -1182,3 +1182,22 @@ button.active i.fa-retweet {
background: rgba($color8, 0.1);
}
}
+
+.empty-column-indicator {
+ color: lighten($color1, 20%);
+ text-align: center;
+ padding: 20px;
+ padding-top: 100px;
+ font-size: 15px;
+ font-weight: 400;
+ cursor: default;
+
+ a {
+ color: $color4;
+ text-decoration: none;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+}