...
 
Commits (5)
......@@ -7,7 +7,7 @@ class HomeController < ApplicationController
before_action :set_data_for_meta
def index
@body_classes = 'app-body'
#
end
private
......
......@@ -3,7 +3,6 @@
import Rails from 'rails-ujs';
export function start() {
require('font-awesome/css/font-awesome.css');
require.context('../images/', true);
try {
......
import { Fragment } from 'react';
import { Link } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { defineMessages, injectIntl } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { me } from '../../initial_state';
import Avatar from '../avatar/avatar';
import DisplayName from '../display_name';
import IconButton from '../icon_button';
import './account.scss';
import { Fragment } from 'react'
import { NavLink } from 'react-router-dom'
import ImmutablePropTypes from 'react-immutable-proptypes'
import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import { me } from '../../initial_state'
import Avatar from '../avatar/avatar'
import DisplayName from '../display_name'
import IconButton from '../icon_button'
import Icon from '../icon'
const messages = defineMessages({
follow: { id: 'account.follow', defaultMessage: 'Follow' },
......@@ -18,7 +17,7 @@ const messages = defineMessages({
unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
mute_notifications: { id: 'account.mute_notifications', defaultMessage: 'Mute notifications from @{name}' },
unmute_notifications: { id: 'account.unmute_notifications', defaultMessage: 'Unmute notifications from @{name}' },
});
})
export default @injectIntl
class Account extends ImmutablePureComponent {
......@@ -34,37 +33,36 @@ class Account extends ImmutablePureComponent {
actionIcon: PropTypes.string,
actionTitle: PropTypes.string,
onActionClick: PropTypes.func,
displayOnly: PropTypes.bool,
};
}
handleFollow = () => {
this.props.onFollow(this.props.account);
this.props.onFollow(this.props.account)
}
handleBlock = () => {
this.props.onBlock(this.props.account);
this.props.onBlock(this.props.account)
}
handleMute = () => {
this.props.onMute(this.props.account);
this.props.onMute(this.props.account)
}
handleMuteNotifications = () => {
this.props.onMuteNotifications(this.props.account, true);
this.props.onMuteNotifications(this.props.account, true)
}
handleUnmuteNotifications = () => {
this.props.onMuteNotifications(this.props.account, false);
this.props.onMuteNotifications(this.props.account, false)
}
handleAction = () => {
this.props.onActionClick(this.props.account);
this.props.onActionClick(this.props.account)
}
render() {
const { account, intl, hidden, onActionClick, actionIcon, actionTitle, displayOnly } = this.props;
const { account, intl, hidden, onActionClick, actionIcon, actionTitle } = this.props
if (!account) return null;
if (!account) return null
if (hidden) {
return (
......@@ -72,29 +70,29 @@ class Account extends ImmutablePureComponent {
{account.get('display_name')}
{account.get('username')}
</Fragment>
);
)
}
let buttons;
let buttons
if (onActionClick && actionIcon) {
buttons = <IconButton icon={actionIcon} title={actionTitle} onClick={this.handleAction} />;
buttons = <IconButton icon={actionIcon} title={actionTitle} onClick={this.handleAction} />
} else if (account.get('id') !== me && account.get('relationship', null) !== null) {
const following = account.getIn(['relationship', 'following']);
const requested = account.getIn(['relationship', 'requested']);
const blocking = account.getIn(['relationship', 'blocking']);
const muting = account.getIn(['relationship', 'muting']);
const following = account.getIn(['relationship', 'following'])
const requested = account.getIn(['relationship', 'requested'])
const blocking = account.getIn(['relationship', 'blocking'])
const muting = account.getIn(['relationship', 'muting'])
if (requested) {
buttons = <IconButton disabled icon='hourglass' title={intl.formatMessage(messages.requested)} />;
buttons = <IconButton disabled icon='hourglass' title={intl.formatMessage(messages.requested)} />
} else if (blocking) {
buttons = <IconButton active icon='unlock' title={intl.formatMessage(messages.unblock, { name: account.get('username') })} onClick={this.handleBlock} />;
buttons = <IconButton active icon='unlock' title={intl.formatMessage(messages.unblock, { name: account.get('username') })} onClick={this.handleBlock} />
} else if (muting) {
let hidingNotificationsButton;
let hidingNotificationsButton
if (account.getIn(['relationship', 'muting_notifications'])) {
hidingNotificationsButton = <IconButton active icon='bell' title={intl.formatMessage(messages.unmute_notifications, { name: account.get('username') })} onClick={this.handleUnmuteNotifications} />;
hidingNotificationsButton = <IconButton active icon='bell' title={intl.formatMessage(messages.unmute_notifications, { name: account.get('username') })} onClick={this.handleUnmuteNotifications} />
} else {
hidingNotificationsButton = <IconButton active icon='bell-slash' title={intl.formatMessage(messages.mute_notifications, { name: account.get('username') })} onClick={this.handleMuteNotifications} />;
hidingNotificationsButton = <IconButton active icon='bell-slash' title={intl.formatMessage(messages.mute_notifications, { name: account.get('username') })} onClick={this.handleMuteNotifications} />
}
buttons = (
......@@ -102,41 +100,44 @@ class Account extends ImmutablePureComponent {
<IconButton active icon='volume-up' title={intl.formatMessage(messages.unmute, { name: account.get('username') })} onClick={this.handleMute} />
{hidingNotificationsButton}
</Fragment>
);
)
} else if (!account.get('moved') || following) {
buttons = <IconButton icon={following ? 'user-times' : 'user-plus'} title={intl.formatMessage(following ? messages.unfollow : messages.follow)} onClick={this.handleFollow} active={following} />;
buttons = <IconButton icon={following ? 'user-times' : 'user-plus'} title={intl.formatMessage(following ? messages.unfollow : messages.follow)} onClick={this.handleFollow} active={following} />
}
}
if (displayOnly) {
return (
<div className='account'>
<div className='account__wrapper'>
<div className='account__display-name'>
<div className='account__avatar-wrapper'>
<Avatar account={account} size={36} />
</div>
return (
<div className={[styles.default, styles.marginTop5PX, styles.marginBottom15PX].join(' ')}>
<div className={[styles.default, styles.flexRow].join(' ')}>
<NavLink
className={[styles.default, styles.noUnderline].join(' ')}
title={account.get('acct')}
to={`/${account.get('acct')}`}
>
<Avatar account={account} size={52} />
</NavLink>
<div className={[styles.default, styles.alignItemsStart, styles.paddingHorizontal10PX].join(' ')}>
<NavLink
className={[styles.default, styles.noUnderline].join(' ')}
title={account.get('acct')}
to={`/${account.get('acct')}`}
>
<DisplayName account={account} />
</div>
</NavLink>
<button className={[styles.default, styles.marginTop5PX, styles.colorBrand, styles.text, styles.cursorPointer, styles.fontSize14PX, styles.circle, styles.border1PX, styles.borderColorBrand, styles.paddingHorizontal20PX, styles.paddingVertical5PX].join(' ')}>
{intl.formatMessage(messages.follow)}
</button>
</div>
</div>
);
}
return (
<div className='account'>
<div className='account__wrapper'>
<Link key={account.get('id')} className='account__display-name' title={account.get('acct')} to={`/${account.get('acct')}`}>
<div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div>
<DisplayName account={account} />
</Link>
<div className='account__relationship'>
{buttons}
</div>
<button className={[styles.default, styles.marginLeftAuto, styles.paddingVertical2PX, styles.cursorPointer].join(' ')}>
<Icon width='14px' height='14px' />
</button>
</div>
</div>
);
)
}
}
import './gab_logo.scss'
const GabLogo = ({
className = 'gab-logo',
width = '50px',
height = '30px',
viewBox = '0 0 50 30'
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
......@@ -18,14 +14,14 @@ const GabLogo = ({
xmlSpace='preserve'
>
<g>
<path className='gab-logo__path' d='M13.8,7.6h-2.4v0.7V9l-0.4-0.3C10.2,7.8,9,7.2,7.7,7.2c-0.2,0-0.4,0-0.4,0c-0.1,0-0.3,0-0.5,0
<path className={styles.fillColorBrand} d='M13.8,7.6h-2.4v0.7V9l-0.4-0.3C10.2,7.8,9,7.2,7.7,7.2c-0.2,0-0.4,0-0.4,0c-0.1,0-0.3,0-0.5,0
c-5.6,0.3-8.7,7.2-5.4,12.1c2.3,3.4,7.1,4.1,9.7,1.5l0.3-0.3l0,0.7c0,1-0.1,1.5-0.4,2.2c-1,2.4-4.1,3-6.8,1.3
c-0.2-0.1-0.4-0.2-0.4-0.2c-0.1,0.1-1.9,3.5-1.9,3.6c0,0.1,0.5,0.4,0.8,0.6c2.2,1.4,5.6,1.7,8.3,0.8c2.7-0.9,4.5-3.2,5-6.4
c0.2-1.1,0.2-0.8,0.2-8.4l0-7.1H13.8z M9.7,17.6c-2.2,1.2-4.9-0.4-4.9-2.9C4.8,12.6,7,11,9,11.6C11.8,12.4,12.3,16.1,9.7,17.6z'/>
<path className='gab-logo__path' d='M45.6,7.7c-2.4-1-5-0.6-6.7,1L38.6,9V4.5V0h-2.4h-2.4v11v11h2.4h2.4v-0.7v-0.7l0.3,0.3
<path className={styles.fillColorBrand} d='M45.6,7.7c-2.4-1-5-0.6-6.7,1L38.6,9V4.5V0h-2.4h-2.4v11v11h2.4h2.4v-0.7v-0.7l0.3,0.3
c2.4,2.4,6.9,1.9,9.3-0.9C51.5,15.9,50.1,9.6,45.6,7.7z M43.7,17.5c-2.1,1.4-5.1-0.2-5.1-2.8c0-2.1,1.9-3.7,3.9-3.3
C45.4,12.1,46.2,15.8,43.7,17.5z'/>
<path className='gab-logo__path' d='M31.5,12.5c-0.7-3.7-3.1-5.5-7.1-5.3c-1.7,0.1-4,0.7-4.8,1.4l-0.1,0.1l0.7,1.7c0.4,0.9,0.7,1.7,0.7,1.7
<path className={styles.fillColorBrand} d='M31.5,12.5c-0.7-3.7-3.1-5.5-7.1-5.3c-1.7,0.1-4,0.7-4.8,1.4l-0.1,0.1l0.7,1.7c0.4,0.9,0.7,1.7,0.7,1.7
c0,0,0.1,0,0.2-0.1c2.7-1.4,5.4-0.9,5.6,1.1l0,0.2l-0.4-0.1c-3-0.8-6.3-0.1-7.7,1.6c-1.8,2.2-0.9,5.8,1.7,7.1
c2.1,1,4.6,0.6,6.1-0.8l0.2-0.2v0.6v0.6h2.4h2.4v-4C31.7,13.7,31.7,13.3,31.5,12.5z M26.9,16.4c-0.1,0.7-0.5,1.5-1,2
c-1.2,1.1-3,0.7-3.2-0.7c-0.2-1,0.6-1.7,2-1.8c0.1,0,0.2,0,0.2,0c0,0,0.2,0,0.4,0c0.5,0,1,0.1,1.4,0.2l0.3,0.1L26.9,16.4z'/>
......
const GroupIcon = ({
className = 'header-nav__item__icon',
width = '26px',
height = '26px',
viewBox = '0 0 48 48'
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={width}
height={height}
viewBox={viewBox}
xmlSpace='preserve'
>
<g>
<path className='header-nav__item__icon__path' d="M 41 25 L 37 25 C 37 26 37 27 37 28 L 37 42 C 37 43 37 43 37 44 L 43 44 C 46 44 48 42 48 40 L 48 32 C 48 28 44 25 41 25 Z M 41 25"/>
<path className='header-nav__item__icon__path' d="M 10 28 C 10 27 10 26 10 25 L 6 25 C 3 25 0 28 0 32 L 0 40 C 0 42 1 44 4 44 L 10 44 C 10 43 10 43 10 42 Z M 10 28"/>
<path className='header-nav__item__icon__path' d="M 28 22 L 19 22 C 15 22 12 25 12 28 L 12 42 C 12 43 13 44 14 44 L 33 44 C 34 44 35 43 35 42 L 35 28 C 35 25 32 22 28 22 Z M 28 22"/>
<circle className='header-nav__item__icon__path' cx="8" cy="15" r="6"/>
<circle className='header-nav__item__icon__path' cx="24" cy="11" r="9"/>
<circle className='header-nav__item__icon__path' cx="40" cy="15" r="6"/>
</g>
</svg>
)
export default GroupIcon
\ No newline at end of file
const HomeIcon = ({
className = 'header-nav__item__icon',
width = '26px',
height = '26px',
viewBox = '0 0 48 48'
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={width}
height={height}
viewBox={viewBox}
xmlSpace='preserve'
>
<g>
<path className='header-nav__item__icon__path' d='M 47.238281 21.695312 L 25.039062 0.417969 C 24.457031 -0.140625 23.542969 -0.140625 22.960938 0.417969 L 0.738281 21.71875 C 0.269531 22.1875 0 22.835938 0 23.5 C 0 24.878906 1.121094 26 2.5 26 L 6 26 L 6 45 C 6 46.65625 7.34375 48 9 48 L 17.5 48 C 18.328125 48 19 47.328125 19 46.5 L 19 33.5 C 19 33.226562 19.222656 33 19.5 33 L 28.5 33 C 28.773438 33 29 33.226562 29 33.5 L 29 46.5 C 29 47.328125 29.671875 48 30.5 48 L 39 48 C 40.65625 48 42 46.65625 42 45 L 42 26 L 45.5 26 C 46.878906 26 48 24.878906 48 23.5 C 48 22.835938 47.730469 22.1875 47.238281 21.695312 Z M 47.238281 21.695312' />
</g>
</svg>
)
export default HomeIcon
\ No newline at end of file
const NotificationsIcon = ({
className = 'header-nav__item__icon',
width = '26px',
height = '26px',
viewBox = '0 0 48 48'
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={width}
height={height}
viewBox={viewBox}
xmlSpace='preserve'
>
<g>
<path className='header-nav__item__icon__path header-nav__item__icon__path--fill' d='M 17 40 C 18 46 21 48 24 48 C 26 48 29 46 30 40 Z M 17 40' />
<path className='header-nav__item__icon__path header-nav__item__icon__path--fill' d='M 24 4 C 25 4 27 4 29 5 L 29 5 C 29 2 27 0 24 0 L 23 0 C 20 0 18 2 18 5 L 18 5 C 20 4 22 4 24 4 Z M 24 4' />
<path className='header-nav__item__icon__path' d='M 41 40 L 6 40 C 5 40 5 40 5 39 C 4 39 5 38 5 38 C 5 38 6 37 8 35 C 9 30 10 25 10 21 C 10 13 16 7 24 7 C 31 7 37 13 37 20 C 37 20 37 20 37 21 C 37 25 38 30 39 35 C 41 37 42 38 42 38 C 42 38 43 39 42 39 C 42 40 42 40 41 40 Z M 42 38 Z M 42 38' />
</g>
</svg>
)
export default NotificationsIcon
\ No newline at end of file
......@@ -4,8 +4,6 @@ import { makeGetAccount } from '../../selectors';
import Avatar from '../avatar';
import DisplayName from '../display_name';
import './autosuggest_account.scss';
const makeMapStateToProps = () => {
const getAccount = makeGetAccount();
......
import unicodeMapping from '../emoji/emoji_unicode_mapping_light';
import './autosuggest_emoji.scss';
const assetHost = process.env.CDN_HOST || '';
export default class AutosuggestEmoji extends PureComponent {
......
import { Fragment } from 'react'
import ImmutablePropTypes from 'react-immutable-proptypes';
import classNames from 'classnames';
import ImmutablePureComponent from 'react-immutable-pure-component';
......@@ -7,8 +8,6 @@ import { textAtCursorMatchesToken } from '../../utils/cursor_token_match';
import AutosuggestAccount from '../autosuggest_account';
import AutosuggestEmoji from '../autosuggest_emoji';
import './autosuggest_textbox.scss';
export default class AutosuggestTextbox extends ImmutablePureComponent {
static propTypes = {
......@@ -198,15 +197,13 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
}
if (textarea) {
return [
<div className='autosuggest-textarea__wrapper' key='autosuggest-textarea__wrapper'>
<div className='autosuggest-textarea'>
<label>
<span style={{ display: 'none' }}>{placeholder}</span>
return (
<Fragment>
<div className={[styles.default].join(' ')}>
<div className={[styles.default, styles.marginLeft5PX].join(' ')}>
<Textarea
inputRef={this.setTextbox}
className='autosuggest-textarea__textarea'
className={[styles.default, styles.backgroundWhite, styles.lineHeight125, styles.resizeNone, styles.paddingVertical15PX, styles.outlineNone, styles.fontSize16PX, styles.text, styles.displayBlock].join(' ')}
disabled={disabled}
placeholder={placeholder}
autoFocus={autoFocus}
......@@ -220,16 +217,16 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
style={style}
aria-autocomplete='list'
/>
</label>
</div>
{children}
</div>
{children}
</div>,
<div className='autosuggest-textarea__suggestions-wrapper' key='autosuggest-textarea__suggestions-wrapper'>
<div className={`autosuggest-textarea__suggestions ${suggestionsHidden || suggestions.isEmpty() ? '' : 'autosuggest-textarea__suggestions--visible'}`}>
{suggestions.map(this.renderSuggestion)}
<div className='autosuggest-textarea__suggestions-wrapper'>
<div className={`autosuggest-textarea__suggestions ${suggestionsHidden || suggestions.isEmpty() ? '' : 'autosuggest-textarea__suggestions--visible'}`}>
{suggestions.map(this.renderSuggestion)}
</div>
</div>
</div>,
];
</Fragment>
)
}
return (
......
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { Map as ImmutableMap } from 'immutable';
import classNames from 'classnames';
import { autoPlayGif } from '../../initial_state';
import './avatar.scss';
import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
import { Map as ImmutableMap } from 'immutable'
import classNames from 'classnames'
import { autoPlayGif } from '../../initial_state'
export default class Avatar extends ImmutablePureComponent {
......@@ -13,57 +11,53 @@ export default class Avatar extends ImmutablePureComponent {
size: PropTypes.number,
inline: PropTypes.bool,
animate: PropTypes.bool,
};
}
static defaultProps = {
account: ImmutableMap(),
animate: autoPlayGif,
inline: false,
};
}
state = {
hovering: false,
sameImg: this.props.account.get('avatar') === this.props.account.get('avatar_static'),
};
}
handleMouseEnter = () => {
if (this.props.animate || this.state.sameImg) return;
if (this.props.animate || this.state.sameImg) return
this.setState({ hovering: true });
this.setState({ hovering: true })
}
handleMouseLeave = () => {
if (this.props.animate || this.state.sameImg) return;
if (this.props.animate || this.state.sameImg) return
this.setState({ hovering: false });
this.setState({ hovering: false })
}
render () {
const { account, size, animate, inline } = this.props;
const { hovering } = this.state;
const { account, size, animate, inline } = this.props
const { hovering } = this.state
// : TODO : remove inline and change all avatars to be sized using css
const style = !size ? {} : {
width: `${size}px`,
height: `${size}px`,
};
const theSrc = account.get((hovering || animate) ? 'avatar' : 'avatar_static');
}
const className = classNames('account__avatar', {
'account__avatar--inline': inline,
});
const theSrc = account.get((hovering || animate) ? 'avatar' : 'avatar_static')
return (
<img
className={className}
className={[styles.default, styles.circle].join(' ')}
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
style={style}
src={theSrc}
alt={account.get('display_name')}
/>
);
)
}
}
......@@ -2,8 +2,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { autoPlayGif } from '../../initial_state';
import './avatar_overlay.scss';
export default class AvatarOverlay extends ImmutablePureComponent {
static propTypes = {
......
import './badge.scss';
export default class Badge extends PureComponent {
static propTypes = {
type: PropTypes.oneOf([
'pro',
'donor',
'investor',
]).isRequired,
};
render() {
const { type } = this.props;
if (!type) return null;
return (
<span className={`badge badge--${type}`}>
{type.toUpperCase()}
</span>
);
}
};
.badge {
text-transform: uppercase;
padding: 2px 6px;
border-radius: 2px;
margin: 0 5px 5px 0;
@include text-sizing(12px, 600, 1, center);
&--pro {
background-color: blueviolet;
color: #fff;
}
&--investor {
background-color: gold;
color: #000;
}
&--donor {
background-color: lightgreen;
color: #000;
}
}
\ No newline at end of file
export { default } from './badge';
\ No newline at end of file
......@@ -3,8 +3,6 @@ import Column from '../column';
import { ColumnHeader } from '../column_header';
import IconButton from '../icon_button';
import './bundle_column_error.scss';
const messages = defineMessages({
title: { id: 'bundle_column_error.title', defaultMessage: 'Network error' },
body: { id: 'bundle_column_error.body', defaultMessage: 'Something went wrong while loading this component.' },
......
import { defineMessages, injectIntl } from 'react-intl';
import IconButton from '../icon_button';
import './bundle_modal_error.scss';
const messages = defineMessages({
error: { id: 'bundle_modal_error.message', defaultMessage: 'Something went wrong while loading this component.' },
retry: { id: 'bundle_modal_error.retry', defaultMessage: 'Try again' },
......
import classNames from 'classnames';
import './button.scss';
import classNames from 'classnames/bind'
export default class Button extends PureComponent {
static propTypes = {
text: PropTypes.node,
href: PropTypes.string,
onClick: PropTypes.func,
disabled: PropTypes.bool,
block: PropTypes.bool,
secondary: PropTypes.bool,
className: PropTypes.string,
children: PropTypes.node,
};
className: PropTypes.string,
}
state = {
hovering: false,
}
handleOnMouseEnter = () => {
this.setState({
hovering: true,
})
}
handleOnMouseLeave = () => {
this.setState({
hovering: false,
})
}
handleClick = (e) => {
if (!this.props.disabled && this.props.onClick) {
this.props.onClick(e);
this.props.onClick(e)
}
}
setRef = (c) => {
this.node = c;
this.node = c
}
focus() {
this.node.focus();
this.node.focus()
}
render () {
const className = classNames('button', this.props.className, {
'button--secondary': this.props.secondary,
'button--block': this.props.block,
});
const { secondary, block, className, disabled, text, children, href } = this.props
const { hovering } = this.state
const cx = classNames.bind(styles)
const classes = cx(className, {
default: 1,
noUnderline: 1,
font: 1,
colorWhite: 1,
circle: 1,
cursorPointer: 1,
textAlignCenter: 1,
paddingVertical10PX: 1,
paddingHorizontal15PX: 1,
width100PC: block,
backgroundColorBrand: !hovering,
backgroundColorBrandDark: hovering,
})
if (href) {
return (
<a
className={classes}
href={href}
onMouseEnter={() => this.handleOnMouseEnter()}
onMouseLeave={() => this.handleOnMouseLeave()}
>
{text || children}
</a>
)
}
return (
<button
className={className}
disabled={this.props.disabled}
onClick={this.handleClick}
ref={this.setRef}
disabled={disabled}
onClick={this.handleClick}
className={classes}
onMouseEnter={() => this.handleOnMouseEnter()}
onMouseLeave={() => this.handleOnMouseLeave()}
>
{this.props.text || this.props.children}
{text || children}
</button>
);
}
......
......@@ -2,8 +2,6 @@ import { isMobile } from '../../utils/is_mobile';
import { ColumnHeader } from '../column_header';
import ColumnBackButton from '../column_back_button';
import './column.scss';
export default class Column extends PureComponent {
static propTypes = {
......
......@@ -3,7 +3,7 @@
position: relative;
box-sizing: border-box;
flex-direction: column;
width: 350px;
// width: 350px;
flex: 1 1 100%;
overflow: hidden;
......
......@@ -2,8 +2,6 @@ import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import Icon from '../icon';
import './column_back_button.scss';
export default class ColumnBackButton extends PureComponent {
static contextTypes = {
......
......@@ -3,8 +3,6 @@ import classNames from 'classnames';
import { injectIntl, defineMessages } from 'react-intl';
import Icon from '../icon';
import './column_header.scss';
const messages = defineMessages({
show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' },
hide: { id: 'column_header.hide_settings', defaultMessage: 'Hide settings' },
......
......@@ -7,8 +7,6 @@ import { createSelector } from 'reselect';
import { fetchLists } from '../../actions/lists';
import Icon from '../icon';
import './column_header.scss';
const messages = defineMessages({
show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' },
hide: { id: 'column_header.hide_settings', defaultMessage: 'Hide settings' },
......
......@@ -2,8 +2,6 @@ import { Link } from 'react-router-dom';
import classNames from 'classnames';
import Icon from '../icon';
import './column_header_setting_button.scss';
export default class ColumnHeaderSettingButton extends PureComponent {
static propTypes = {
......
import { defineMessages, injectIntl } from 'react-intl';
import Column from '../column';
import './column_indicator.scss';
const messages = defineMessages({
loading: { id: 'loading_indicator.label', defaultMessage: 'Loading...' },
missing: { id: 'missing_indicator.sublabel', defaultMessage: 'This resource could not be found.' },
......
import Button from '../button';
import './column_inline_form.scss';
export default class ColumnInlineForm extends PureComponent {
static propTypes = {
......
import { Link } from 'react-router-dom';
import Icon from '../../components/icon';
import './column_link.scss';
export default class ColumnLink extends PureComponent {
static propTypes = {
......
import './column_settings_heading.scss';
export default class ColumnSettingsHeading extends PureComponent {
static propTypes = {
heading: PropTypes.object.isRequired,
......@@ -7,7 +5,7 @@ export default class ColumnSettingsHeading extends PureComponent {
};
render() {
const { heading } = this.props;
const { heading, id } = this.props;
return (
<span id={id} className='column-settings-heading'>{heading}</span>
......
import './column_subheading.scss';
export default class ColumnSubheading extends PureComponent {
static propTypes = {
text: PropTypes.string.isRequired,
......
import './columns_area.scss';
export default class ColumnsArea extends PureComponent {
static propTypes = {
children: PropTypes.node,
layout: PropTypes.object,
};
render () {
const { children } = this.props;
const layout = this.props.layout || {LEFT:null,RIGHT:null};
console.log("layout:", layout);
return (
<div className='page'>
<div className='page__columns'>
<div className='columns-area__panels'>
<div className='columns-area__panels__pane columns-area__panels__pane--left'>
<div className='columns-area__panels__pane__inner'>
{layout.LEFT}
</div>
</div>
<div className='columns-area__panels__main'>
<div className='columns-area columns-area--mobile'>
{children}
</div>
</div>
<div className='columns-area__panels__pane columns-area__panels__pane--right'>
<div className='columns-area__panels__pane__inner'>
{layout.RIGHT}
</div>
</div>
</div>
</div>
</div>
)
}
}
.page {
display: flex;
flex-direction: column;
width: 100%;
&__top {
display: flex;
z-index: 105;
@include size(100%, auto);
@media (min-width:895px) {
top: -290px;
position: sticky;
}
}
&__columns {
display: flex;
flex-direction: column;
@include size(100%);
}
}
.columns-area {
flex: 1 1 auto;
position: relative;
@include flex(center, stretch, row);
&__panels {
@include size(100%);
@include flex(center);
&__pane {
height: 100%;
pointer-events: none;
padding-top: 15px;
@include flex(flex-end);
&--start {
justify-content: flex-start;
}
&__inner {
pointer-events: auto;
@include size(265px, 100%);
}
}
&__main {
display: flex;
flex-direction: column;
box-sizing: border-box;
width: 100%;
max-width: 600px;
padding: 0 20px;
@media screen and (max-width: 375px) {
padding: 0 10px;
}
@media screen and (min-width: 895px) {
margin: 0 20px;
padding: 0;
}
}
}
}
@media screen and (min-width: 631px) {
.columns-area {
padding: 0;
>div {
.column,
.drawer {
@include horizontal-padding(5px);
}
}
}
}
.columns-area--mobile {
flex-direction: column;
width: 100%;
@include margin-center;
.column,
.drawer {
padding: 0;
@include size(100%);
}
.search__input {
padding: 15px 30px 15px 15px;
@include text-sizing(16px, 400, 18px);
}
.search__icon .fa {
top: 15px;
}
@media screen and (min-width: 360px) {
padding: 15px 0;
}
@media screen and (min-width: 630px) {
.detailed-status {
padding: 15px;
.media-gallery,
.video-player {
margin-top: 15px;
}
}
.account__header__bar {
padding: 5px 10px;
}
.navigation-bar,
.compose-form {
padding: 15px;
}
.compose-form .compose-form__publish .compose-form__publish-button-wrapper {
padding-top: 15px;
}
.account {
padding: 15px 10px;
}
.notification {
&__message {
margin-left: 48px + 15px * 2;
padding-top: 15px;
}
&__favourite-icon-wrapper {
left: -32px;
}
.status {
padding-top: 8px;
}
.account {
padding-top: 8px;
}
.account__avatar-wrapper {
@include horizontal-margin(17px, 15px);
}
}
}
}
@media screen and (max-width: 895px) {
.columns-area__panels__pane--left {
display: none;
}
}
@media screen and (max-width: 1180px) {
.columns-area__panels__pane--right {
display: none;
}
}
.columns-area--mobile .column {
// @include gab-container-standards();
}
\ No newline at end of file
export { default } from './columns_area';
\ No newline at end of file
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import Icon from './icon';
export default class DisplayName extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
};
render () {
const { account } = this.props;
return (
<span className={[styles.default, styles.flexRow, styles.maxWidth100PC, styles.alignItemsCenter].join(' ')}>
<bdi className={[styles.text, styles.whiteSpaceNoWrap, styles.textOverflowEllipsis].join(' ')}>
<strong
className={[styles.text, styles.overflowWrapBreakWord, styles.whiteSpaceNoWrap, styles.fontSize15PX, styles.fontWeightBold, styles.colorBlack, styles.lineHeight125, styles.marginRight2PX].join(' ')}
dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }}
/>
</bdi>
{
account.get('is_verified') &&
<Icon id='verified' width='15px' height='15px' className={[styles.default]} title='Verified Account' />
/*<Icon id='verified' width='15px' height='15px' className={[styles.default]} title='PRO' />
<Icon id='verified' width='15px' height='15px' className={[styles.default]} title='Donor' />
<Icon id='verified' width='15px' height='15px' className={[styles.default]} title='Investor' />*/
}
<span className={[styles.text, styles.displayFlex, styles.flexNormal, styles.flexShrink1, styles.fontSize15PX, styles.overflowWrapBreakWord, styles.textOverflowEllipsis, styles.marginLeft5PX, styles.colorSubtle, styles.fontWeightNormal, styles.lineHeight125].join(' ')}>
@{account.get('acct')}
</span>
</span>
);
}
}
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import VerifiedIcon from '../verified_icon';
import './display_name.scss';
export default class DisplayName extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
};
render () {
const { account } = this.props;
return (
<span className='display-name'>
<bdi>
<strong className='display-name__html' dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }} />
</bdi>
{account.get('is_verified') && <VerifiedIcon />}
<span className='display-name__account'>@{account.get('acct')}</span>
</span>
);
}
}
.display-name {
display: block;
max-width: 100%;
@include text-overflow(break-word);
&__html {
font-weight: 600;
padding-right: 4px;
}
&__account {
font-size: 14px;
}
}
\ No newline at end of file
export { default } from './display_name';
\ No newline at end of file
import { defineMessages, injectIntl } from 'react-intl';
import IconButton from '../icon_button';
import './domain.scss';
const messages = defineMessages({
unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
});
......
......@@ -6,8 +6,6 @@ import spring from 'react-motion/lib/spring';
import Motion from '../../features/ui/util/optional_motion';
import IconButton from '../icon_button';
import './dropdown_menu.scss';
const listenerOptions = detectPassiveEvents.hasSupport ? { passive: true } : false;
let id = 0;
......
import { FormattedMessage } from 'react-intl';
import './error_boundary.scss';
export default class ErrorBoundary extends PureComponent {
static propTypes = {
......
import './extended_video_player.scss';
export default class ExtendedVideoPlayer extends PureComponent {
static propTypes = {
......
import ComposeIcon from './assets/compose_icon';
import './floating_action_button.scss';
export default class FloatingActionButton extends Component {
static propTypes = {
onClick: PropTypes.func.isRequired,
......
......@@ -3,8 +3,6 @@ import { FormattedMessage, injectIntl } from 'react-intl';
import NotificationCounter from '../notification_counter';
import { me } from '../../initial_state';
import './footer_bar.scss';
const links = [
<NavLink key='pr1' className='footer-bar__link' to='/home' data-preview-title-id='column.home'>
<i className='tabs-bar__link__icon home'/>
......@@ -28,7 +26,7 @@ const links = [
export default
@injectIntl
@withRouter
class FooterBar extends React.PureComponent {
class FooterBar extends PureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
......
import { NavLink } from 'react-router-dom'
import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
import { injectIntl, defineMessages } from 'react-intl'
import classNames from 'classnames/bind'
import Button from './button'
import Icon from './icon'
import { closeSidebar } from '../actions/sidebar'
import { me } from '../initial_state'
import { makeGetAccount } from '../selectors'
// import ProgressPanel from './progress_panel'
import GabLogo from './assets/gab_logo'
import {
GroupIcon,
HomeIcon,
NotificationsIcon,
} from './assets/tabs_bar_icon'
const messages = defineMessages({
followers: { id: 'account.followers', defaultMessage: 'Followers' },
follows: { id: 'account.follows', defaultMessage: 'Follows' },
profile: { id: 'account.profile', defaultMessage: 'Profile' },
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' },
mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' },
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
lists: { id: 'column.lists', defaultMessage: 'Lists', },
apps: { id: 'tabs_bar.apps', defaultMessage: 'Apps' },
more: { id: 'sidebar.more', defaultMessage: 'More' },
pro: { id: 'promo.gab_pro', defaultMessage: 'Upgrade to GabPRO' },
trends: { id: 'promo.trends', defaultMessage: 'Trends' },
search: { id: 'tabs_bar.search', defaultMessage: 'Search' },
shop: { id: 'tabs_bar.shop', defaultMessage: 'Store - Buy Merch' },
donate: { id: 'tabs_bar.donate', defaultMessage: 'Make a Donation' },
})
const mapStateToProps = state => {
const getAccount = makeGetAccount()
return {
account: getAccount(state, me),
sidebarOpen: state.get('sidebar').sidebarOpen,
}
}
const mapDispatchToProps = (dispatch) => ({
onClose() {
dispatch(closeSidebar())
},
})
export default @connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class Header extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
account: ImmutablePropTypes.map,
sidebarOpen: PropTypes.bool,
onClose: PropTypes.func.isRequired,
}
state = {
moreOpen: false,
hoveringItemIndex: null,
}