This commit is contained in:
mgabdev 2020-05-08 22:17:19 -04:00
parent a390662e4f
commit b620cb1372
38 changed files with 734 additions and 277 deletions

View File

@ -157,6 +157,8 @@ export function expandNotifications({ maxId } = {}, done = noOp) {
return; return;
} }
console.log("activeFilter:", activeFilter)
const params = { const params = {
max_id: maxId, max_id: maxId,
exclude_types: activeFilter === 'all' ? null : excludeTypesFromFilter(activeFilter), exclude_types: activeFilter === 'all' ? null : excludeTypesFromFilter(activeFilter),

View File

@ -236,7 +236,6 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
outlineNone: 1, outlineNone: 1,
lineHeight125: 1, lineHeight125: 1,
colorPrimary: 1, colorPrimary: 1,
height100PC: small,
width100PC: !small, width100PC: !small,
pt15: !small, pt15: !small,
px15: !small, px15: !small,
@ -253,7 +252,6 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
default: 1, default: 1,
maxWidth100PC: 1, maxWidth100PC: 1,
flexGrow1: small, flexGrow1: small,
height100PC: small,
justifyContentCenter: small, justifyContentCenter: small,
}) })
@ -261,7 +259,7 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
return ( return (
<Fragment> <Fragment>
<div className={textareaContainerClasses}> <div className={textareaContainerClasses}>
<Textarea {/*<Textarea
inputRef={this.setTextbox} inputRef={this.setTextbox}
className={textareaClasses} className={textareaClasses}
disabled={disabled} disabled={disabled}
@ -275,9 +273,9 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
// onBlur={this.onBlur} // onBlur={this.onBlur}
// onPaste={this.onPaste} // onPaste={this.onPaste}
aria-autocomplete='list' aria-autocomplete='list'
/> />*/}
{/*<Composer <Composer
inputRef={this.setTextbox} inputRef={this.setTextbox}
disabled={disabled} disabled={disabled}
placeholder={placeholder} placeholder={placeholder}
@ -290,7 +288,7 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
onBlur={this.onBlur} onBlur={this.onBlur}
onPaste={this.onPaste} onPaste={this.onPaste}
small={small} small={small}
/>*/} />
{children} {children}
</div> </div>

View File

@ -0,0 +1,48 @@
import Button from './button'
export default class BackButton extends PureComponent {
static contextTypes = {
router: PropTypes.object,
}
static propTypes = {
classNames: PropTypes.string,
iconClassName: PropTypes.string,
iconSize: PropTypes.string,
}
historyBack = () => {
if (window.history && window.history.length === 1) {
this.context.router.history.push('/home')
} else {
this.context.router.history.goBack()
}
}
handleBackClick = () => {
this.historyBack()
}
render() {
const {
classNames,
iconClassName,
iconSize,
} = this.props
return (
<Button
noClasses
color='primary'
backgroundColor='none'
className={classNames || [_s.alignItemsCenter, _s.bgTransparent, _s.mr5, _s.cursorPointer, _s.outlineNone, _s.default, _s.justifyContentCenter].join(' ')}
icon='arrow-left'
iconSize={iconSize || '24px'}
iconClassName={iconClassName || [_s.mr5, _s.fillPrimary].join(' ')}
onClick={this.handleBackClick}
/>
)
}
}

View File

@ -4,7 +4,7 @@ import Button from './button'
import Comment from './comment' import Comment from './comment'
import ScrollableList from './scrollable_list' import ScrollableList from './scrollable_list'
import Text from './text' import Text from './text'
import { PureComponent } from 'react'; import Dummy from './dummy'
export default class CommentList extends ImmutablePureComponent { export default class CommentList extends ImmutablePureComponent {
@ -27,7 +27,7 @@ export default class CommentList extends ImmutablePureComponent {
const upperLimit = commentsLimited ? 6 : size const upperLimit = commentsLimited ? 6 : size
const max = Math.min(commentsLimited ? 2 : upperLimit, size) const max = Math.min(commentsLimited ? 2 : upperLimit, size)
const Wrapper = !commentsLimited ? ScrollableList : DummyContainer const Wrapper = !commentsLimited ? ScrollableList : Dummy
return ( return (
<div> <div>
@ -70,10 +70,4 @@ export default class CommentList extends ImmutablePureComponent {
) )
} }
}
class DummyContainer extends PureComponent {
render() {
return <div>{this.props.children}</div>
}
} }

View File

@ -201,8 +201,9 @@ class Composer extends PureComponent {
pt15: !small, pt15: !small,
px15: !small, px15: !small,
px10: small, px10: small,
pt10: small, pt5: small,
pb10: 1, pb5: small,
pb10: !small,
}) })
return ( return (

View File

@ -0,0 +1,5 @@
export default class Dummy extends PureComponent {
render() {
return <div>{this.props.children}</div>
}
}

View File

@ -71,7 +71,7 @@ export default class ErrorBoundary extends PureComponent {
<h1 className={[_s.default, _s.mr15].join(' ')}> <h1 className={[_s.default, _s.mr15].join(' ')}>
<Button href='/' isText aria-label='Gab' className={[_s.default, _s.justifyContentCenter, _s.noSelect, _s.noUnderline, _s.height53PX, _s.cursorPointer, _s.px10, _s.mr15].join(' ')}> <Button href='/' isText aria-label='Gab' className={[_s.default, _s.justifyContentCenter, _s.noSelect, _s.noUnderline, _s.height53PX, _s.cursorPointer, _s.px10, _s.mr15].join(' ')}>
<Icon id='gab-logo' className={_s.fillWhite} /> <Icon id='logo' className={_s.fillWhite} />
</Button> </Button>
</h1> </h1>

View File

@ -4,7 +4,11 @@ import { defineMessages, injectIntl } from 'react-intl'
import { openPopover, closePopover } from '../actions/popover' import { openPopover, closePopover } from '../actions/popover'
import { openModal } from '../actions/modal' import { openModal } from '../actions/modal'
import { joinGroup, leaveGroup } from '../actions/groups' import { joinGroup, leaveGroup } from '../actions/groups'
import { PLACEHOLDER_MISSING_HEADER_SRC } from '../constants' import {
PLACEHOLDER_MISSING_HEADER_SRC,
BREAKPOINT_EXTRA_SMALL,
} from '../constants'
import Responsive from '../features/ui/util/responsive_component'
import Button from './button' import Button from './button'
import Block from './block' import Block from './block'
import Image from './image' import Image from './image'
@ -46,6 +50,7 @@ class GroupHeader extends ImmutablePureComponent {
static propTypes = { static propTypes = {
group: ImmutablePropTypes.map, group: ImmutablePropTypes.map,
children: PropTypes.any,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
onToggleMembership: PropTypes.func.isRequired, onToggleMembership: PropTypes.func.isRequired,
onOpenGroupOptions: PropTypes.func.isRequired, onOpenGroupOptions: PropTypes.func.isRequired,
@ -67,6 +72,7 @@ class GroupHeader extends ImmutablePureComponent {
render() { render() {
const { const {
children,
group, group,
intl, intl,
relationships, relationships,
@ -90,8 +96,8 @@ class GroupHeader extends ImmutablePureComponent {
actionButtonTitle = intl.formatMessage(!isMember ? messages.join : messages.leave) actionButtonTitle = intl.formatMessage(!isMember ? messages.join : messages.leave)
if (isMember) { if (isMember) {
actionButtonOptions = { actionButtonOptions = {
backgroundColor: 'tertiary', backgroundColor: 'danger',
color: 'primary', color: 'white',
} }
} }
} }
@ -99,25 +105,24 @@ class GroupHeader extends ImmutablePureComponent {
// : todo : // : todo :
// {group.get('archived') && <Icon id='lock' title={intl.formatMessage(messages.group_archived)} />} // {group.get('archived') && <Icon id='lock' title={intl.formatMessage(messages.group_archived)} />}
// const adminMenu = [
// { text: intl.formatMessage(messages.edit), to: `/groups/${group.get('id')}/edit` },
// { text: intl.formatMessage(messages.removed_accounts), to: `/groups/${group.get('id')}/removed-accounts` },
// ]
return ( return (
<div className={[_s.default, _s.z1, _s.width100PC, _s.mb15].join(' ')}> <div className={[_s.default, _s.z1, _s.width100PC, _s.mb15].join(' ')}>
<Block> <Responsive max={BREAKPOINT_EXTRA_SMALL}>
<div className={[_s.default, _s.width100PC].join(' ')}> <div className={[_s.default, _s.boxShadowBlock, _s.bgPrimary].join(' ')}>
<div className={[_s.default, _s.width100PC].join(' ')}>
{
coverSrc && !coverSrcMissing &&
<Image className={_s.height350PX} src={coverSrc} alt={title} />
}
<div className={[_s.default, _s.height53PX, _s.width100PC].join(' ')}> {
<div className={[_s.default, _s.flexRow, _s.height100PC, _s.px10].join(' ')}> coverSrc && !coverSrcMissing &&
<TabBar tabs={tabs} /> <Image className={_s.height200PX} src={coverSrc} alt={title} />
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter, _s.height100PC, _s.mlAuto].join(' ')}> }
<div className={[_s.default, _s.width100PC].join(' ')}>
<div className={[_s.default, _s.width100PC, _s.px15, _s.mt10, _s.py10].join(' ')}>
{children}
</div>
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter, _s.borderTop1PX, _s.borderColorSecondary, _s.mt5, _s.pt15, _s.height100PC, _s.px15].join(' ')}>
{ {
!!actionButtonTitle && !!actionButtonTitle &&
<Button <Button
@ -126,12 +131,12 @@ class GroupHeader extends ImmutablePureComponent {
onClick={this.handleOnToggleMembership} onClick={this.handleOnToggleMembership}
{...actionButtonOptions} {...actionButtonOptions}
> >
<Text color='inherit' size='small'> <Text color='inherit' size='small' className={_s.px10}>
{actionButtonTitle} {actionButtonTitle}
</Text> </Text>
</Button> </Button>
} }
<Button <Button
radiusSmall radiusSmall
color='primary' color='primary'
@ -142,10 +147,60 @@ class GroupHeader extends ImmutablePureComponent {
buttonRef={this.setInfoBtn} buttonRef={this.setInfoBtn}
/> />
</div> </div>
<div className={[_s.default, _s.flexRow, _s.height100PC, _s.mt15, _s.pt10, _s.px10].join(' ')}>
<TabBar tabs={tabs} />
</div>
</div> </div>
</div> </div>
</div> </div>
</Block> </Responsive>
{ /** desktop */}
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
<Block>
<div className={[_s.default, _s.width100PC].join(' ')}>
{
coverSrc && !coverSrcMissing &&
<Image className={_s.height350PX} src={coverSrc} alt={title} />
}
<div className={[_s.default, _s.height53PX, _s.width100PC].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.height100PC, _s.px10].join(' ')}>
<TabBar tabs={tabs} />
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter, _s.height100PC, _s.mlAuto].join(' ')}>
{
!!actionButtonTitle &&
<Button
radiusSmall
className={_s.mr5}
onClick={this.handleOnToggleMembership}
{...actionButtonOptions}
>
<Text color='inherit' size='small' className={_s.px10}>
{actionButtonTitle}
</Text>
</Button>
}
<Button
radiusSmall
color='primary'
backgroundColor='tertiary'
className={_s.mr5}
icon='ellipsis'
onClick={this.handleOnOpenGroupOptions}
buttonRef={this.setInfoBtn}
/>
</div>
</div>
</div>
</div>
</Block>
</Responsive>
</div> </div>
) )
} }

View File

@ -96,7 +96,7 @@ const ICONS = {
'error': ErrorIcon, 'error': ErrorIcon,
'explore': ExploreIcon, 'explore': ExploreIcon,
'fullscreen': FullscreenIcon, 'fullscreen': FullscreenIcon,
'gab-logo': GabLogoIcon, 'logo': GabLogoIcon,
'gif': GifIcon, 'gif': GifIcon,
'globe': GlobeIcon, 'globe': GlobeIcon,
'group': GroupIcon, 'group': GroupIcon,

View File

@ -0,0 +1,80 @@
import Button from './button'
import Search from './search'
import Text from './text'
import ResponsiveClassesComponent from '../features/ui/util/responsive_classes_component';
export default class LoggedOutNavigationBar extends PureComponent {
static propTypes = {
title: PropTypes.string,
showBackBtn: PropTypes.bool,
}
render() {
return (
<ResponsiveClassesComponent
classNames={[_s.default, _s.z4, _s.height53PX, _s.width100PC].join(' ')}
classNamesXS={[_s.default, _s.z4, _s.height98PX, _s.width100PC].join(' ')}
>
<ResponsiveClassesComponent
classNames={[_s.default, _s.height53PX, _s.flexRow, _s.flexWrap, _s.bgNavigation, _s.alignItemsCenter, _s.z3, _s.top0, _s.right0, _s.left0, _s.posFixed].join(' ')}
classNamesXS={[_s.default, _s.height98PX, _s.flexRow, _s.flexWrap, _s.bgNavigation, _s.alignItemsCenter, _s.z3, _s.top0, _s.right0, _s.left0, _s.posFixed].join(' ')}
>
<ResponsiveClassesComponent
classNames={[_s.default, _s.flexRow, _s.width330PX].join(' ')}
classNamesXS={[_s.default, _s.flexRow, _s.width100PC].join(' ')}
>
<Button
href='/'
color='none'
backgroundColor='none'
icon='logo'
iconClassName={[_s.mr5, _s.fillNavigation].join(' ')}
/>
<div className={[_s.default, _s.flexGrow1, _s.mr10].join(' ')}>
<Search />
</div>
</ResponsiveClassesComponent>
<ResponsiveClassesComponent
classNames={[_s.default, _s.flexRow, _s.py5, _s.px10, _s.width330PX, _s.mlAuto].join(' ')}
classNamesXS={[_s.default, _s.flexRow, _s.py5, _s.px10, _s.width100PC].join(' ')}
>
<Button
isNarrow
isOutline
color='white'
backgroundColor='none'
href='/auth/log_in'
className={[_s.borderColorWhite, _s.mr5, _s.flexGrow1, _s.alignItemsCenter, _s.justifyContentCenter, _s.py5].join(' ')}
>
<Text color='inherit' weight='medium' align='center'>
Log in
</Text>
</Button>
<Button
isNarrow
color='brand'
backgroundColor='white'
href='/auth/sign_up'
className={[_s.justifyContentCenter, _s.alignItemsCenter, _s.ml5, _s.flexGrow1, _s.py5].join(' ')}
>
<Text color='inherit' weight='bold' align='center'>
Sign up
</Text>
</Button>
</ResponsiveClassesComponent>
</ResponsiveClassesComponent>
</ResponsiveClassesComponent>
)
}
}

View File

@ -80,7 +80,7 @@ class NavigationBar extends ImmutablePureComponent {
backgroundColor='none' backgroundColor='none'
className={[_s.default, _s.justifyContentCenter, _s.noSelect, _s.noUnderline, _s.height53PX, _s.cursorPointer, _s.px10, _s.mr15].join(' ')} className={[_s.default, _s.justifyContentCenter, _s.noSelect, _s.noUnderline, _s.height53PX, _s.cursorPointer, _s.px10, _s.mr15].join(' ')}
> >
<Icon id='gab-logo' className={_s.fillNavigationBrand} /> <Icon id='logo' className={_s.fillNavigationBrand} />
</Button> </Button>
</h1> </h1>

View File

@ -8,6 +8,7 @@ import { shortNumberFormat } from '../../utils/numbers'
import PanelLayout from './panel_layout' import PanelLayout from './panel_layout'
import Button from '../button' import Button from '../button'
import Divider from '../divider' import Divider from '../divider'
import Dummy from '../dummy'
import Icon from '../icon' import Icon from '../icon'
import Text from '../text' import Text from '../text'
import RelativeTimestamp from '../relative_timestamp' import RelativeTimestamp from '../relative_timestamp'
@ -19,7 +20,6 @@ const messages = defineMessages({
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
onOpenGroupMembersModal(groupId) { onOpenGroupMembersModal(groupId) {
console.log("onOpenGroupMembersModal:", groupId)
dispatch(openModal(MODAL_GROUP_MEMBERS, { groupId })) dispatch(openModal(MODAL_GROUP_MEMBERS, { groupId }))
}, },
}) })
@ -33,6 +33,7 @@ class GroupInfoPanel extends ImmutablePureComponent {
group: ImmutablePropTypes.map.isRequired, group: ImmutablePropTypes.map.isRequired,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
onOpenGroupMembersModal: PropTypes.func.isRequired, onOpenGroupMembersModal: PropTypes.func.isRequired,
noPanel: PropTypes.bool,
} }
handleOnOpenGroupMembersModal = () => { handleOnOpenGroupMembersModal = () => {
@ -40,10 +41,12 @@ class GroupInfoPanel extends ImmutablePureComponent {
} }
render() { render() {
const { intl, group } = this.props const { intl, group, noPanel } = this.props
const Wrapper = noPanel ? Dummy : PanelLayout
return ( return (
<PanelLayout title={intl.formatMessage(messages.title)}> <Wrapper title={intl.formatMessage(messages.title)}>
{ {
!!group && !!group &&
<Fragment> <Fragment>
@ -102,7 +105,7 @@ class GroupInfoPanel extends ImmutablePureComponent {
</Text> </Text>
</Fragment> </Fragment>
} }
</PanelLayout> </Wrapper>
) )
} }
} }

View File

@ -38,20 +38,8 @@ class ListsPanel extends ImmutablePureComponent {
'lists', 'lists',
] ]
static getDerivedStateFromProps(nextProps, prevState) { componentDidMount(prevProps, prevState, snapshot) {
if (!nextProps.isHidden && nextProps.isIntersecting && !prevState.fetched) { this.props.onFetchLists()
return {
fetched: true,
}
}
return null
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (!prevState.fetched && this.state.fetched) {
this.props.onFetchLists()
}
} }
render() { render() {

View File

@ -81,4 +81,4 @@ class MediaGalleryPanel extends ImmutablePureComponent {
</PanelLayout> </PanelLayout>
) )
} }
} }

