forked from treehouse/mastodon
Use upstream's Icon component
Rework the codebase to avoid unnecessary differences with upstreamsignup-info-prompt
parent
f2b307af25
commit
f154d9d6e9
|
@ -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';
|
||||
|
||||
// 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;
|
||||
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} />
|
||||
);
|
||||
}
|
||||
|
||||
// Props.
|
||||
Icon.propTypes = {
|
||||
className: PropTypes.string,
|
||||
fullwidth: PropTypes.bool,
|
||||
icon: PropTypes.string,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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>)
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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."
|
||||
/>
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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` }} />
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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}>
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -47,8 +47,8 @@ class TextareaIcons extends ImmutablePureComponent {
|
|||
title={intl.formatMessage(message)}
|
||||
>
|
||||
<Icon
|
||||
fullwidth
|
||||
icon={icon}
|
||||
fixedWidth
|
||||
id={icon}
|
||||
/>
|
||||
</span>
|
||||
) : null
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -68,8 +68,8 @@ export default class ActionsModal extends ImmutablePureComponent {
|
|||
return (
|
||||
<Icon
|
||||
className='icon'
|
||||
fullwidth
|
||||
icon={icon}
|
||||
fixedWidth
|
||||
id={icon}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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 />}
|
||||
|
|
Loading…
Reference in New Issue