diff --git a/app/javascript/mastodon/features/getting_started/index.js b/app/javascript/mastodon/features/getting_started/index.js index 4316328e2..13b2122fc 100644 --- a/app/javascript/mastodon/features/getting_started/index.js +++ b/app/javascript/mastodon/features/getting_started/index.js @@ -37,6 +37,7 @@ const messages = defineMessages({ menu: { id: 'getting_started.heading', defaultMessage: 'Getting started' }, group_directory: { id: 'getting_started.group_directory', defaultMessage: 'Group directory' }, profile_directory: { id: 'getting_started.directory', defaultMessage: 'Profile directory' }, + suggestions: { id: 'navigation_bar.suggestions', defaultMessage: 'Suggestions' }, trends: { id: 'navigation_bar.trends', defaultMessage: 'Trends' }, information_acct: { id: 'navigation_bar.information_acct', defaultMessage: 'Fedibird info' }, hashtag_fedibird: { id: 'navigation_bar.hashtag_fedibird', defaultMessage: 'fedibird' }, @@ -122,10 +123,11 @@ class GettingStarted extends ImmutablePureComponent { } navItems.push( + , , ); - height += 48; + height += 48*2; navItems.push( , @@ -155,10 +157,11 @@ class GettingStarted extends ImmutablePureComponent { } navItems.push( + , , ); - height += 48; + height += 48*2; navItems.push( , diff --git a/app/javascript/mastodon/features/suggestions/index.js b/app/javascript/mastodon/features/suggestions/index.js new file mode 100644 index 000000000..515cef4e5 --- /dev/null +++ b/app/javascript/mastodon/features/suggestions/index.js @@ -0,0 +1,119 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import PropTypes from 'prop-types'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import { fetchSuggestions, dismissSuggestion } from 'mastodon/actions/suggestions'; +import Column from '../ui/components/column'; +import ColumnHeader from '../../components/column_header'; +import ColumnSubheading from '../ui/components/column_subheading'; +import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; +import ScrollableList from 'mastodon/components/scrollable_list'; +import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; +import AccountContainer from 'mastodon/containers/account_container'; +import ImmutablePureComponent from 'react-immutable-pure-component'; + +const messages = defineMessages({ + heading: { id: 'suggestions.heading', defaultMessage: 'Suggestions' }, + subheading: { id: 'suggestions.header', defaultMessage: 'You might be interested in…' }, + dismissSuggestion: { id: 'suggestions.dismiss', defaultMessage: 'Dismiss suggestion' }, +}); + +const mapStateToProps = state => ({ + suggestions: state.getIn(['suggestions', 'items']), + isLoading: state.getIn(['suggestions', 'isLoading'], true), +}); + +export default @connect(mapStateToProps) +@injectIntl +class Suggestions extends ImmutablePureComponent { + + static propTypes = { + dispatch: PropTypes.func.isRequired, + suggestions: ImmutablePropTypes.list.isRequired, + intl: PropTypes.object.isRequired, + columnId: PropTypes.string, + multiColumn: PropTypes.bool, + isLoading: PropTypes.bool, + }; + + componentDidMount () { + this.fetchSuggestions(); + } + + fetchSuggestions = () => { + const { dispatch } = this.props; + + dispatch(fetchSuggestions()); + } + + dismissSuggestion = account => { + const { dispatch } = this.props; + + dispatch(dismissSuggestion(account.get('id'))); + } + + handlePin = () => { + const { columnId, dispatch } = this.props; + + if (columnId) { + dispatch(removeColumn(columnId)); + } else { + dispatch(addColumn('SUGGESTIONS', {})); + } + } + + handleMove = (dir) => { + const { columnId, dispatch } = this.props; + dispatch(moveColumn(columnId, dir)); + } + + handleHeaderClick = () => { + this.column.scrollTop(); + } + + setRef = c => { + this.column = c; + } + + render () { + const { intl, suggestions, columnId, multiColumn, isLoading } = this.props; + const pinned = !!columnId; + + const emptyMessage = ; + + return ( + + + + } + bindToDocument={!multiColumn} + > + {suggestions && suggestions.map(suggestion => ( + + ))} + + + ); + } + +} diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.js index 3c1f07af6..c7f30aab1 100644 --- a/app/javascript/mastodon/features/ui/components/columns_area.js +++ b/app/javascript/mastodon/features/ui/components/columns_area.js @@ -29,6 +29,7 @@ import { GroupDirectory, Directory, Trends, + Suggestions, } from '../../ui/util/async-components'; import Icon from 'mastodon/components/icon'; import ComposePanel from './compose_panel'; @@ -56,6 +57,7 @@ const componentMap = { 'GROUP_DIRECTORY': GroupDirectory, 'DIRECTORY': Directory, 'TRENDS': Trends, + 'SUGGESTIONS': Suggestions, }; const messages = defineMessages({ diff --git a/app/javascript/mastodon/features/ui/components/navigation_panel.js b/app/javascript/mastodon/features/ui/components/navigation_panel.js index 5e2adedc5..71999ddda 100644 --- a/app/javascript/mastodon/features/ui/components/navigation_panel.js +++ b/app/javascript/mastodon/features/ui/components/navigation_panel.js @@ -25,6 +25,7 @@ const NavigationPanel = () => ( {profile_directory && } + diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js index 1629b0dbd..625e8d41d 100644 --- a/app/javascript/mastodon/features/ui/index.js +++ b/app/javascript/mastodon/features/ui/index.js @@ -58,6 +58,7 @@ import { Directory, FollowRecommendations, Trends, + Suggestions, } from './util/async-components'; import { me } from '../../initial_state'; import { closeOnboarding, INTRODUCTION_VERSION } from 'mastodon/actions/onboarding'; @@ -175,6 +176,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 c98e4a51a..f4fd13383 100644 --- a/app/javascript/mastodon/features/ui/util/async-components.js +++ b/app/javascript/mastodon/features/ui/util/async-components.js @@ -189,3 +189,7 @@ export function FollowRecommendations () { export function Trends () { return import(/* webpackChunkName: "features/trends" */'../../trends'); } + +export function Suggestions () { + return import(/* webpackChunkName: "features/suggestions" */'../../suggestions'); +} diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 48b5ba56e..6f0903aea 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -203,6 +203,7 @@ "empty_column.mutes": "You haven't muted any users yet.", "empty_column.notifications": "You don't have any notifications yet. When other people interact with you, you will see it here.", "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up", + "empty_column.suggestions": "No one has suggestions yet.", "empty_column.trends": "No one has trends yet.", "error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.", "error.unexpected_crash.explanation_addons": "This page could not be displayed correctly. This error is likely caused by a browser add-on or automatic translation tools.", @@ -346,6 +347,7 @@ "navigation_bar.short.preferences": "Pref.", "navigation_bar.short.public_timeline": "FTL", "navigation_bar.short.search": "Search", + "navigation_bar.suggestions": "Suggestions", "navigation_bar.trends": "Trends", "notification.favourite": "{name} favourited your post", "notification.follow": "{name} followed you", @@ -489,6 +491,7 @@ "status.unpin": "Unpin from profile", "suggestions.dismiss": "Dismiss suggestion", "suggestions.header": "You might be interested in…", + "suggestions.heading": "Suggestions", "tabs_bar.federated_timeline": "Federated", "tabs_bar.home": "Home", "tabs_bar.lists": "List", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index bdc6bfaf5..bd2f0eab6 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -202,6 +202,7 @@ "empty_column.lists": "まだリストがありません。リストを作るとここに表示されます。", "empty_column.mutes": "まだ誰もミュートしていません。", "empty_column.notifications": "まだ通知がありません。他の人とふれ合って会話を始めましょう。", + "empty_column.suggestions": "まだおすすめできるユーザーがいません。", "empty_column.trends": "まだ何もトレンドがありません。", "empty_column.public": "ここにはまだ何もありません! 公開で何かを投稿したり、他のサーバーのユーザーをフォローしたりしていっぱいにしましょう", "error.unexpected_crash.explanation": "不具合かブラウザの互換性問題のため、このページを正しく表示できませんでした。", @@ -346,6 +347,7 @@ "navigation_bar.short.preferences": "設定", "navigation_bar.short.public_timeline": "連合", "navigation_bar.short.search": "検索", + "navigation_bar.suggestions": "おすすめユーザー", "navigation_bar.trends": "トレンド", "notification.favourite": "{name}さんがあなたの投稿をお気に入りに登録しました", "notification.follow": "{name}さんにフォローされました", @@ -489,6 +491,7 @@ "status.unpin": "プロフィールへの固定を解除", "suggestions.dismiss": "隠す", "suggestions.header": "興味あるかもしれません…", + "suggestions.heading": "おすすめユーザー", "tabs_bar.federated_timeline": "連合", "tabs_bar.home": "ホーム", "tabs_bar.lists": "リスト",