Add suggestions columns

This commit is contained in:
noellabo 2021-03-29 21:21:56 +09:00
parent cfce94fb24
commit 2de85178bd
8 changed files with 139 additions and 2 deletions

View file

@ -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(
<ColumnLink key='suggestions' icon='user-plus' text={intl.formatMessage(messages.suggestions)} to='/suggestions' />,
<ColumnLink key='trends' icon='line-chart' text={intl.formatMessage(messages.trends)} to='/trends' />,
);
height += 48;
height += 48*2;
navItems.push(
<ColumnLink key='information_acct' icon='info-circle' text={intl.formatMessage(messages.information_acct)} to='/accounts/2' />,
@ -155,10 +157,11 @@ class GettingStarted extends ImmutablePureComponent {
}
navItems.push(
<ColumnLink key='suggestions' icon='user-plus' text={intl.formatMessage(messages.suggestions)} to='/suggestions' />,
<ColumnLink key='trends' icon='line-chart' text={intl.formatMessage(messages.trends)} to='/trends' />,
);
height += 48;
height += 48*2;
navItems.push(
<ColumnLink key='information_acct' icon='info-circle' text={intl.formatMessage(messages.information_acct)} to='/accounts/2' />,

View file

@ -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 = <FormattedMessage id='empty_column.suggestions' defaultMessage='No one has suggestions yet.' />;
return (
<Column bindToDocument={!multiColumn} ref={this.setRef} label={intl.formatMessage(messages.heading)}>
<ColumnHeader
icon='user-plus'
title={intl.formatMessage(messages.heading)}
onPin={this.handlePin}
onMove={this.handleMove}
onClick={this.handleHeaderClick}
pinned={pinned}
multiColumn={multiColumn}
showBackButton
/>
<ScrollableList
trackScroll={!pinned}
scrollKey={`suggestions-${columnId}`}
isLoading={isLoading}
emptyMessage={emptyMessage}
prepend={<ColumnSubheading text={intl.formatMessage(messages.subheading)} />}
bindToDocument={!multiColumn}
>
{suggestions && suggestions.map(suggestion => (
<AccountContainer
key={suggestion.get('account')}
id={suggestion.get('account')}
actionIcon={suggestion.get('source') === 'past_interaction' ? 'times' : null}
actionTitle={suggestion.get('source') === 'past_interaction' ? intl.formatMessage(messages.dismissSuggestion) : null}
onActionClick={dismissSuggestion}
/>
))}
</ScrollableList>
</Column>
);
}
}

View file

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

View file

@ -25,6 +25,7 @@ const NavigationPanel = () => (
<NavLink className='column-link column-link--transparent' to='/circles'><Icon className='column-link__icon' id='user-circle' fixedWidth /><FormattedMessage id='navigation_bar.circles' defaultMessage='Circles' /></NavLink>
<NavLink className='column-link column-link--transparent' to='/group_directory'><Icon className='column-link__icon' id='address-book-o' fixedWidth /><FormattedMessage id='getting_started.group_directory' defaultMessage='Group directory' /></NavLink>
{profile_directory && <NavLink className='column-link column-link--transparent' to='/directory'><Icon className='column-link__icon' id='address-book-o' fixedWidth /><FormattedMessage id='getting_started.directory' defaultMessage='Profile directory' /></NavLink>}
<NavLink className='column-link column-link--transparent' to='/suggestions'><Icon className='column-link__icon' id='user-plus' fixedWidth /><FormattedMessage id='navigation_bar.suggestions' defaultMessage='Suggestions' /></NavLink>
<NavLink className='column-link column-link--transparent' to='/trends'><Icon className='column-link__icon' id='line-chart' fixedWidth /><FormattedMessage id='navigation_bar.trends' defaultMessage='Trends' /></NavLink>
<ListPanel />

View file

@ -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 {
<WrappedRoute path='/group_directory' component={GroupDirectory} content={children} />
<WrappedRoute path='/directory' component={Directory} content={children} />
<WrappedRoute path='/trends' component={Trends} content={children} />
<WrappedRoute path='/suggestions' component={Suggestions} content={children} />
<WrappedRoute path='/statuses/new' component={Compose} content={children} />
<WrappedRoute path='/statuses/:statusId' exact component={Status} content={children} />

View file

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

View file

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

View file

@ -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": "リスト",