Use upstream's Icon component

Rework the codebase to avoid unnecessary differences with upstream
pull/1216/head
Thibaut Girka 2019-09-09 15:28:45 +02:00 committed by ThibG
parent f2b307af25
commit f154d9d6e9
18 changed files with 62 additions and 66 deletions

View File

@ -1,26 +1,21 @@
// Package imports.
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
export default class Icon extends React.PureComponent {
static propTypes = {
id: PropTypes.string.isRequired,
className: PropTypes.string,
fixedWidth: PropTypes.bool,
};
render () {
const { id, className, fixedWidth, ...other } = this.props;
return (
<i role='img' className={classNames('fa', `fa-${id}`, className, { 'fa-fw': fixedWidth })} {...other} />
);
}
// This just renders a FontAwesome icon.
export default function Icon ({
className,
fullwidth,
icon,
}) {
const computedClass = classNames('icon', 'fa', { 'fa-fw': fullwidth }, `fa-${icon}`, className);
return icon ? (
<span
aria-hidden='true'
className={computedClass}
/>
) : null;
}
// Props.
Icon.propTypes = {
className: PropTypes.string,
fullwidth: PropTypes.bool,
icon: PropTypes.string,
};

View File

@ -3,6 +3,7 @@ import Motion from 'flavours/glitch/util/optional_motion';
import spring from 'react-motion/lib/spring';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import Icon from 'flavours/glitch/components/icon';
export default class IconButton extends React.PureComponent {
@ -133,7 +134,7 @@ export default class IconButton extends React.PureComponent {
tabIndex={tabIndex}
disabled={disabled}
>
<i className={`fa fa-fw fa-${icon}`} aria-hidden='true' />
<Icon id={icon} fixedWidth aria-hidden='true' />
</button>
);
}
@ -155,7 +156,7 @@ export default class IconButton extends React.PureComponent {
tabIndex={tabIndex}
disabled={disabled}
>
<i style={{ transform: `rotate(${rotate}deg)` }} className={`fa fa-fw fa-${icon}`} aria-hidden='true' />
<Icon id={icon} style={{ transform: `rotate(${rotate}deg)` }} fixedWidth aria-hidden='true' />
{this.props.label}
</button>)
}

View File

@ -6,7 +6,7 @@ const formatNumber = num => num > 40 ? '40+' : num;
const IconWithBadge = ({ id, count, className }) => (
<i className='icon-with-badge'>
<Icon icon={id} fixedWidth className={className} />
<Icon id={id} fixedWidth className={className} />
{count > 0 && <i className='icon-with-badge__badge'>{formatNumber(count)}</i>}
</i>
);

View File