View File

@ -9,6 +9,7 @@ import PanelLayout from './panel_layout'
import Divider from '../divider' import Divider from '../divider'
import Icon from '../icon' import Icon from '../icon'
import Text from '../text' import Text from '../text'
import Dummy from '../dummy'
const messages = defineMessages({ const messages = defineMessages({
title: { id: 'about', defaultMessage: 'About' }, title: { id: 'about', defaultMessage: 'About' },
@ -39,6 +40,7 @@ class ProfileInfoPanel extends ImmutablePureComponent {
static propTypes = { static propTypes = {
identityProofs: ImmutablePropTypes.list, identityProofs: ImmutablePropTypes.list,
account: ImmutablePropTypes.map, account: ImmutablePropTypes.map,
noPanel: PropTypes.bool,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
} }
@ -47,7 +49,12 @@ class ProfileInfoPanel extends ImmutablePureComponent {
} }
render() { render() {
const { intl, account, identityProofs } = this.props const {
intl,
account,
identityProofs,
noPanel
} = this.props
if (!account) return null if (!account) return null
@ -60,8 +67,10 @@ class ProfileInfoPanel extends ImmutablePureComponent {
const isInvestor = account.get('is_investor') const isInvestor = account.get('is_investor')
const hasBadges = isPro || isDonor || isInvestor const hasBadges = isPro || isDonor || isInvestor
const Wrapper = noPanel ? Dummy : PanelLayout
return ( return (
<PanelLayout title={intl.formatMessage(messages.title)}> <Wrapper title={intl.formatMessage(messages.title)}>
<div className={[_s.default].join(' ')}> <div className={[_s.default].join(' ')}>
{ {
hasNote && hasNote &&
@ -166,7 +175,7 @@ class ProfileInfoPanel extends ImmutablePureComponent {
)} )}
</div> </div>
</PanelLayout> </Wrapper>
) )
} }
} }

View File

@ -5,6 +5,8 @@ import { me, favouritesCount } from '../../initial_state'
import { shortNumberFormat } from '../../utils/numbers' import { shortNumberFormat } from '../../utils/numbers'
import PanelLayout from './panel_layout' import PanelLayout from './panel_layout'
import UserStat from '../user_stat' import UserStat from '../user_stat'
import Dummy from '../dummy'
import ResponsiveClassesComponent from '../../features/ui/util/responsive_classes_component'
const messages = defineMessages({ const messages = defineMessages({
gabs: { id: 'account.gabs', defaultMessage: 'Gabs' }, gabs: { id: 'account.gabs', defaultMessage: 'Gabs' },
@ -20,32 +22,45 @@ class ProfileStatsPanel extends ImmutablePureComponent {
static propTypes = { static propTypes = {
account: ImmutablePropTypes.map, account: ImmutablePropTypes.map,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
noPanel: PropTypes.bool,
} }
render() { render() {
const { intl, account } = this.props const {
intl,
account,
noPanel
} = this.props
if (!account) return null if (!account) return null
const Wrapper = noPanel ? Dummy : PanelLayout
return ( return (
<PanelLayout> <Wrapper>
{ {
!!account && !!account &&
<div className={[_s.default, _s.flexRow].join(' ')}> <ResponsiveClassesComponent
classNames={[_s.default, _s.flexRow].join(' ')}
classNamesXS={[_s.default, _s.flexRow, _s.mt15, _s.pt10].join(' ')}
>
<UserStat <UserStat
title={intl.formatMessage(messages.gabs)} title={intl.formatMessage(messages.gabs)}
value={shortNumberFormat(account.get('statuses_count'))} value={shortNumberFormat(account.get('statuses_count'))}
to={`/${account.get('acct')}`} to={`/${account.get('acct')}`}
isCentered={noPanel}
/> />
<UserStat <UserStat
title={intl.formatMessage(messages.follows)} title={intl.formatMessage(messages.follows)}
value={shortNumberFormat(account.get('following_count'))} value={shortNumberFormat(account.get('following_count'))}
to={`/${account.get('acct')}/following`} to={`/${account.get('acct')}/following`}
isCentered={noPanel}
/> />
<UserStat <UserStat
title={intl.formatMessage(messages.followers)} title={intl.formatMessage(messages.followers)}
value={shortNumberFormat(account.get('followers_count'))} value={shortNumberFormat(account.get('followers_count'))}
to={`/${account.get('acct')}/followers`} to={`/${account.get('acct')}/followers`}
isCentered={noPanel}
/> />
{ {
account.get('id') === me && account.get('id') === me &&
@ -53,11 +68,12 @@ class ProfileStatsPanel extends ImmutablePureComponent {
title={intl.formatMessage(messages.likes)} title={intl.formatMessage(messages.likes)}
value={shortNumberFormat(favouritesCount)} value={shortNumberFormat(favouritesCount)}
to={`/${account.get('acct')}/likes`} to={`/${account.get('acct')}/likes`}
isCentered={noPanel}
/> />
} }
</div> </ResponsiveClassesComponent>
} }
</PanelLayout> </Wrapper>
) )
} }
} }

View File

@ -7,6 +7,7 @@ import {
POPOVER_PROFILE_OPTIONS, POPOVER_PROFILE_OPTIONS,
PLACEHOLDER_MISSING_HEADER_SRC, PLACEHOLDER_MISSING_HEADER_SRC,
MODAL_EDIT_PROFILE, MODAL_EDIT_PROFILE,
BREAKPOINT_EXTRA_SMALL,
} from '../constants' } from '../constants'
import { openModal } from '../actions/modal' import { openModal } from '../actions/modal'
import { openPopover } from '../actions/popover' import { openPopover } from '../actions/popover'
@ -19,6 +20,7 @@ import Image from './image'
import MovedNote from './moved_note' import MovedNote from './moved_note'
import TabBar from './tab_bar' import TabBar from './tab_bar'
import Text from './text' import Text from './text'
import Responsive from '../features/ui/util/responsive_component';
const messages = defineMessages({ const messages = defineMessages({
followers: { id: 'account.followers', defaultMessage: 'Followers' }, followers: { id: 'account.followers', defaultMessage: 'Followers' },
@ -51,6 +53,7 @@ class ProfileHeader extends ImmutablePureComponent {
static propTypes = { static propTypes = {
account: ImmutablePropTypes.map, account: ImmutablePropTypes.map,
children: PropTypes.any,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
onEditProfile: PropTypes.func.isRequired, onEditProfile: PropTypes.func.isRequired,
openProfileOptionsPopover: PropTypes.func.isRequired, openProfileOptionsPopover: PropTypes.func.isRequired,
@ -87,7 +90,11 @@ class ProfileHeader extends ImmutablePureComponent {
} }
render() { render() {
const { account, intl } = this.props const {
account,
children,
intl,
} = this.props
const { stickied } = this.state const { stickied } = this.state
const tabs = !account ? null : [ const tabs = !account ? null : [
@ -108,7 +115,7 @@ class ProfileHeader extends ImmutablePureComponent {
const headerSrc = !!account ? account.get('header') : '' const headerSrc = !!account ? account.get('header') : ''
const headerMissing = headerSrc.indexOf(PLACEHOLDER_MISSING_HEADER_SRC) > -1 || !headerSrc const headerMissing = headerSrc.indexOf(PLACEHOLDER_MISSING_HEADER_SRC) > -1 || !headerSrc
const avatarSize = headerMissing ? 75 : 150 const avatarSize = headerMissing ? 75 : 150
const top = headerMissing ? -30 : -380 const top = headerMissing ? -46 : -380
const avatarContainerClasses = CX({ const avatarContainerClasses = CX({
default: 1, default: 1,
@ -130,55 +137,51 @@ class ProfileHeader extends ImmutablePureComponent {
displayNone: stickied, displayNone: stickied,
}) })
const mobileAvatarContainerClasses = CX({
default: 1,
circle: 1,
boxShadowProfileAvatar: 1,
mtNeg50PX: !headerMissing,
})
return ( return (
<div className={[_s.default, _s.z1, _s.width100PC].join(' ')}> <div className={[_s.default, _s.z1, _s.width100PC].join(' ')}>
<Sticky top={top} enabled onStateChange={this.onStickyStateChange}> <Responsive max={BREAKPOINT_EXTRA_SMALL}>
<div className={[_s.default, _s.z1, _s.width100PC, _s.alignItemsCenter, _s.boxShadowBlock, _s.bgPrimary].join(' ')}> <div className={[_s.default, _s.z1, _s.width100PC, _s.alignItemsCenter, _s.boxShadowBlock, _s.bgPrimary].join(' ')}>
<div className={[_s.default, _s.width1015PX].join(' ')}> <div className={[_s.default, _s.width100PC].join(' ')}>
{ {
!headerMissing && !headerMissing &&
<div className={[_s.default, _s.height350PX, _s.width100PC, _s.bottomRightRadiusSmall, _s.bottomLeftRadiusSmall, _s.overflowHidden].join(' ')}> <div className={[_s.default, _s.height200PX, _s.px10, _s.width100PC, _s.mt10, _s.overflowHidden].join(' ')}>
<Image <Image
alt={intl.formatMessage(messages.headerPhoto)} alt={intl.formatMessage(messages.headerPhoto)}
className={_s.height350PX} className={[_s.topRightRadiusSmall, _s.topLeftRadiusSmall, _s.height100PC].join(' ')}
src={headerSrc} src={headerSrc}
/> />
</div> </div>
} }
{ {
headerMissing && headerMissing &&
<div className={[_s.default, _s.py10, _s.width100PC].join(' ')} /> <div className={[_s.default, _s.height20PX, _s.width100PC].join(' ')} />
} }
<div className={[_s.default, _s.width100PC].join(' ')}> <div className={[_s.default, _s.width100PC].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.pr15, _s.pl25, _s.mb5].join(' ')}> <div className={[_s.default, _s.alignItemsCenter, _s.px15, _s.mb5].join(' ')}>
<div className={avatarContainerClasses}> <div className={mobileAvatarContainerClasses}>
<Avatar size={avatarSize} account={account} noHover /> <Avatar size={100} account={account} noHover />
</div> </div>
<div className={[_s.default, _s.flexRow, _s.px15, _s.flexNormal, _s.py10].join(' ')}> <div className={[_s.default, _s.flexRow, _s.flexNormal, _s.py10].join(' ')}>
<DisplayName account={account} isMultiline noRelationship isLarge noHover /> <DisplayName account={account} isMultiline noRelationship isLarge noHover />
</div> </div>
</div> </div>
<div className={[_s.default, _s.flexRow, _s.bgPrimary, _s.height53PX].join(' ')}> <div className={[_s.default, _s.bgPrimary, _s.alignItemsCenter].join(' ')}>
<div className={tabBarContainerClasses}>
<TabBar tabs={tabs} isLarge />
</div>
<div className={stickyBarContainerClasses}>
<Avatar size={36} account={account} noHover />
<div className={[_s.default, _s.ml10].join(' ')}>
<DisplayName account={account} noUsername noRelationship noHover isLarge />
</div>
</div>
{ {
account && account.get('id') === me && account && account.get('id') === me &&
<div className={[_s.default, _s.flexRow, _s.mlAuto, _s.py5].join(' ')}> <div className={[_s.default,_s.py5].join(' ')}>
<Button <Button
isOutline isOutline
backgroundColor='none' backgroundColor='none'
@ -195,18 +198,7 @@ class ProfileHeader extends ImmutablePureComponent {
{ {
account && account.get('id') !== me && account && account.get('id') !== me &&
<div className={[_s.default, _s.flexRow, _s.mlAuto, _s.py5].join(' ')}> <div className={[_s.default, _s.flexRow, _s.py5].join(' ')}>
<Button
isOutline
icon='ellipsis'
iconSize='18px'
iconClassName={_s.inheritFill}
color='brand'
backgroundColor='none'
className={[_s.justifyContentCenter, _s.alignItemsCenter, _s.mr10, _s.px10].join(' ')}
onClick={this.handleOpenMore}
buttonRef={this.setOpenMoreNodeRef}
/>
<form action='https://chat.gab.com/private-message' method='POST'> <form action='https://chat.gab.com/private-message' method='POST'>
<Button <Button
@ -221,16 +213,148 @@ class ProfileHeader extends ImmutablePureComponent {
/> />
<input type='hidden' value={account.get('username')} name='username' /> <input type='hidden' value={account.get('username')} name='username' />
</form> </form>
<div className={[_s.default, _s.flexRow, _s.pb3, _s.mr10].join(' ')}>
<AccountActionButton account={account} />
</div>
<AccountActionButton account={account} /> <div>
<Button
isOutline
icon='ellipsis'
iconSize='18px'
iconClassName={_s.inheritFill}
color='brand'
backgroundColor='none'
className={[_s.justifyContentCenter, _s.alignItemsCenter, _s.px10].join(' ')}
onClick={this.handleOpenMore}
buttonRef={this.setOpenMoreNodeRef}
/>
</div>
</div> </div>
} }
<div className={[_s.default, _s.width100PC, _s.px15, _s.mt15, _s.mb10, _s.pt15, _s.pb10].join(' ')}>
{children}
</div>
<div className={[_s.default, _s.mt10].join(' ')}>
<TabBar tabs={tabs} isLarge />
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</Sticky>
</Responsive>
{ /** desktop */ }
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
<Sticky top={top} enabled onStateChange={this.onStickyStateChange}>
<div className={[_s.default, _s.z1, _s.width100PC, _s.alignItemsCenter, _s.boxShadowBlock, _s.bgPrimary].join(' ')}>
<div className={[_s.default, _s.width1015PX].join(' ')}>
{
!headerMissing &&
<div className={[_s.default, _s.height350PX, _s.width100PC, _s.bottomRightRadiusSmall, _s.bottomLeftRadiusSmall, _s.overflowHidden].join(' ')}>
<Image
alt={intl.formatMessage(messages.headerPhoto)}
className={_s.height100PC}
src={headerSrc}
/>
</div>
}
{
headerMissing &&
<div className={[_s.default, _s.height20PX, _s.width100PC].join(' ')} />
}
<div className={[_s.default, _s.width100PC].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.pr15, _s.pl25, _s.mb5].join(' ')}>
<div className={avatarContainerClasses}>
<Avatar size={avatarSize} account={account} noHover />
</div>
<div className={[_s.default, _s.flexRow, _s.px15, _s.flexNormal, _s.py10].join(' ')}>
<DisplayName account={account} isMultiline noRelationship isLarge noHover />
</div>
</div>
<div className={[_s.default, _s.flexRow, _s.bgPrimary, _s.height53PX].join(' ')}>
<div className={tabBarContainerClasses}>
<TabBar tabs={tabs} isLarge />
</div>
<div className={stickyBarContainerClasses}>
<Avatar size={36} account={account} noHover />
<div className={[_s.default, _s.ml10].join(' ')}>
<DisplayName account={account} noUsername noRelationship noHover isLarge />
</div>
</div>
{
account && account.get('id') === me &&
<div className={[_s.default, _s.flexRow, _s.mlAuto, _s.py5].join(' ')}>
<Button
isOutline
backgroundColor='none'
color='brand'
className={[_s.justifyContentCenter, _s.alignItemsCenter].join(' ')}
onClick={this.handleOnEditProfile}
>
<Text color='inherit' weight='bold' size='medium' className={_s.px15}>
{intl.formatMessage(messages.editProfile)}
</Text>
</Button>
</div>
}
{
account && account.get('id') !== me &&
<div className={[_s.default, _s.flexRow, _s.mlAuto, _s.py5].join(' ')}>
<div>
<Button
isOutline
icon='ellipsis'
iconSize='18px'
iconClassName={_s.inheritFill}
color='brand'
backgroundColor='none'
className={[_s.justifyContentCenter, _s.alignItemsCenter, _s.mr10, _s.px10].join(' ')}
onClick={this.handleOpenMore}
buttonRef={this.setOpenMoreNodeRef}
/>
</div>
<form action='https://chat.gab.com/private-message' method='POST'>
<Button
isOutline
type='submit'
icon='chat'
iconSize='18px'
iconClassName={_s.inheritFill}
color='brand'
backgroundColor='none'
className={[_s.justifyContentCenter, _s.alignItemsCenter, _s.mr10, _s.px10].join(' ')}
/>
<input type='hidden' value={account.get('username')} name='username' />
</form>
<div className={[_s.default, _s.flexRow, _s.pb3].join(' ')}>
<AccountActionButton account={account} />
</div>
</div>
}
</div>
</div>
</div>
</div>
</Sticky>
</Responsive>
</div> </div>
) )
} }

View File

@ -0,0 +1,41 @@
import BackButton from './back_button'
import Heading from './heading'
export default class ProfileNavigationBar extends PureComponent {
static propTypes = {
title: PropTypes.string,
showBackBtn: PropTypes.bool,
}
render() {
const { title } = this.props
return (
<div className={[_s.default, _s.z4, _s.height53PX, _s.width100PC].join(' ')}>
<div className={[_s.default, _s.height53PX, _s.bgNavigation, _s.alignItemsCenter, _s.z3, _s.top0, _s.right0, _s.left0, _s.posFixed].join(' ')} >
<div className={[_s.default, _s.flexRow, _s.width100PC].join(' ')}>
<BackButton
classNames={[_s.height53PX, _s.bgTransparent, _s.ml10, _s.mr10, _s.cursorPointer, _s.outlineNone, _s.default, _s.justifyContentCenter].join(' ')}
iconSize='32px'
iconClassName={[_s.mr5, _s.fillNavigation].join(' ')}
/>
<div className={[_s.default, _s.height53PX, _s.justifyContentCenter, _s.mrAuto].join(' ')}>
<Heading size='h1'>
<span className={[_s.textOverflowEllipsis, _s.colorNavigation].join(' ')}>
{title}
</span>
</Heading>
</div>
</div>
</div>
</div>
)
}
}

View File

@ -1,5 +1,6 @@
import { withRouter } from 'react-router-dom' import { withRouter } from 'react-router-dom'
import queryString from 'query-string' import queryString from 'query-string'
import { me } from '../initial_state'
import { CX } from '../constants' import { CX } from '../constants'
import { import {
changeSearch, changeSearch,
@ -128,7 +129,7 @@ class Search extends PureComponent {
}) })
const prependIconColor = highlighted ? 'brand' : 'white' const prependIconColor = highlighted ? 'brand' : 'white'
const placeholder = !me ? 'Search Gab' : 'Search for people, groups or news'
const id = 'nav-search' const id = 'nav-search'
return ( return (
@ -140,7 +141,7 @@ class Search extends PureComponent {
id={id} id={id}
className={inputClasses} className={inputClasses}
type='text' type='text'
placeholder='Search for people, groups or news' placeholder={placeholder}
ref={this.setTextbox} ref={this.setTextbox}
value={value} value={value}
onKeyUp={this.handleKeyUp} onKeyUp={this.handleKeyUp}

View File

@ -12,6 +12,7 @@ import Responsive from '../features/ui/util/responsive_component'
import SidebarSectionTitle from './sidebar_section_title' import SidebarSectionTitle from './sidebar_section_title'
import SidebarSectionItem from './sidebar_section_item' import SidebarSectionItem from './sidebar_section_item'
import Heading from './heading' import Heading from './heading'
import BackButton from './back_button'
import Pills from './pills' import Pills from './pills'
const messages = defineMessages({ const messages = defineMessages({
@ -227,16 +228,7 @@ class Sidebar extends ImmutablePureComponent {
<div className={[_s.default, _s.flexRow, _s.px5, _s.pt10].join(' ')}> <div className={[_s.default, _s.flexRow, _s.px5, _s.pt10].join(' ')}>
{ {
showBackBtn && showBackBtn &&
<Button <BackButton />
noClasses
color='primary'
backgroundColor='none'
className={[_s.alignItemsCenter, _s.bgTransparent, _s.mr5, _s.cursorPointer, _s.outlineNone, _s.default, _s.justifyContentCenter].join(' ')}
icon='arrow-left'
iconSize='24px'
iconClassName={[_s.mr5, _s.fillPrimary].join(' ')}
onClick={this.handleBackClick}
/>
} }
<Heading size='h1'> <Heading size='h1'>
{title} {title}

View File

@ -535,9 +535,12 @@ class Status extends ImmutablePureComponent {
{ {
!isChild && !compactMode && !!me && !isChild && !compactMode && !!me &&
<div className={[_s.default, _s.borderTop1PX, _s.borderColorSecondary, _s.pt10, _s.px15, _s.mb10].join(' ')}> <ResponsiveClassesComponent
classNames={[_s.default, _s.borderTop1PX, _s.borderColorSecondary, _s.pt10, _s.px15, _s.mb10].join(' ')}
classNamesXS={[_s.default, _s.borderTop1PX, _s.borderColorSecondary, _s.pt10, _s.px10, _s.mb10].join(' ')}
>
<ComposeFormContainer replyToId={status.get('id')} shouldCondense /> <ComposeFormContainer replyToId={status.get('id')} shouldCondense />
</div> </ResponsiveClassesComponent>
} }
{ {

View File

@ -1,3 +1,4 @@
import ResponsiveClassesComponent from '../features/ui/util/responsive_classes_component';
import TabBarItem from './tab_bar_item' import TabBarItem from './tab_bar_item'
/** /**
@ -16,7 +17,10 @@ export default class TabBar extends PureComponent {
const { tabs, isLarge } = this.props const { tabs, isLarge } = this.props
return ( return (
<div className={[_s.default, _s.height53PX, _s.px5, _s.flexRow].join(' ')}> <ResponsiveClassesComponent
classNames={[_s.default, _s.height53PX, _s.px5, _s.flexRow].join(' ')}
classNamesXS={[_s.default, _s.height40PX, _s.px5, _s.flexRow].join(' ')}
>
{ {
// Check for if tabs exist or not. // Check for if tabs exist or not.
// We don't `return null` because it maintains 53px height if no tabs. // We don't `return null` because it maintains 53px height if no tabs.
@ -32,7 +36,7 @@ export default class TabBar extends PureComponent {
/> />
)) ))
} }
</div> </ResponsiveClassesComponent>
) )
} }

View File

@ -56,7 +56,7 @@ class TabBarItem extends PureComponent {
const containerClasses = CX({ const containerClasses = CX({
default: 1, default: 1,
height53PX: 1, height100PC: 1,
noUnderline: 1, noUnderline: 1,
text: 1, text: 1,
displayFlex: 1, displayFlex: 1,

View File

@ -1,4 +1,5 @@
import { NavLink } from 'react-router-dom' import { NavLink } from 'react-router-dom'
import { CX } from '../constants'
import Text from './text' import Text from './text'
/** /**
@ -17,6 +18,7 @@ export default class UserStat extends PureComponent {
PropTypes.number, PropTypes.number,
PropTypes.object, PropTypes.object,
]).isRequired, ]).isRequired,
isCentered: PropTypes.bool.isRequired,
} }
state = { state = {
@ -32,21 +34,36 @@ export default class UserStat extends PureComponent {
} }
render() { render() {
const { to, title, value } = this.props const {
to,
title,
value,
isCentered,
} = this.props
const { hovering } = this.state const { hovering } = this.state
const align = isCentered ? 'center' : 'left'
const containerClasses = CX({
default: 1,
cursorPointer: 1,
noUnderline: 1,
flexNormal: isCentered,
flexGrow1: !isCentered,
pr15: !isCentered,
})
return ( return (
<NavLink <NavLink
to={to} to={to}
title={`${value} ${title}`} title={`${value} ${title}`}
className={[_s.default, _s.flexGrow1, _s.cursorPointer, _s.noUnderline, _s.pr15].join(' ')} className={containerClasses}
onMouseEnter={this.handleOnMouseEnter} onMouseEnter={this.handleOnMouseEnter}
onMouseLeave={this.handleOnMouseLeave} onMouseLeave={this.handleOnMouseLeave}
> >
<Text size='large' weight='bold' color='brand'> <Text size='large' weight='bold' color='brand' align={align}>
{value} {value}
</Text> </Text>
<Text size='small' weight='medium' color='secondary' hasUnderline={hovering}> <Text size='small' weight='medium' color='secondary' hasUnderline={hovering} align={align}>
{title} {title}
</Text> </Text>
</NavLink> </NavLink>

View File

@ -208,6 +208,18 @@ const mapDispatchToProps = (dispatch) => ({
} }
}, },
onOpenLikes(status) {
if (!me) return dispatch(openModal('UNAUTHORIZED'))
dispatch(openModal('STATUS_LIKES', { status }))
},
onOpenReposts(status) {
if (!me) return dispatch(openModal('UNAUTHORIZED'))
dispatch(openModal('STATUS_REPOSTS', { status }))
},
onFetchComments(statusId) { onFetchComments(statusId) {
dispatch(fetchComments(statusId)) dispatch(fetchComments(statusId))
}, },
@ -216,14 +228,6 @@ const mapDispatchToProps = (dispatch) => ({
dispatch(fetchContext(statusId)) dispatch(fetchContext(statusId))
}, },
onOpenLikes(status) {
dispatch(openModal('STATUS_LIKES', { status }))
},
onOpenReposts(status) {
dispatch(openModal('STATUS_REPOSTS', { status }))
},
}); });
export default connect(makeMapStateToProps, mapDispatchToProps)(Status); export default connect(makeMapStateToProps, mapDispatchToProps)(Status);

View File

@ -27,6 +27,14 @@ export default class ComposeExtraButton extends PureComponent {
} = this.props } = this.props
const btnClasses = cx({ const btnClasses = cx({
default: 1,
circle: 1,
noUnderline: 1,
font: 1,
cursorPointer: 1,
textAlignCenter: 1,
outlineNone: 1,
bgTransparent: 1,
bgSubtle_onHover: !active, bgSubtle_onHover: !active,
bgBrandLight: active, bgBrandLight: active,
py10: !small, py10: !small,
@ -45,6 +53,7 @@ export default class ComposeExtraButton extends PureComponent {
const button = ( const button = (
<Button <Button
noClasses
className={btnClasses} className={btnClasses}
title={title} title={title}
isDisabled={disabled} isDisabled={disabled}

View File

@ -12,6 +12,7 @@ import {
} from '../../../constants' } from '../../../constants'
import AutosuggestTextbox from '../../../components/autosuggest_textbox' import AutosuggestTextbox from '../../../components/autosuggest_textbox'
import Responsive from '../../ui/util/responsive_component' import Responsive from '../../ui/util/responsive_component'
import ResponsiveClassesComponent from '../../ui/util/responsive_classes_component'
import Avatar from '../../../components/avatar' import Avatar from '../../../components/avatar'
import Button from '../../../components/button' import Button from '../../../components/button'
import CharacterCounter from '../../../components/character_counter' import CharacterCounter from '../../../components/character_counter'
@ -254,6 +255,8 @@ class ComposeForm extends ImmutablePureComponent {
flexWrap: 1, flexWrap: 1,
overflowHidden: 1, overflowHidden: 1,
flex1: 1, flex1: 1,
heightMin28PX: 1,
py2: shouldCondense,
alignItemsEnd: shouldCondense, alignItemsEnd: shouldCondense,
flexRow: shouldCondense, flexRow: shouldCondense,
radiusSmall: shouldCondense, radiusSmall: shouldCondense,
@ -267,8 +270,9 @@ class ComposeForm extends ImmutablePureComponent {
alignItemsCenter: !shouldCondense, alignItemsCenter: !shouldCondense,
alignItemsStart: shouldCondense, alignItemsStart: shouldCondense,
mt10: !shouldCondense, mt10: !shouldCondense,
px15: !shouldCondense, px10: !shouldCondense,
mlAuto: shouldCondense, mlAuto: shouldCondense,
flexWrap: !shouldCondense,
}) })
const commentPublishBtnClasses = CX({ const commentPublishBtnClasses = CX({
@ -285,7 +289,7 @@ class ComposeForm extends ImmutablePureComponent {
<div className={[_s.default, _s.width100PC].join(' ')}> <div className={[_s.default, _s.width100PC].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.width100PC].join(' ')}> <div className={[_s.default, _s.flexRow, _s.width100PC].join(' ')}>
<div className={[_s.default, _s.mr10, _s.mt5].join(' ')}> <div className={[_s.default, _s.mr10].join(' ')}>
<Avatar account={account} size={28} noHover /> <Avatar account={account} size={28} noHover />
</div> </div>

View File

@ -1,16 +1,10 @@
import ImmutablePropTypes from 'react-immutable-proptypes' import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component' import ImmutablePureComponent from 'react-immutable-pure-component'
import { FormattedMessage } from 'react-intl'
import { withRouter } from 'react-router-dom' import { withRouter } from 'react-router-dom'
import { fetchSuggestions, dismissSuggestion } from '../actions/suggestions' import { fetchSuggestions, dismissSuggestion } from '../actions/suggestions'
import { me } from '../initial_state'
import HashtagItem from '../components/hashtag_item' import HashtagItem from '../components/hashtag_item'
import Icon from '../components/icon'
import { WhoToFollowPanel } from '../components/panel'
// import TrendsPanel from '../ui/components/trends_panel'
import GroupListItem from '../components/group_list_item' import GroupListItem from '../components/group_list_item'
import Block from '../components/block'
import Heading from '../components/heading'
import Button from '../components/button'
import Text from '../components/text' import Text from '../components/text'
import Account from '../components/account' import Account from '../components/account'
import PanelLayout from '../components/panel/panel_layout' import PanelLayout from '../components/panel/panel_layout'
@ -91,7 +85,7 @@ class Search extends ImmutablePureComponent {
) )
} }
if (results.get('groups') && results.get('groups').size > 0 && (isTop || showGroups)) { if (results.get('groups') && results.get('groups').size > 0 && me && (isTop || showGroups)) {
const size = isTop ? Math.min(results.get('groups').size, theLimit) : results.get('groups').size; const size = isTop ? Math.min(results.get('groups').size, theLimit) : results.get('groups').size;
const isMax = size === results.get('groups').size const isMax = size === results.get('groups').size
@ -123,7 +117,7 @@ class Search extends ImmutablePureComponent {
) )
} }
if (results.get('hashtags') && results.get('hashtags').size > 0 && (isTop || showHashtags)) { if (results.get('hashtags') && results.get('hashtags').size > 0 && me && (isTop || showHashtags)) {
const size = isTop ? Math.min(results.get('hashtags').size, theLimit) : results.get('hashtags').size; const size = isTop ? Math.min(results.get('hashtags').size, theLimit) : results.get('hashtags').size;
const isMax = size === results.get('hashtags').size const isMax = size === results.get('hashtags').size

View File

@ -170,7 +170,7 @@ class SwitchingArea extends PureComponent {
<WrappedRoute path='/notifications' exact page={NotificationsPage} component={Notifications} content={children} /> <WrappedRoute path='/notifications' exact page={NotificationsPage} component={Notifications} content={children} />
<WrappedRoute path='/search' exact publicRoute page={SearchPage} component={Search} content={children} /> <WrappedRoute path='/search' exact publicRoute page={SearchPage} component={Search} content={children} />
<WrappedRoute path='/search/people' exact page={SearchPage} component={Search} content={children} /> <WrappedRoute path='/search/people' exact publicRoute page={SearchPage} component={Search} content={children} />
<WrappedRoute path='/search/hashtags' exact page={SearchPage} component={Search} content={children} /> <WrappedRoute path='/search/hashtags' exact page={SearchPage} component={Search} content={children} />
<WrappedRoute path='/search/groups' exact page={SearchPage} component={Search} content={children} /> <WrappedRoute path='/search/groups' exact page={SearchPage} component={Search} content={children} />
@ -350,12 +350,8 @@ class UI extends PureComponent {
} }
} }
// componentWillMount() {
// }
componentDidMount() { componentDidMount() {
// if (!me) return if (!me) return
window.addEventListener('beforeunload', this.handleBeforeUnload, false) window.addEventListener('beforeunload', this.handleBeforeUnload, false)
@ -373,13 +369,12 @@ class UI extends PureComponent {
window.setTimeout(() => Notification.requestPermission(), 120 * 1000) window.setTimeout(() => Notification.requestPermission(), 120 * 1000)
} }
if (me) { this.props.dispatch(expandHomeTimeline())
this.props.dispatch(expandHomeTimeline()) this.props.dispatch(initializeNotifications())
this.props.dispatch(expandNotifications())
this.props.dispatch(initializeNotifications())
setTimeout(() => this.props.dispatch(fetchFilters()), 500) setTimeout(() => {
} this.props.dispatch(fetchFilters())
}, 500)
// this.hotkeys.__mousetrap__.stopCallback = (e, element) => { // this.hotkeys.__mousetrap__.stopCallback = (e, element) => {
// return ['TEXTAREA', 'SELECT', 'INPUT'].includes(element.tagName) // return ['TEXTAREA', 'SELECT', 'INPUT'].includes(element.tagName)
// } // }
@ -394,11 +389,11 @@ class UI extends PureComponent {
document.removeEventListener('dragend', this.handleDragEnd) document.removeEventListener('dragend', this.handleDragEnd)
} }
setRef = c => { setRef = (c) => {
this.node = c this.node = c
} }
handleHotkeyNew = e => { handleHotkeyNew = (e) => {
e.preventDefault() e.preventDefault()
const element = this.node.querySelector('.compose-form__autosuggest-wrapper textarea') const element = this.node.querySelector('.compose-form__autosuggest-wrapper textarea')
@ -408,7 +403,7 @@ class UI extends PureComponent {
} }
} }
handleHotkeySearch = e => { handleHotkeySearch = (e) => {
e.preventDefault() e.preventDefault()
const element = this.node.querySelector('.search__input') const element = this.node.querySelector('.search__input')
@ -418,7 +413,7 @@ class UI extends PureComponent {
} }
} }
handleHotkeyForceNew = e => { handleHotkeyForceNew = (e) => {
this.handleHotkeyNew(e) this.handleHotkeyNew(e)
this.props.dispatch(resetCompose()) this.props.dispatch(resetCompose())
} }
@ -431,7 +426,7 @@ class UI extends PureComponent {
} }
} }
setHotkeysRef = c => { setHotkeysRef = (c) => {
this.hotkeys = c this.hotkeys = c
} }

View File

@ -1,8 +1,14 @@
import ImmutablePropTypes from 'react-immutable-proptypes' import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component' import ImmutablePureComponent from 'react-immutable-pure-component'
import Sticky from 'react-stickynode' import Sticky from 'react-stickynode'
import { BREAKPOINT_EXTRA_SMALL } from '../constants'
import Layout from './layout' import Layout from './layout'
import GroupInfoPanel from '../components/panel/group_info_panel'
import WhoToFollowPanel from '../components/panel/who_to_follow_panel'
import GroupSidebarPanel from '../components/panel/groups_panel'
import LinkFooter from '../components/link_footer'
import GroupHeader from '../components/group_header' import GroupHeader from '../components/group_header'
import Responsive from '../features/ui/util/responsive_component';
export default class GroupLayout extends ImmutablePureComponent { export default class GroupLayout extends ImmutablePureComponent {
@ -25,6 +31,7 @@ export default class GroupLayout extends ImmutablePureComponent {
relationships, relationships,
showBackBtn, showBackBtn,
title, title,
noComposeButton,
} = this.props } = this.props
return ( return (
@ -33,28 +40,47 @@ export default class GroupLayout extends ImmutablePureComponent {
actions={actions} actions={actions}
showBackBtn={showBackBtn} showBackBtn={showBackBtn}
title={title} title={title}
noComposeButton
> >
<div className={[_s.default, _s.width100PC, _s.pl15].join(' ')}> <Responsive max={BREAKPOINT_EXTRA_SMALL}>
<div className={[_s.default, _s.width100PC].join(' ')}>
<GroupHeader group={group} relationships={relationships} /> <GroupHeader group={group} relationships={relationships}>
<GroupInfoPanel group={group} noPanel />
</GroupHeader>
<div className={[_s.default, _s.flexRow, _s.width100PC, _s.justifyContentEnd].join(' ')}> <div className={[_s.default, _s.width100PC, _s.z1].join(' ')}>
<div className={[_s.default, _s.width645PX, _s.z1].join(' ')}> {children}
<div className={_s.default}> </div>
{children}
</div>
</Responsive>
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
<div className={[_s.default, _s.width100PC, _s.pl15].join(' ')}>
<GroupHeader group={group} relationships={relationships} />
<div className={[_s.default, _s.flexRow, _s.width100PC, _s.justifyContentEnd].join(' ')}>
<div className={[_s.default, _s.width645PX, _s.z1].join(' ')}>
<div className={_s.default}>
{children}
</div>
</div>
<div className={[_s.default, _s.ml15, _s.width340PX].join(' ')}>
<Sticky top={73} enabled>
<div className={[_s.default, _s.width340PX].join(' ')}>
<GroupInfoPanel group={group} />
<WhoToFollowPanel />
<GroupSidebarPanel isSlim />
<LinkFooter />
</div>
</Sticky>
</div> </div>
</div> </div>
<div className={[_s.default, _s.ml15, _s.width340PX].join(' ')}>
<Sticky top={73} enabled>
<div className={[_s.default, _s.width340PX].join(' ')}>
{layout}
</div>
</Sticky>
</div>
</div> </div>
</Responsive>
</div>
</Layout> </Layout>
) )
} }

View File

@ -1,7 +1,9 @@
import Sticky from 'react-stickynode' import Sticky from 'react-stickynode'
import Sidebar from '../components/sidebar' import Sidebar from '../components/sidebar'
import { BREAKPOINT_EXTRA_SMALL } from '../constants' import { BREAKPOINT_EXTRA_SMALL } from '../constants'
import { me } from '../initial_state'
import NavigationBar from '../components/navigation_bar' import NavigationBar from '../components/navigation_bar'
import LoggedOutNavigationBar from '../components/logged_out_navigation_bar'
import FooterBar from '../components/footer_bar' import FooterBar from '../components/footer_bar'
import FloatingActionButton from '../components/floating_action_button' import FloatingActionButton from '../components/floating_action_button'
import Responsive from '../features/ui/util/responsive_component' import Responsive from '../features/ui/util/responsive_component'
@ -38,12 +40,19 @@ export default class Layout extends PureComponent {
return ( return (
<div className={[_s.default, _s.width100PC, _s.heightMin100VH, _s.bgTertiary].join(' ')}> <div className={[_s.default, _s.width100PC, _s.heightMin100VH, _s.bgTertiary].join(' ')}>
<NavigationBar {
actions={actions} me &&
tabs={tabs} <NavigationBar
title={title} actions={actions}
showBackBtn={showBackBtn} tabs={tabs}
/> title={title}
showBackBtn={showBackBtn}
/>
}
{
!me &&
<LoggedOutNavigationBar />
}
<div className={[_s.default, _s.flexRow, _s.width100PC].join(' ')}> <div className={[_s.default, _s.flexRow, _s.width100PC].join(' ')}>
{ {
@ -57,7 +66,7 @@ export default class Layout extends PureComponent {
/> />
</Responsive> </Responsive>
} }
<ResponsiveClassesComponent <ResponsiveClassesComponent
classNames={[_s.default, _s.flexShrink1, _s.flexGrow1].join(' ')} classNames={[_s.default, _s.flexShrink1, _s.flexGrow1].join(' ')}
classNamesSmall={[_s.default, _s.flexShrink1, _s.flexGrow1].join(' ')} classNamesSmall={[_s.default, _s.flexShrink1, _s.flexGrow1].join(' ')}

View File

@ -1,15 +1,25 @@
import ImmutablePropTypes from 'react-immutable-proptypes' import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component' import ImmutablePureComponent from 'react-immutable-pure-component'
import { BREAKPOINT_EXTRA_SMALL } from '../constants'
import Sticky from 'react-stickynode' import Sticky from 'react-stickynode'
import { me } from '../initial_state'
import LinkFooter from '../components/link_footer'
import ProfileStatsPanel from '../components/panel/profile_stats_panel'
import ProfileInfoPanel from '../components/panel/profile_info_panel'
import MediaGalleryPanel from '../components/panel/media_gallery_panel'
import NavigationBar from '../components/navigation_bar' import NavigationBar from '../components/navigation_bar'
import FooterBar from '../components/footer_bar'
import ProfileHeader from '../components/profile_header' import ProfileHeader from '../components/profile_header'
import ProfileNavigationBar from '../components/profile_navigation_bar'
import LoggedOutNavigationBar from '../components/logged_out_navigation_bar'
import Responsive from '../features/ui/util/responsive_component';
import Divider from '../components/divider';
export default class ProfileLayout extends ImmutablePureComponent { export default class ProfileLayout extends ImmutablePureComponent {
static propTypes = { static propTypes = {
account: ImmutablePropTypes.map, account: ImmutablePropTypes.map,
children: PropTypes.node.isRequired, children: PropTypes.node.isRequired,
layout: PropTypes.object,
title: PropTypes.string, title: PropTypes.string,
} }
@ -17,49 +27,103 @@ export default class ProfileLayout extends ImmutablePureComponent {
const { const {
account, account,
children, children,
layout,
title, title,
} = this.props } = this.props
return ( return (
<div className={[_s.default, _s.width100PC, _s.heightMin100VH, _s.bgTertiary].join(' ')}> <div className={[_s.default, _s.width100PC, _s.heightMin100VH, _s.bgTertiary].join(' ')}>
<Responsive max={BREAKPOINT_EXTRA_SMALL}>
{
!!me &&
<ProfileNavigationBar title={title} />
}
{
!me &&
<LoggedOutNavigationBar />
}
<NavigationBar /> <main role='main' className={[_s.default, _s.width100PC].join(' ')}>
<main role='main' className={[_s.default, _s.width100PC].join(' ')}> <div className={[_s.default, _s.width100PC, _s.flexRow, _s.pb15].join(' ')}>
<div className={[_s.default, _s.width100PC, _s.flexRow, _s.pb15].join(' ')}> <div className={[_s.default, _s.width100PC, _s.flexRow, _s.justifyContentSpaceBetween].join(' ')}>
<div className={[_s.default, _s.z1, _s.width100PC, _s.alignItemsCenter].join(' ')}>
<div className={[_s.default, _s.width100PC, _s.flexRow, _s.justifyContentSpaceBetween].join(' ')}> <ProfileHeader account={account}>
<div className={[_s.default, _s.z1, _s.width100PC, _s.alignItemsCenter].join(' ')}> <ProfileInfoPanel account={account} noPanel />
<Divider isSmall />
<ProfileStatsPanel account={account} noPanel />
</ProfileHeader>
<ProfileHeader account={account} /> <div className={[_s.default, _s.width100PC, , _s.flexRow, _s.justifyContentEnd, _s.py15].join(' ')}>
<div className={[_s.default, _s.width100PC, _s.z1].join(' ')}>
<div className={[_s.default, _s.width1015PX,, _s.flexRow, _s.justifyContentEnd, _s.py15].join(' ')}> <div className={_s.default}>
<div className={[_s.default, _s.width340PX, _s.mr15].join(' ')}> {children}
<Sticky top={63} enabled>
<div className={[_s.default, _s.width340PX].join(' ')}>
{layout}
</div> </div>
</Sticky>
</div>
<div className={[_s.default, _s.width645PX, _s.z1].join(' ')}>
<div className={_s.default}>
{children}
</div> </div>
</div> </div>
</div>
</div>
</div> </div>
</div> </div>
</main>
</div> <Responsive max={BREAKPOINT_EXTRA_SMALL}>
<FooterBar />
</Responsive>
</Responsive>
</main> <Responsive min={BREAKPOINT_EXTRA_SMALL}>
{
me &&
<NavigationBar />
}
{
!me &&
<LoggedOutNavigationBar />
}
<main role='main' className={[_s.default, _s.width100PC].join(' ')}>
<div className={[_s.default, _s.width100PC, _s.flexRow, _s.pb15].join(' ')}>
<div className={[_s.default, _s.width100PC, _s.flexRow, _s.justifyContentSpaceBetween].join(' ')}>
<div className={[_s.default, _s.z1, _s.width100PC, _s.alignItemsCenter].join(' ')}>
<ProfileHeader account={account} />
<div className={[_s.default, _s.width1015PX, , _s.flexRow, _s.justifyContentEnd, _s.py15].join(' ')}>
<div className={[_s.default, _s.width340PX, _s.mr15].join(' ')}>
<Sticky top={63} enabled>
<div className={[_s.default, _s.width340PX].join(' ')}>
<ProfileStatsPanel account={account} />
<ProfileInfoPanel account={account} />
<MediaGalleryPanel account={account} />
<LinkFooter />
</div>
</Sticky>
</div>
<div className={[_s.default, _s.width645PX, _s.z1].join(' ')}>
<div className={_s.default}>
{children}
</div>
</div>
</div>
</div>
</div>
</div>
</main>
</Responsive>
</div> </div>
) )
} }
} }

View File

@ -4,11 +4,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component' import ImmutablePureComponent from 'react-immutable-pure-component'
import { fetchGroup } from '../actions/groups' import { fetchGroup } from '../actions/groups'
import PageTitle from '../features/ui/util/page_title' import PageTitle from '../features/ui/util/page_title'
import GroupInfoPanel from '../components/panel/group_info_panel'
import GroupLayout from '../layouts/group_layout' import GroupLayout from '../layouts/group_layout'
import WhoToFollowPanel from '../components/panel/who_to_follow_panel'
import GroupSidebarPanel from '../components/panel/groups_panel'
import LinkFooter from '../components/link_footer'
import TimelineComposeBlock from '../components/timeline_compose_block' import TimelineComposeBlock from '../components/timeline_compose_block'
import Divider from '../components/divider' import Divider from '../components/divider'
@ -21,8 +17,10 @@ const mapStateToProps = (state, { params: { id } }) => ({
relationships: state.getIn(['group_relationships', id]), relationships: state.getIn(['group_relationships', id]),
}) })
const mapDispatchToProps = () => ({ const mapDispatchToProps = (dispatch) => ({
fetchGroup, onFetchGroup(groupId) {
dispatch(fetchGroup(groupId))
}
}) })
export default export default
@ -35,11 +33,12 @@ class GroupPage extends ImmutablePureComponent {
group: ImmutablePropTypes.map, group: ImmutablePropTypes.map,
children: PropTypes.node.isRequired, children: PropTypes.node.isRequired,
relationships: ImmutablePropTypes.map, relationships: ImmutablePropTypes.map,
fetchGroup: PropTypes.func.isRequired, onFetchGroup: PropTypes.func.isRequired,
} }
componentDidMount() { componentDidMount() {
this.props.fetchGroup(this.props.params.id) console.log("group page mounted:", this.props.params.id)
this.props.onFetchGroup(this.props.params.id)
} }
render() { render() {
@ -65,14 +64,6 @@ class GroupPage extends ImmutablePureComponent {
// onClick: null, // onClick: null,
// }, // },
]} ]}
layout={(
<Fragment>
<GroupInfoPanel group={group} />
<WhoToFollowPanel />
<GroupSidebarPanel isSlim />
<LinkFooter />
</Fragment>
)}
> >
<PageTitle path={[groupTitle, intl.formatMessage(messages.group)]} /> <PageTitle path={[groupTitle, intl.formatMessage(messages.group)]} />

View File

@ -2,8 +2,8 @@ import { Fragment } from 'react'
import { openModal } from '../actions/modal' import { openModal } from '../actions/modal'
import { defineMessages, injectIntl } from 'react-intl' import { defineMessages, injectIntl } from 'react-intl'
import { MODAL_HOME_TIMELINE_SETTINGS } from '../constants' import { MODAL_HOME_TIMELINE_SETTINGS } from '../constants'
import IntersectionObserverArticle from '../components/intersection_observer_article' // import IntersectionObserverArticle from '../components/intersection_observer_article'
import IntersectionObserverWrapper from '../features/ui/util/intersection_observer_wrapper' // import IntersectionObserverWrapper from '../features/ui/util/intersection_observer_wrapper'
import PageTitle from '../features/ui/util/page_title' import PageTitle from '../features/ui/util/page_title'
import GroupsPanel from '../components/panel/groups_panel' import GroupsPanel from '../components/panel/groups_panel'
import ListsPanel from '../components/panel/lists_panel' import ListsPanel from '../components/panel/lists_panel'
@ -43,23 +43,23 @@ class HomePage extends PureComponent {
totalQueuedItemsCount: PropTypes.number.isRequired, totalQueuedItemsCount: PropTypes.number.isRequired,
} }
intersectionObserverWrapper = new IntersectionObserverWrapper() // intersectionObserverWrapper = new IntersectionObserverWrapper()
componentDidMount() { // componentDidMount() {
this.attachIntersectionObserver() // this.attachIntersectionObserver()
} // }
componentWillUnmount() { // componentWillUnmount() {
this.detachIntersectionObserver() // this.detachIntersectionObserver()
} // }
attachIntersectionObserver() { // attachIntersectionObserver() {
this.intersectionObserverWrapper.connect() // this.intersectionObserverWrapper.connect()
} // }
detachIntersectionObserver() { // detachIntersectionObserver() {
this.intersectionObserverWrapper.disconnect() // this.intersectionObserverWrapper.disconnect()
} // }
render() { render() {
const { const {
@ -87,30 +87,9 @@ class HomePage extends PureComponent {
<UserPanel /> <UserPanel />
<ProgressPanel /> <ProgressPanel />
<TrendsPanel /> <TrendsPanel />
<IntersectionObserverArticle <ListsPanel />
id={'home-sidebar-lists-panel'} <WhoToFollowPanel />
listLength={7} <GroupsPanel />
index={4}
intersectionObserverWrapper={this.intersectionObserverWrapper}
>
<ListsPanel />
</IntersectionObserverArticle>
<IntersectionObserverArticle
id={'home-sidebar-wtf-panel'}
listLength={7}
index={5}
intersectionObserverWrapper={this.intersectionObserverWrapper}
>
<WhoToFollowPanel />
</IntersectionObserverArticle>
<IntersectionObserverArticle
id={'home-sidebar-groups-panel'}
listLength={7}
index={6}
intersectionObserverWrapper={this.intersectionObserverWrapper}
>
<GroupsPanel isLazy />
</IntersectionObserverArticle>
<LinkFooter /> <LinkFooter />
</Fragment> </Fragment>
)} )}

View File

@ -35,6 +35,7 @@ const mapStateToProps = (state) => ({
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
setFilter(value) { setFilter(value) {
console.log("SETTING ACTIVE FILTER:", value)
dispatch(setFilter('active', value)) dispatch(setFilter('active', value))
}, },
}) })
@ -56,7 +57,9 @@ class NotificationsPage extends PureComponent {
selectedFilter: PropTypes.string.isRequired, selectedFilter: PropTypes.string.isRequired,
} }
componentDidMount() { componentWill
UNSAFE_componentWillMount() {
this.checkForQueryStringChange(this.context.router.route.location) this.checkForQueryStringChange(this.context.router.route.location)
} }

View File

@ -5,10 +5,6 @@ import { fetchAccountByUsername } from '../actions/accounts'
import { makeGetAccount } from '../selectors' import { makeGetAccount } from '../selectors'
import { me } from '../initial_state' import { me } from '../initial_state'
import PageTitle from '../features/ui/util/page_title' import PageTitle from '../features/ui/util/page_title'
import LinkFooter from '../components/link_footer'
import ProfileStatsPanel from '../components/panel/profile_stats_panel'
import ProfileInfoPanel from '../components/panel/profile_info_panel'
import MediaGalleryPanel from '../components/panel/media_gallery_panel'
import ColumnIndicator from '../components/column_indicator' import ColumnIndicator from '../components/column_indicator'
import ProfileLayout from '../layouts/profile_layout' import ProfileLayout from '../layouts/profile_layout'
@ -66,14 +62,7 @@ class ProfilePage extends ImmutablePureComponent {
return ( return (
<ProfileLayout <ProfileLayout
account={account} account={account}
layout={( title={name}
<Fragment>
<ProfileStatsPanel account={account} />
<ProfileInfoPanel account={account} />
{ !unavailable && <MediaGalleryPanel account={account} /> }
<LinkFooter />
</Fragment>
)}
> >
<PageTitle path={`${name} (@${username})`} /> <PageTitle path={`${name} (@${username})`} />
{ {

View File

@ -5,6 +5,7 @@ import Responsive from '../features/ui/util/responsive_component'
import PageTitle from '../features/ui/util/page_title' import PageTitle from '../features/ui/util/page_title'
import LinkFooter from '../components/link_footer' import LinkFooter from '../components/link_footer'
import SearchFilterPanel from '../components/panel/search_filter_panel' import SearchFilterPanel from '../components/panel/search_filter_panel'
import TrendsPanel from '../components/panel/trends_panel'
import Search from '../components/search' import Search from '../components/search'
import Layout from '../layouts/layout' import Layout from '../layouts/layout'
@ -57,6 +58,7 @@ class SearchPage extends PureComponent {
layout={( layout={(
<Fragment> <Fragment>
<SearchFilterPanel /> <SearchFilterPanel />
<TrendsPanel />
<LinkFooter /> <LinkFooter />
</Fragment> </Fragment>
)} )}

View File

@ -240,6 +240,7 @@ body {
.flexRow { flex-direction: row; } .flexRow { flex-direction: row; }
.flexWrap { flex-wrap: wrap; } .flexWrap { flex-wrap: wrap; }
.flexColumnReverse { flex-direction: column-reverse; }
.alignItemsEnd { align-items: flex-end; } .alignItemsEnd { align-items: flex-end; }
.alignItemsStart { align-items: flex-start; } .alignItemsStart { align-items: flex-start; }
@ -451,14 +452,17 @@ body {
.heightMin80PX { min-height: 80px; } .heightMin80PX { min-height: 80px; }
.heightMin58PX { min-height: 58px; } .heightMin58PX { min-height: 58px; }
.heightMin50PX { min-height: 50px; } .heightMin50PX { min-height: 50px; }
.heightMin28PX { min-height: 28px; }
.height100PC { height: 100%; } .height100PC { height: 100%; }
.height350PX { height: 350px; } .height350PX { height: 350px; }
.height260PX { height: 260px; } .height260PX { height: 260px; }
.height220PX { height: 220px; } .height220PX { height: 220px; }
.height215PX { height: 215px; } .height215PX { height: 215px; }
.height200PX { height: 200px; }
.height158PX { height: 158px; } .height158PX { height: 158px; }
.height122PX { height: 122px; } .height122PX { height: 122px; }
.height98PX { height: 98px; }
.height72PX { height: 72px; } .height72PX { height: 72px; }
.height60PX { height: 60px; } .height60PX { height: 60px; }
.height53PX { height: 53px; } .height53PX { height: 53px; }
@ -664,11 +668,13 @@ body {
.mb5 { margin-bottom: 5px; } .mb5 { margin-bottom: 5px; }
.mbNeg5PX { margin-bottom: -5px; } .mbNeg5PX { margin-bottom: -5px; }
.mt15 { margin-top: 10px; }
.mt10 { margin-top: 10px; } .mt10 { margin-top: 10px; }
.mt5 { margin-top: 5px; } .mt5 { margin-top: 5px; }
.mt2 { margin-top: 2px; } .mt2 { margin-top: 2px; }
.mtAuto { margin-top: auto; } .mtAuto { margin-top: auto; }
.mtNeg32PX { margin-top: -32px; } .mtNeg32PX { margin-top: -32px; }
.mtNeg50PX { margin-top: -50px; }
.mtNeg75PX { margin-top: -75px; } .mtNeg75PX { margin-top: -75px; }
.pt5625PC { padding-top: 56.25%; } .pt5625PC { padding-top: 56.25%; }
@ -682,6 +688,7 @@ body {
.pb15 { padding-bottom: 15px; } .pb15 { padding-bottom: 15px; }
.pb10 { padding-bottom: 10px; } .pb10 { padding-bottom: 10px; }
.pb5 { padding-bottom: 5px; } .pb5 { padding-bottom: 5px; }
.pb3 { padding-bottom: 3px; }
.pl35 { padding-left: 35px; } .pl35 { padding-left: 35px; }
.pl25 { padding-left: 25px; } .pl25 { padding-left: 25px; }