This commit is contained in:
mgabdev 2020-05-09 23:26:58 -04:00
parent b620cb1372
commit dcb0a2c74b
25 changed files with 223 additions and 184 deletions

View File

@ -0,0 +1,24 @@
const AngleLeftIcon = ({
className = '',
size = '16px',
title = '',
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={size}
height={size}
viewBox='0 0 64 64'
xmlSpace='preserve'
aria-label={title}
>
<g>
<path d='M 25.835938 32.011719 L 49.777344 8.070312 C 50.4375 7.414062 50.800781 6.535156 50.800781 5.59375 C 50.800781 4.65625 50.4375 3.777344 49.777344 3.121094 L 47.679688 1.023438 C 47.019531 0.363281 46.140625 0 45.203125 0 C 44.265625 0 43.386719 0.363281 42.730469 1.023438 L 14.222656 29.53125 C 13.558594 30.191406 13.199219 31.074219 13.199219 32.011719 C 13.199219 32.953125 13.558594 33.835938 14.222656 34.5 L 42.703125 62.976562 C 43.359375 63.636719 44.238281 64 45.179688 64 C 46.117188 64 46.996094 63.636719 47.652344 62.976562 L 49.75 60.878906 C 51.117188 59.515625 51.117188 57.292969 49.75 55.929688 Z M 25.835938 32.011719' />
</g>
</svg>
)
export default AngleLeftIcon

View File

@ -1,3 +1,4 @@
import { CX } from '../constants'
import Button from './button' import Button from './button'
export default class BackButton extends PureComponent { export default class BackButton extends PureComponent {
@ -7,7 +8,8 @@ export default class BackButton extends PureComponent {
} }
static propTypes = { static propTypes = {
classNames: PropTypes.string, className: PropTypes.string,
icon: PropTypes.string,
iconClassName: PropTypes.string, iconClassName: PropTypes.string,
iconSize: PropTypes.string, iconSize: PropTypes.string,
} }
@ -26,18 +28,29 @@ export default class BackButton extends PureComponent {
render() { render() {
const { const {
classNames, className,
icon,
iconClassName, iconClassName,
iconSize, iconSize,
} = this.props } = this.props
const classes = CX(className, {
alignItemsCenter: 1,
bgTransparent: 1,
mr5: 1,
cursorPointer: 1,
outlineNone: 1,
default: 1,
justifyContentCenter: 1,
})
return ( return (
<Button <Button
noClasses noClasses
color='primary' color='primary'
backgroundColor='none' backgroundColor='none'
className={classNames || [_s.alignItemsCenter, _s.bgTransparent, _s.mr5, _s.cursorPointer, _s.outlineNone, _s.default, _s.justifyContentCenter].join(' ')} className={classes}
icon='arrow-left' icon={icon || 'angle-left'}
iconSize={iconSize || '24px'} iconSize={iconSize || '24px'}
iconClassName={iconClassName || [_s.mr5, _s.fillPrimary].join(' ')} iconClassName={iconClassName || [_s.mr5, _s.fillPrimary].join(' ')}
onClick={this.handleBackClick} onClick={this.handleBackClick}

View File

@ -33,6 +33,7 @@ class DisplayName extends ImmutablePureComponent {
noRelationship: PropTypes.bool, noRelationship: PropTypes.bool,
noUsername: PropTypes.bool, noUsername: PropTypes.bool,
isComment: PropTypes.bool, isComment: PropTypes.bool,
isCentered: PropTypes.bool,
} }
updateOnProps = [ updateOnProps = [
@ -44,6 +45,7 @@ class DisplayName extends ImmutablePureComponent {
'noRelationship', 'noRelationship',
'noUsername', 'noUsername',
'isComment', 'isComment',
'isCentered',
] ]
mouseOverTimeout = null mouseOverTimeout = null
@ -81,6 +83,7 @@ class DisplayName extends ImmutablePureComponent {
noRelationship, noRelationship,
isSmall, isSmall,
isComment, isComment,
isCentered,
} = this.props } = this.props
if (!account) return null if (!account) return null
@ -91,6 +94,7 @@ class DisplayName extends ImmutablePureComponent {
alignItemsCenter: !isMultiline, alignItemsCenter: !isMultiline,
flexRow: !isMultiline, flexRow: !isMultiline,
cursorPointer: !noHover, cursorPointer: !noHover,
alignItemsCenter: isCentered,
}) })
const displayNameClasses = CX({ const displayNameClasses = CX({
@ -124,9 +128,9 @@ class DisplayName extends ImmutablePureComponent {
}) })
const iconSize = const iconSize =
!!isLarge ? '19px' : !!isLarge ? 19 :
!!isComment ? '12px' : !!isComment ? 12 :
!!isSmall ? '14px' : '15px' !!isSmall ? 14 : 15
const domain = account.get('acct').split('@')[1] const domain = account.get('acct').split('@')[1]
const isRemoteUser = !!domain const isRemoteUser = !!domain
@ -157,20 +161,20 @@ class DisplayName extends ImmutablePureComponent {
onMouseLeave={noHover ? undefined : this.handleMouseLeave} onMouseLeave={noHover ? undefined : this.handleMouseLeave}
ref={this.setRef} ref={this.setRef}
> >
<span className={[_s.default, _s.flexRow, _s.alignItemsCenter, _s.maxWidth180PX, _s.maxWidth100PC].join(' ')}> <span className={[_s.default, _s.flexRow, _s.alignItemsCenter, _s.maxWidth100PC].join(' ')}>
<bdi className={[_s.text, _s.whiteSpaceNoWrap, _s.textOverflowEllipsis].join(' ')}> <bdi className={[_s.text, _s.whiteSpaceNoWrap, _s.textOverflowEllipsis].join(' ')}>
<strong <strong
className={displayNameClasses} className={displayNameClasses}
dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }} dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }}
/> />
{ {
!noRelationship && account.get('locked') && account.get('locked') &&
<Icon id='lock-filled' size={iconSize} className={[_s.fillPrimary, _s.ml5].join(' ')} /> <Icon id='lock-filled' size={`${iconSize - 3}px`} className={[_s.fillPrimary, _s.ml5].join(' ')} />
} }
</bdi> </bdi>
{ {
account.get('is_verified') && account.get('is_verified') &&
<Icon id='verified' size={iconSize} className={_s.default} /> <Icon id='verified' size={`${iconSize}px`} className={[_s.ml5, _s.default].join(' ')} />
} }
</span> </span>
{ {

View File

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

View File

@ -1,53 +1,89 @@
import { withRouter } from 'react-router-dom' import { withRouter } from 'react-router-dom'
import { me } from '../initial_state' import { me } from '../initial_state'
import { CX } from '../constants'
import Button from './button' import Button from './button'
export default export default
@withRouter @withRouter
class FooterBar extends PureComponent { class FooterBar extends PureComponent {
static contextTypes = {
router: PropTypes.object,
}
render() { render() {
if (!me) return false if (!me) return false
const noRouter = !this.context.router
const currentPathname = noRouter ? '' : this.context.router.route.location.pathname
const buttons = [
{
to: '/home',
icon: 'home',
title: 'Home',
active: currentPathname === '/home',
},
{
to: '/notifications',
icon: 'notifications',
title: 'Notifications',
active: currentPathname === '/notifications',
},
{
href: 'https://chat.gab.com',
icon: 'chat',
title: 'Chat',
},
{
href: 'https://trends.gab.com',
icon: 'trends',
title: 'Trends',
},
{
to: '/groups',
icon: 'group',
title: 'Groups',
active: currentPathname === '/groups',
},
]
return ( return (
<div className={[_s.default, _s.z4, _s.heightMin58PX, _s.width100PC].join(' ')}> <div className={[_s.default, _s.z4, _s.heightMin58PX, _s.width100PC].join(' ')}>
<div className={[_s.default, _s.posFixed, _s.left0, _s.right0, _s.bottom0, _s.heightMin58PX, _s.width100PC, _s.bgPrimary, _s.borderTop1PX, _s.borderColorSecondary].join(' ')}> <div className={[_s.default, _s.posFixed, _s.left0, _s.right0, _s.bottom0, _s.heightMin58PX, _s.width100PC, _s.bgPrimary, _s.borderTop1PX, _s.borderColorSecondary].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter, _s.height100PC, _s.heightMin58PX, _s.footerChin, _s.justifyContentSpaceAround].join(' ')}> <div className={[_s.default, _s.flexRow, _s.alignItemsCenter, _s.height100PC, _s.heightMin58PX, _s.footerChin, _s.justifyContentSpaceAround].join(' ')}>
{
buttons.map((props) => {
const classes = CX({
borderTop2PX: 1,
borderColorTransparent: !props.active,
borderColorBrand: props.active,
height100PC: 1,
heightMin58PX: 1,
px15: 1,
flexGrow1: 1,
alignItemsCenter: 1,
justifyContentCenter: 1,
})
const color = props.active ? 'brand' : 'secondary'
return (
<Button <Button
isText
backgroundColor='none' backgroundColor='none'
color='secondary'
to='/home'
icon='home'
iconSize='20px'
/>
<Button
backgroundColor='none'
color='secondary'
to='/notifications'
icon='notifications'
iconSize='20px'
/>
<Button
backgroundColor='none'
color='secondary'
href='https://chat.gab.com'
icon='chat'
iconSize='20px'
/>
<Button
backgroundColor='none'
color='secondary'
href='https://trends.gab.com'
icon='trends'
iconSize='20px'
/>
<Button
backgroundColor='none'
color='secondary'
to='/groups'
icon='group'
iconSize='20px' iconSize='20px'
color={color}
to={props.to}
icon={props.icon}
href={props.href}
title={props.title}
className={classes}
/> />
)
})
}
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,5 +1,6 @@
import AddIcon from '../assets/add_icon' import AddIcon from '../assets/add_icon'
import AngleRightIcon from '../assets/angle_right_icon' import AngleRightIcon from '../assets/angle_right_icon'
import AngleLeftIcon from '../assets/angle_left_icon'
import AppsIcon from '../assets/apps_icon' import AppsIcon from '../assets/apps_icon'
import ArrowLeftIcon from '../assets/arrow_left_icon' import ArrowLeftIcon from '../assets/arrow_left_icon'
import ArrowRightIcon from '../assets/arrow_right_icon' import ArrowRightIcon from '../assets/arrow_right_icon'
@ -74,6 +75,7 @@ import WebsiteIcon from '../assets/website_icon'
const ICONS = { const ICONS = {
'add': AddIcon, 'add': AddIcon,
'angle-right': AngleRightIcon, 'angle-right': AngleRightIcon,
'angle-left': AngleLeftIcon,
'apps': AppsIcon, 'apps': AppsIcon,
'arrow-left': ArrowLeftIcon, 'arrow-left': ArrowLeftIcon,
'arrow-right': ArrowRightIcon, 'arrow-right': ArrowRightIcon,

View File

@ -1,30 +1,8 @@
import classNames from 'classnames'; import { LoadingBar } from 'react-redux-loading-bar'
import { LoadingBar } from 'react-redux-loading-bar'; import {
import ZoomableImage from './zoomable_image'; CX,
} from '../constants'
// .image-loader { import ZoomableImage from './zoomable_image'
// position: relative;
// @include flex(center, center, column);
// @include size(100%);
// &__preview-canvas {
// object-fit: contain;
// @include max-size($media-modal-media-max-width, $media-modal-media-max-height);
// @include background-image("", contain, center, repeat);
// }
// &--amorphous & {
// &__preview-canvas {
// display: none;
// }
// }
// .loading-bar {
// position: relative;
// }
// }
export default class ImageLoader extends PureComponent { export default class ImageLoader extends PureComponent {
@ -54,7 +32,7 @@ export default class ImageLoader extends PureComponent {
get canvasContext() { get canvasContext() {
if (!this.canvas) { if (!this.canvas) {
return null; return null
} }
this._canvasContext = this._canvasContext || this.canvas.getContext('2d'); this._canvasContext = this._canvasContext || this.canvas.getContext('2d');
@ -151,12 +129,39 @@ export default class ImageLoader extends PureComponent {
} }
render () { render () {
const { alt, src, width, height, onClick } = this.props; const { alt, src, width, height, onClick } = this.props
const { loading } = this.state; const { loading } = this.state
const className = classNames('image-loader', { // .image-loader {
'image-loader--loading': loading, // position: relative;
'image-loader--amorphous': !this.hasSize(),
// @include flex(center, center, column);
// @include size(100%);
// &__preview-canvas {
// object-fit: contain;
// @include max-size($media-modal-media-max-width, $media-modal-media-max-height);
// @include background-image("", contain, center, repeat);
// }
// &--amorphous & {
// &__preview-canvas {
// display: none;
// }
// }
// .loading-bar {
// position: relative;
// }
// }
const className = CX({
default: 1,
width100PC: 1,
height100PC: 1,
// 'image-loader--loading': loading,
// 'image-loader--amorphous': !this.hasSize(),
}); });
return ( return (
@ -164,7 +169,7 @@ export default class ImageLoader extends PureComponent {
<LoadingBar loading={loading ? 1 : 0} className='loading-bar' style={{ width: this.state.width || width }} /> <LoadingBar loading={loading ? 1 : 0} className='loading-bar' style={{ width: this.state.width || width }} />
{loading ? ( {loading ? (
<canvas <canvas
className='image-loader__preview-canvas' className={[_s.default, _s.objectFitCover].join(' ')}
ref={this.setCanvasRef} ref={this.setCanvasRef}
width={width} width={width}
height={height} height={height}

View File

@ -148,14 +148,7 @@ class ModalBase extends PureComponent {
onClick={this.handleOnClose} onClick={this.handleOnClose}
className={[_s.default, _s.posFixed, _s.alignItemsCenter, _s.justifyContentCenter, _s.z4, _s.width100PC, _s.height100PC, _s.top0, _s.rightAuto, _s.bottomAuto, _s.left0].join(' ')} className={[_s.default, _s.posFixed, _s.alignItemsCenter, _s.justifyContentCenter, _s.z4, _s.width100PC, _s.height100PC, _s.top0, _s.rightAuto, _s.bottomAuto, _s.left0].join(' ')}
> >
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
{children} {children}
</Responsive>
<Responsive max={BREAKPOINT_EXTRA_SMALL}>
<CardView>
{children}
</CardView>
</Responsive>
</div> </div>
</Fragment> </Fragment>
} }

View File

@ -7,6 +7,7 @@ import Responsive from '../features/ui/util/responsive_component'
import ResponsiveClassesComponent from '../features/ui/util/responsive_classes_component' import ResponsiveClassesComponent from '../features/ui/util/responsive_classes_component'
import { CX } from '../constants' import { CX } from '../constants'
import Avatar from './avatar' import Avatar from './avatar'
import BackButton from './back_button'
import Button from './button' import Button from './button'
import Heading from './heading' import Heading from './heading'
import Icon from './icon' import Icon from './icon'
@ -21,10 +22,6 @@ export default
@connect(mapStateToProps) @connect(mapStateToProps)
class NavigationBar extends ImmutablePureComponent { class NavigationBar extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
}
static propTypes = { static propTypes = {
account: ImmutablePropTypes.map, account: ImmutablePropTypes.map,
actions: PropTypes.array, actions: PropTypes.array,
@ -33,18 +30,6 @@ class NavigationBar extends ImmutablePureComponent {
showBackBtn: PropTypes.bool, showBackBtn: PropTypes.bool,
} }
historyBack = () => {
if (window.history && window.history.length === 1) {
this.context.router.history.push('/home')
} else {
this.context.router.history.goBack()
}
}
handleBackClick = () => {
this.historyBack()
}
handleProfileClick = () => { handleProfileClick = () => {
} }
@ -119,7 +104,7 @@ class NavigationBar extends ImmutablePureComponent {
{ /** Mobile */} { /** Mobile */}
<Responsive max={BREAKPOINT_EXTRA_SMALL}> <Responsive max={BREAKPOINT_EXTRA_SMALL}>
<div className={[_s.default, _s.width84PX, _s.pl10].join(' ')}> <div className={[_s.default, _s.width84PX, _s.alignItemsStart, _s.pl10].join(' ')}>
{ {
!!account && !showBackBtn && !!account && !showBackBtn &&
<button <button
@ -132,15 +117,11 @@ class NavigationBar extends ImmutablePureComponent {
} }
{ {
showBackBtn && showBackBtn &&
<Button <BackButton
noClasses className={_s.height53PX}
color='primary' icon='angle-left'
backgroundColor='none' iconSize='18px'
className={[_s.height53PX, _s.bgTransparent, _s.mr5, _s.cursorPointer, _s.outlineNone, _s.default, _s.justifyContentCenter].join(' ')}
icon='arrow-left'
iconSize='32px'
iconClassName={[_s.mr5, _s.fillNavigation].join(' ')} iconClassName={[_s.mr5, _s.fillNavigation].join(' ')}
onClick={this.handleBackClick}
/> />
} }
</div> </div>

View File

@ -1,6 +1,5 @@
import { Fragment } from 'react' import { Fragment } from 'react'
import { defineMessages, injectIntl } from 'react-intl' import { defineMessages, injectIntl } from 'react-intl'
import { fetchSuggestions, dismissSuggestion } from '../../actions/suggestions'
import ImmutablePureComponent from 'react-immutable-pure-component' import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes' import ImmutablePropTypes from 'react-immutable-proptypes'
import { List as ImmutableList } from 'immutable' import { List as ImmutableList } from 'immutable'
@ -27,13 +26,8 @@ const mapStateToProps = (state, { account }) => {
} }
} }
const mapDispatchToProps = (dispatch) => ({
fetchSuggestions: () => dispatch(fetchSuggestions()),
dismissSuggestion: account => dispatch(dismissSuggestion(account.get('id'))),
})
export default export default
@connect(mapStateToProps, mapDispatchToProps) @connect(mapStateToProps, null)
@injectIntl @injectIntl
class ProfileInfoPanel extends ImmutablePureComponent { class ProfileInfoPanel extends ImmutablePureComponent {
@ -44,10 +38,6 @@ class ProfileInfoPanel extends ImmutablePureComponent {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
} }
componentDidMount() {
this.props.fetchSuggestions()
}
render() { render() {
const { const {
intl, intl,

View File

@ -36,25 +36,9 @@ class WhoToFollowPanel extends ImmutablePureComponent {
'suggestions', 'suggestions',
] ]
state = { componentDidMount() {
fetched: false,
}
static getDerivedStateFromProps(nextProps, prevState) {
if (!nextProps.isHidden && nextProps.isIntersecting && !prevState.fetched) {
return {
fetched: true
}
}
return null
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (!prevState.fetched && this.state.fetched) {
this.props.fetchSuggestions() this.props.fetchSuggestions()
} }
}
render() { render() {
const { intl, suggestions, dismissSuggestion } = this.props const { intl, suggestions, dismissSuggestion } = this.props

View File

@ -5,6 +5,7 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'
import classNames from 'classnames/bind' import classNames from 'classnames/bind'
import escapeTextContentForBrowser from 'escape-html' import escapeTextContentForBrowser from 'escape-html'
import spring from 'react-motion/lib/spring' import spring from 'react-motion/lib/spring'
import { me } from '../initial_state'
import Motion from '../features/ui/util/optional_motion' import Motion from '../features/ui/util/optional_motion'
import { vote } from '../actions/polls' import { vote } from '../actions/polls'
import emojify from './emoji/emoji' import emojify from './emoji/emoji'
@ -202,7 +203,7 @@ class Poll extends ImmutablePureComponent {
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter].join(' ')}> <div className={[_s.default, _s.flexRow, _s.alignItemsCenter].join(' ')}>
{ {
!showResults && !showResults && me &&
<Button <Button
isNarrow isNarrow
className={_s.mr10} className={_s.mr10}

View File

@ -65,7 +65,7 @@ class StatusSharePopover extends ImmutablePureComponent {
render() { render() {
const { intl, status } = this.props const { intl, status } = this.props
const mailToHref = !status ? undefined : `mailto:?subject=&body=${status.get('url')}` const mailToHref = !status ? undefined : `mailto:?subject=Gab&body=${status.get('url')}`
return ( return (
<PopoverLayout width={220}> <PopoverLayout width={220}>

View File

@ -173,7 +173,13 @@ class ProfileHeader extends ImmutablePureComponent {
</div> </div>
<div className={[_s.default, _s.flexRow, _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
isLarge
isCentered
noHover
/>
</div> </div>
</div> </div>
@ -214,7 +220,7 @@ 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(' ')}> <div className={[_s.default, _s.flexRow, _s.mr10].join(' ')}>
<AccountActionButton account={account} /> <AccountActionButton account={account} />
</div> </div>
@ -278,7 +284,7 @@ class ProfileHeader extends ImmutablePureComponent {
</div> </div>
<div className={[_s.default, _s.flexRow, _s.px15, _s.flexNormal, _s.py10].join(' ')}> <div className={[_s.default, _s.flexRow, _s.px15, _s.flexNormal, _s.py10].join(' ')}>
<DisplayName account={account} isMultiline noRelationship isLarge noHover /> <DisplayName account={account} isMultiline isLarge noHover />
</div> </div>
</div> </div>

View File

@ -18,8 +18,8 @@ export default class ProfileNavigationBar extends PureComponent {
<div className={[_s.default, _s.flexRow, _s.width100PC].join(' ')}> <div className={[_s.default, _s.flexRow, _s.width100PC].join(' ')}>
<BackButton <BackButton
classNames={[_s.height53PX, _s.bgTransparent, _s.ml10, _s.mr10, _s.cursorPointer, _s.outlineNone, _s.default, _s.justifyContentCenter].join(' ')} className={[_s.height53PX, _s.pl10, _s.pr10].join(' ')}
iconSize='32px' iconSize='18px'
iconClassName={[_s.mr5, _s.fillNavigation].join(' ')} iconClassName={[_s.mr5, _s.fillNavigation].join(' ')}
/> />

View File

@ -63,10 +63,6 @@ export default
@injectIntl @injectIntl
class Sidebar extends ImmutablePureComponent { class Sidebar extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
}
static propTypes = { static propTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
account: ImmutablePropTypes.map, account: ImmutablePropTypes.map,
@ -94,18 +90,6 @@ class Sidebar extends ImmutablePureComponent {
}) })
} }
historyBack = () => {
if (window.history && window.history.length === 1) {
this.context.router.history.push('/home')
} else {
this.context.router.history.goBack()
}
}
handleBackClick = () => {
this.historyBack()
}
setMoreButtonRef = n => { setMoreButtonRef = n => {
this.moreBtnRef = n this.moreBtnRef = n
} }
@ -221,14 +205,16 @@ class Sidebar extends ImmutablePureComponent {
<header role='banner' className={[_s.default, _s.flexGrow1, _s.z3, _s.alignItemsEnd].join(' ')}> <header role='banner' className={[_s.default, _s.flexGrow1, _s.z3, _s.alignItemsEnd].join(' ')}>
<div className={[_s.default, _s.width240PX].join(' ')}> <div className={[_s.default, _s.width240PX].join(' ')}>
<div className={[_s.default, _s.posFixed, _s.heightCalc53PX, _s.bottom0].join(' ')}> <div className={[_s.default, _s.posFixed, _s.heightCalc53PX, _s.bottom0].join(' ')}>
<div className={[_s.default, _s.height100PC, _s.alignItemsStart, _s.width240PX, _s.pr15, _s.py10, _s.overflowYScroll].join(' ')}> <div className={[_s.default, _s.height100PC, _s.alignItemsStart, _s.width240PX, _s.pr15, _s.py10, _s.noScrollbar, _s.overflowYScroll].join(' ')}>
<div className={[_s.default, _s.width100PC].join(' ')}> <div className={[_s.default, _s.width100PC].join(' ')}>
{ {
!!title && !!title &&
<div className={[_s.default, _s.flexRow, _s.px5, _s.pt10].join(' ')}> <div className={[_s.default, _s.flexRow, _s.px5, _s.pt10].join(' ')}>
{ {
showBackBtn && showBackBtn &&
<BackButton /> <BackButton
icon='arrow-left'
/>
} }
<Heading size='h1'> <Heading size='h1'>
{title} {title}

View File

@ -39,8 +39,6 @@ class StatusPrepend extends ImmutablePureComponent {
const isRepost = (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') const isRepost = (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object')
console.log("isComment:", isComment)
if (!isFeatured && !isPromoted && !isRepost && !isComment) return null if (!isFeatured && !isPromoted && !isRepost && !isComment) return null
let iconId let iconId

View File

@ -117,7 +117,7 @@ class Notifications extends ImmutablePureComponent {
// : todo : include follow requests // : todo : include follow requests
console.log('--0--notifications:', notifications) console.log('--0--notifications:', hasMore)
if (isLoading && this.scrollableContent) { if (isLoading && this.scrollableContent) {
scrollableContent = this.scrollableContent scrollableContent = this.scrollableContent

View File

@ -370,6 +370,7 @@ class UI extends PureComponent {
} }
this.props.dispatch(expandHomeTimeline()) this.props.dispatch(expandHomeTimeline())
this.props.dispatch(expandNotifications())
this.props.dispatch(initializeNotifications()) this.props.dispatch(initializeNotifications())
setTimeout(() => { setTimeout(() => {

View File

@ -21,6 +21,7 @@ export default class ProfileLayout extends ImmutablePureComponent {
account: ImmutablePropTypes.map, account: ImmutablePropTypes.map,
children: PropTypes.node.isRequired, children: PropTypes.node.isRequired,
title: PropTypes.string, title: PropTypes.string,
unavailable: PropTypes.bool,
} }
render() { render() {
@ -28,6 +29,7 @@ export default class ProfileLayout extends ImmutablePureComponent {
account, account,
children, children,
title, title,
unavailable,
} = this.props } = this.props
return ( return (
@ -101,7 +103,7 @@ export default class ProfileLayout extends ImmutablePureComponent {
<div className={[_s.default, _s.width340PX].join(' ')}> <div className={[_s.default, _s.width340PX].join(' ')}>
<ProfileStatsPanel account={account} /> <ProfileStatsPanel account={account} />
<ProfileInfoPanel account={account} /> <ProfileInfoPanel account={account} />
<MediaGalleryPanel account={account} /> { !unavailable && <MediaGalleryPanel account={account} /> }
<LinkFooter /> <LinkFooter />
</div> </div>
</Sticky> </Sticky>

View File

@ -37,7 +37,6 @@ class GroupPage extends ImmutablePureComponent {
} }
componentDidMount() { componentDidMount() {
console.log("group page mounted:", this.props.params.id)
this.props.onFetchGroup(this.props.params.id) this.props.onFetchGroup(this.props.params.id)
} }
@ -54,16 +53,9 @@ class GroupPage extends ImmutablePureComponent {
return ( return (
<GroupLayout <GroupLayout
showBackBtn showBackBtn
title={intl.formatMessage(messages.group)} title={groupTitle}
group={group} group={group}
relationships={relationships} relationships={relationships}
actions={[
// : todo :
// {
// icon: 'ellipsis',
// onClick: null,
// },
]}
> >
<PageTitle path={[groupTitle, intl.formatMessage(messages.group)]} /> <PageTitle path={[groupTitle, intl.formatMessage(messages.group)]} />

View File

@ -16,6 +16,7 @@ const filters = [
'reblog', 'reblog',
'poll', 'poll',
'follow', 'follow',
'follow_requests',
] ]
const messages = defineMessages({ const messages = defineMessages({
@ -25,6 +26,7 @@ const messages = defineMessages({
reblog: { id: 'reposts', defaultMessage: 'Reposts' }, reblog: { id: 'reposts', defaultMessage: 'Reposts' },
poll: { id: 'polls', defaultMessage: 'Poll' }, poll: { id: 'polls', defaultMessage: 'Poll' },
follow: { id: 'notifications.filter.follows', defaultMessage: 'Follows' }, follow: { id: 'notifications.filter.follows', defaultMessage: 'Follows' },
follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
all: { id: 'notifications.filter.all', defaultMessage: 'All' }, all: { id: 'notifications.filter.all', defaultMessage: 'All' },
}) })
@ -35,7 +37,6 @@ 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))
}, },
}) })

View File

@ -1,4 +1,4 @@
import { Fragment } from 'react' import { FormattedMessage } from 'react-intl'
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 { fetchAccountByUsername } from '../actions/accounts' import { fetchAccountByUsername } from '../actions/accounts'
@ -6,6 +6,7 @@ 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 ColumnIndicator from '../components/column_indicator' import ColumnIndicator from '../components/column_indicator'
import Block from '../components/block'
import ProfileLayout from '../layouts/profile_layout' import ProfileLayout from '../layouts/profile_layout'
const mapStateToProps = (state, { params: { username } }) => { const mapStateToProps = (state, { params: { username } }) => {
@ -63,6 +64,7 @@ class ProfilePage extends ImmutablePureComponent {
<ProfileLayout <ProfileLayout
account={account} account={account}
title={name} title={name}
unavailable={unavailable}
> >
<PageTitle path={`${name} (@${username})`} /> <PageTitle path={`${name} (@${username})`} />
{ {
@ -74,6 +76,12 @@ class ProfilePage extends ImmutablePureComponent {
account, account,
}) })
} }
{
unavailable &&
<ColumnIndicator type='error' message={
<FormattedMessage id='empty_column.account_unavailable' defaultMessage='Profile unavailable' />
} />
}
</ProfileLayout> </ProfileLayout>
) )
} }

View File

@ -12,7 +12,7 @@ export const shortNumberFormat = (number) => {
return ( return (
<Fragment> <Fragment>
<FormattedNumber value={number / 1000} maximumFractionDigits={1} /> <FormattedNumber value={number / 1000} maximumFractionDigits={1} />k
</Fragment> </Fragment>
) )
} }

View File

@ -1,4 +1,5 @@
:root { :root {
--color_highlight: #CCF3DF;
--color_brand-dark: #378e61; --color_brand-dark: #378e61;
--color_brand-light: #63DA9D; --color_brand-light: #63DA9D;
--color_brand-light-opaque: rgb(54, 233, 145, .125); --color_brand-light-opaque: rgb(54, 233, 145, .125);
@ -94,6 +95,14 @@
--navigation_brand: var(--color_brand) !important; --navigation_brand: var(--color_brand) !important;
} }
::selection {
background: var(--color_highlight);
}
::-moz-selection {
background: var(--color_highlight);
}
html, html,
body { body {
height: 100%; height: 100%;
@ -296,6 +305,7 @@ body {
.borderBottom6PX { border-bottom-width: 6px; } .borderBottom6PX { border-bottom-width: 6px; }
.borderLeft1PX { border-left-width: 1px; } .borderLeft1PX { border-left-width: 1px; }
.borderTop1PX { border-top-width: 1px; } .borderTop1PX { border-top-width: 1px; }
.borderTop2PX { border-top-width: 2px; }
.border1PX { border-width: 1px; } .border1PX { border-width: 1px; }
.border2PX { border-width: 2px; } .border2PX { border-width: 2px; }