@ -31,7 +31,7 @@ class ActionBar extends React.PureComponent {
if (account.get('acct') !== account.get('username')) {
extraInfo = (
<div className='account__disclaimer'>
<Icon icon='info-circle' fixedWidth /> <FormattedMessage
<Icon id='info-circle' fixedWidth /> <FormattedMessage
id='account.disclaimer_full'
defaultMessage="Information below may reflect the user's profile incompletely."
/>

View File

@ -158,7 +158,7 @@ class Header extends ImmutablePureComponent {
}
if (account.get('locked')) {
lockedIcon = <Icon icon='lock' title={intl.formatMessage(messages.account_locked)} />;
lockedIcon = <Icon id='lock' title={intl.formatMessage(messages.account_locked)} />;
}
if (account.get('id') !== me) {
@ -256,7 +256,7 @@ class Header extends ImmutablePureComponent {
<div className='account__header__tabs__buttons'>
{actionBtn}
<DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' />
<DropdownMenuContainer items={menu} id='ellipsis-v' size={24} direction='right' />
</div>
</div>

View File

@ -198,8 +198,8 @@ class Audio extends React.PureComponent {
<div className='video-player__controls active'>
<div className='video-player__buttons-bar'>
<div className='video-player__buttons left'>
<button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay}><Icon icon={paused ? 'play' : 'pause'} fixedWidth /></button>
<button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon icon={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
<button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
<button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
<div className='video-player__volume' onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
<div className='video-player__volume__current' style={{ width: `${volumeWidth}px` }} />

View File

@ -185,7 +185,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
if (on !== null && typeof on !== 'undefined') {
prefix = <Toggle checked={on} onChange={this.handleClick} />;
} else if (icon) {
prefix = <Icon className='icon' fullwidth icon={icon} />
prefix = <Icon className='icon' fixedWidth id={icon} />
}
return (

View File

@ -82,13 +82,13 @@ class Header extends ImmutablePureComponent {
aria-label={intl.formatMessage(messages.start)}
title={intl.formatMessage(messages.start)}
to='/getting-started'
><Icon icon='asterisk' /></Link>
><Icon id='asterisk' /></Link>
{renderForColumn('HOME', (
<Link
aria-label={intl.formatMessage(messages.home_timeline)}
title={intl.formatMessage(messages.home_timeline)}
to='/timelines/home'
><Icon icon='home' /></Link>
><Icon id='home' /></Link>
))}
{renderForColumn('NOTIFICATIONS', (
<Link
@ -97,7 +97,7 @@ class Header extends ImmutablePureComponent {
to='/notifications'
>
<span className='icon-badge-wrapper'>
<Icon icon='bell' />
<Icon id='bell' />
{ showNotificationsBadge && unreadNotifications > 0 && <div className='icon-badge' />}
</span>
</Link>
@ -107,27 +107,27 @@ class Header extends ImmutablePureComponent {
aria-label={intl.formatMessage(messages.community)}
title={intl.formatMessage(messages.community)}
to='/timelines/public/local'
><Icon icon='users' /></Link>
><Icon id='users' /></Link>
))}
{renderForColumn('PUBLIC', (
<Link
aria-label={intl.formatMessage(messages.public)}
title={intl.formatMessage(messages.public)}
to='/timelines/public'
><Icon icon='globe' /></Link>
><Icon id='globe' /></Link>
))}
<a
aria-label={intl.formatMessage(messages.settings)}
onClick={onSettingsClick}
href='#'
title={intl.formatMessage(messages.settings)}
><Icon icon='cogs' /></a>
><Icon id='cogs' /></a>
<a
aria-label={intl.formatMessage(messages.logout)}
onClick={this.handleLogoutClick}
href={ signOutLink }
title={intl.formatMessage(messages.logout)}
><Icon icon='sign-out' /></a>
><Icon id='sign-out' /></a>
</nav>
);
};

View File

@ -79,7 +79,7 @@ class Option extends React.PureComponent {
</label>
<div className='poll__cancel'>
<IconButton disabled={index <= 1} title={intl.formatMessage(messages.remove_option)} icon='times' onClick={this.handleOptionRemove} />
<IconButton disabled={index <= 1} title={intl.formatMessage(messages.remove_option)} id='times' onClick={this.handleOptionRemove} />
</div>
</li>
);
@ -132,7 +132,7 @@ class PollForm extends ImmutablePureComponent {
{options.size < pollLimits.max_options && (
<label className='poll__text editable'>
<span className={classNames('poll__input')} style={{ opacity: 0 }} />
<button className='button button-secondary' onClick={this.handleAddOption}><Icon icon='plus' /> <FormattedMessage {...messages.add_option} /></button>
<button className='button button-secondary' onClick={this.handleAddOption}><Icon id='plus' /> <FormattedMessage {...messages.add_option} /></button>
</label>
)}
</ul>

View File

@ -58,7 +58,7 @@ class Publisher extends ImmutablePureComponent {
text={
<span>
<Icon
icon={{
id={{
public: 'globe',
unlisted: 'unlock',
private: 'lock',
@ -80,7 +80,7 @@ class Publisher extends ImmutablePureComponent {
return (
<span>
<Icon
icon={{
id={{
direct: 'envelope',
private: 'lock',
public: 'globe',

View File

@ -153,8 +153,8 @@ class Search extends React.PureComponent {
role='button'
tabIndex='0'
>
<Icon icon='search' className={hasValue ? '' : 'active'} />
<Icon icon='times-circle' className={hasValue ? 'active' : ''} />
<Icon id='search' className={hasValue ? '' : 'active'} />
<Icon id='times-circle' className={hasValue ? 'active' : ''} />
</div>
<Overlay show={expanded && !hasValue} placement='bottom' target={this}>

View File

@ -82,7 +82,7 @@ class SearchResults extends ImmutablePureComponent {
count += results.get('accounts').size;
accounts = (
<section>
<h5><Icon icon='users' fixedWidth /><FormattedMessage id='search_results.accounts' defaultMessage='People' /></h5>
<h5><Icon id='users' fixedWidth /><FormattedMessage id='search_results.accounts' defaultMessage='People' /></h5>
{results.get('accounts').map(accountId => <AccountContainer id={accountId} key={accountId} />)}
@ -95,7 +95,7 @@ class SearchResults extends ImmutablePureComponent {
count += results.get('statuses').size;
statuses = (
<section>
<h5><Icon icon='quote-right' fixedWidth /><FormattedMessage id='search_results.statuses' defaultMessage='Toots' /></h5>
<h5><Icon id='quote-right' fixedWidth /><FormattedMessage id='search_results.statuses' defaultMessage='Toots' /></h5>
{results.get('statuses').map(statusId => <StatusContainer id={statusId} key={statusId}/>)}
@ -108,7 +108,7 @@ class SearchResults extends ImmutablePureComponent {
count += results.get('hashtags').size;
hashtags = (
<section>
<h5><Icon icon='hashtag' fixedWidth /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></h5>
<h5><Icon id='hashtag' fixedWidth /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></h5>
{results.get('hashtags').map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />)}
@ -121,7 +121,7 @@ class SearchResults extends ImmutablePureComponent {
return (
<div className='drawer--results'>
<header className='search-results__header'>
<Icon icon='search' fixedWidth />
<Icon id='search' fixedWidth />
<FormattedMessage id='search_results.total' defaultMessage='{count, number} {count, plural, one {result} other {results}}' values={{ count }} />
</header>

View File

@ -47,8 +47,8 @@ class TextareaIcons extends ImmutablePureComponent {
title={intl.formatMessage(message)}
>
<Icon
fullwidth
icon={icon}
fixedWidth
id={icon}
/>
</span>
) : null

View File

@ -44,7 +44,7 @@ export default class Upload extends ImmutablePureComponent {
{({ scale }) => (
<div style={{ transform: `scale(${scale})`, backgroundImage: `url(${media.get('preview_url')})`, backgroundPosition: `${x}% ${y}%` }}>
<div className={classNames('composer--upload_form--actions', { active: true })}>
<button className='icon-button' onClick={this.handleUndoClick}><Icon icon='times' /> <FormattedMessage id='upload_form.undo' defaultMessage='Delete' /></button>
<button className='icon-button' onClick={this.handleUndoClick}><Icon id='times' /> <FormattedMessage id='upload_form.undo' defaultMessage='Delete' /></button>
<button className='icon-button' onClick={this.handleFocalPointClick}><Icon id='pencil' /> <FormattedMessage id='upload_form.edit' defaultMessage='Edit' /></button>
</div>
</div>

View File

@ -22,7 +22,7 @@ export default class UploadProgress extends React.PureComponent {
return (
<div className='composer--upload_form--progress'>
<Icon icon={icon} />
<Icon id={icon} />
<div className='message'>
{message}

View File

@ -68,8 +68,8 @@ export default class ActionsModal extends ImmutablePureComponent {
return (
<Icon
className='icon'
fullwidth
icon={icon}
fixedWidth
id={icon}
/>
);
default:

View File

@ -46,7 +46,7 @@ class ListPanel extends ImmutablePureComponent {
<hr />
{lists.map(list => (
<NavLink key={list.get('id')} className='column-link column-link--transparent' strict to={`/timelines/list/${list.get('id')}`}><Icon className='column-link__icon' icon='list-ul' fixedWidth />{list.get('title')}</NavLink>
<NavLink key={list.get('id')} className='column-link column-link--transparent' strict to={`/timelines/list/${list.get('id')}`}><Icon className='column-link__icon' id='list-ul' fixedWidth />{list.get('title')}</NavLink>
))}
</div>
);

View File

@ -11,23 +11,23 @@ import TrendsContainer from 'flavours/glitch/features/getting_started/containers
const NavigationPanel = ({ onOpenSettings }) => (
<div className='navigation-panel'>
<NavLink className='column-link column-link--transparent' to='/timelines/home' data-preview-title-id='column.home' data-preview-icon='home' ><Icon className='column-link__icon' icon='home' fixedWidth /><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></NavLink>
<NavLink className='column-link column-link--transparent' to='/timelines/home' data-preview-title-id='column.home' data-preview-icon='home' ><Icon className='column-link__icon' id='home' fixedWidth /><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></NavLink>
<NavLink className='column-link column-link--transparent' to='/notifications' data-preview-title-id='column.notifications' data-preview-icon='bell' ><NotificationsCounterIcon className='column-link__icon' /><FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' /></NavLink>
<FollowRequestsNavLink />
<NavLink className='column-link column-link--transparent' to='/timelines/public/local' data-preview-title-id='column.community' data-preview-icon='users' ><Icon className='column-link__icon' icon='users' fixedWidth /><FormattedMessage id='tabs_bar.local_timeline' defaultMessage='Local' /></NavLink>
<NavLink className='column-link column-link--transparent' exact to='/timelines/public' data-preview-title-id='column.public' data-preview-icon='globe' ><Icon className='column-link__icon' icon='globe' fixedWidth /><FormattedMessage id='tabs_bar.federated_timeline' defaultMessage='Federated' /></NavLink>
<NavLink className='column-link column-link--transparent' to='/timelines/direct'><Icon className='column-link__icon' icon='envelope' fixedWidth /><FormattedMessage id='navigation_bar.direct' defaultMessage='Direct messages' /></NavLink>
<NavLink className='column-link column-link--transparent' to='/bookmarks'><Icon className='column-link__icon' icon='bookmark' fixedWidth /><FormattedMessage id='navigation_bar.bookmarks' defaultMessage='Bookmarks' /></NavLink>
{profile_directory && <NavLink className='column-link column-link--transparent' to='/directory'><Icon className='column-link__icon' icon='address-book-o' fixedWidth /><FormattedMessage id='getting_started.directory' defaultMessage='Profile directory' /></NavLink>}
<NavLink className='column-link column-link--transparent' to='/lists'><Icon className='column-link__icon' icon='list-ul' fixedWidth /><FormattedMessage id='navigation_bar.lists' defaultMessage='Lists' /></NavLink>
<NavLink className='column-link column-link--transparent' to='/timelines/public/local' data-preview-title-id='column.community' data-preview-icon='users' ><Icon className='column-link__icon' id='users' fixedWidth /><FormattedMessage id='tabs_bar.local_timeline' defaultMessage='Local' /></NavLink>
<NavLink className='column-link column-link--transparent' exact to='/timelines/public' data-preview-title-id='column.public' data-preview-icon='globe' ><Icon className='column-link__icon' id='globe' fixedWidth /><FormattedMessage id='tabs_bar.federated_timeline' defaultMessage='Federated' /></NavLink>
<NavLink className='column-link column-link--transparent' to='/timelines/direct'><Icon className='column-link__icon' id='envelope' fixedWidth /><FormattedMessage id='navigation_bar.direct' defaultMessage='Direct messages' /></NavLink>
<NavLink className='column-link column-link--transparent' to='/bookmarks'><Icon className='column-link__icon' id='bookmark' fixedWidth /><FormattedMessage id='navigation_bar.bookmarks' defaultMessage='Bookmarks' /></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='/lists'><Icon className='column-link__icon' id='list-ul' fixedWidth /><FormattedMessage id='navigation_bar.lists' defaultMessage='Lists' /></NavLink>
<ListPanel />
<hr />
{!!preferencesLink && <a className='column-link column-link--transparent' href={preferencesLink} target='_blank'><Icon className='column-link__icon' icon='cog' fixedWidth /><FormattedMessage id='navigation_bar.preferences' defaultMessage='Preferences' /></a>}
<a className='column-link column-link--transparent' href='#' onClick={onOpenSettings}><Icon className='column-link__icon' icon='cogs' fixedWidth /><FormattedMessage id='navigation_bar.app_settings' defaultMessage='App settings' /></a>
{!!relationshipsLink && <a className='column-link column-link--transparent' href={relationshipsLink} target='_blank'><Icon className='column-link__icon' icon='users' fixedWidth /><FormattedMessage id='navigation_bar.follows_and_followers' defaultMessage='Follows and followers' /></a>}
{!!preferencesLink && <a className='column-link column-link--transparent' href={preferencesLink} target='_blank'><Icon className='column-link__icon' id='cog' fixedWidth /><FormattedMessage id='navigation_bar.preferences' defaultMessage='Preferences' /></a>}
<a className='column-link column-link--transparent' href='#' onClick={onOpenSettings}><Icon className='column-link__icon' id='cogs' fixedWidth /><FormattedMessage id='navigation_bar.app_settings' defaultMessage='App settings' /></a>
{!!relationshipsLink && <a className='column-link column-link--transparent' href={relationshipsLink} target='_blank'><Icon className='column-link__icon' id='users' fixedWidth /><FormattedMessage id='navigation_bar.follows_and_followers' defaultMessage='Follows and followers' /></a>}
{showTrends && <div className='flex-spacer' />}
{showTrends && <TrendsContainer />}