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

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

View File

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

View File

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

View File

@@ -1,53 +1,89 @@
import { withRouter } from 'react-router-dom'
import { me } from '../initial_state'
import { CX } from '../constants'
import Button from './button'
export default
@withRouter
class FooterBar extends PureComponent {
static contextTypes = {
router: PropTypes.object,
}
render() {
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 (
<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.flexRow, _s.alignItemsCenter, _s.height100PC, _s.heightMin58PX, _s.footerChin, _s.justifyContentSpaceAround].join(' ')}>
<Button
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'
/>
{
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
isText
backgroundColor='none'
iconSize='20px'
color={color}
to={props.to}
icon={props.icon}
href={props.href}
title={props.title}
className={classes}
/>
)
})
}
</div>
</div>
</div>

View File

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

View File

@@ -1,30 +1,8 @@
import classNames from 'classnames';
import { LoadingBar } from 'react-redux-loading-bar';
import ZoomableImage from './zoomable_image';
// .image-loader {
// 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;
// }
// }
import { LoadingBar } from 'react-redux-loading-bar'
import {
CX,
} from '../constants'
import ZoomableImage from './zoomable_image'
export default class ImageLoader extends PureComponent {
@@ -54,7 +32,7 @@ export default class ImageLoader extends PureComponent {
get canvasContext() {
if (!this.canvas) {
return null;
return null
}
this._canvasContext = this._canvasContext || this.canvas.getContext('2d');
@@ -151,12 +129,39 @@ export default class ImageLoader extends PureComponent {
}
render () {
const { alt, src, width, height, onClick } = this.props;
const { loading } = this.state;
const { alt, src, width, height, onClick } = this.props
const { loading } = this.state
const className = classNames('image-loader', {
'image-loader--loading': loading,
'image-loader--amorphous': !this.hasSize(),
// .image-loader {
// 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;
// }
// }
const className = CX({
default: 1,
width100PC: 1,
height100PC: 1,
// 'image-loader--loading': loading,
// 'image-loader--amorphous': !this.hasSize(),
});
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 }} />
{loading ? (
<canvas
className='image-loader__preview-canvas'
className={[_s.default, _s.objectFitCover].join(' ')}
ref={this.setCanvasRef}
width={width}
height={height}

View File

@@ -148,14 +148,7 @@ class ModalBase extends PureComponent {
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(' ')}
>
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
{children}
</Responsive>
<Responsive max={BREAKPOINT_EXTRA_SMALL}>
<CardView>
{children}
</CardView>
</Responsive>
{children}
</div>
</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 { CX } from '../constants'
import Avatar from './avatar'
import BackButton from './back_button'
import Button from './button'
import Heading from './heading'
import Icon from './icon'
@@ -21,10 +22,6 @@ export default
@connect(mapStateToProps)
class NavigationBar extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
}
static propTypes = {
account: ImmutablePropTypes.map,
actions: PropTypes.array,
@@ -33,18 +30,6 @@ class NavigationBar extends ImmutablePureComponent {
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 = () => {
}
@@ -119,7 +104,7 @@ class NavigationBar extends ImmutablePureComponent {
{ /** Mobile */}
<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 &&
<button
@@ -132,15 +117,11 @@ class NavigationBar extends ImmutablePureComponent {
}
{
showBackBtn &&
<Button
noClasses
color='primary'
backgroundColor='none'
className={[_s.height53PX, _s.bgTransparent, _s.mr5, _s.cursorPointer, _s.outlineNone, _s.default, _s.justifyContentCenter].join(' ')}
icon='arrow-left'
iconSize='32px'
<BackButton
className={_s.height53PX}
icon='angle-left'
iconSize='18px'
iconClassName={[_s.mr5, _s.fillNavigation].join(' ')}
onClick={this.handleBackClick}
/>
}
</div>

View File

@@ -1,6 +1,5 @@
import { Fragment } from 'react'
import { defineMessages, injectIntl } from 'react-intl'
import { fetchSuggestions, dismissSuggestion } from '../../actions/suggestions'
import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
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
@connect(mapStateToProps, mapDispatchToProps)
@connect(mapStateToProps, null)
@injectIntl
class ProfileInfoPanel extends ImmutablePureComponent {
@@ -44,10 +38,6 @@ class ProfileInfoPanel extends ImmutablePureComponent {
intl: PropTypes.object.isRequired,
}
componentDidMount() {
this.props.fetchSuggestions()
}
render() {
const {
intl,

View File

@@ -36,24 +36,8 @@ class WhoToFollowPanel extends ImmutablePureComponent {
'suggestions',
]
state = {
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()
}
componentDidMount() {
this.props.fetchSuggestions()
}
render() {

View File

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

View File

@@ -65,7 +65,7 @@ class StatusSharePopover extends ImmutablePureComponent {
render() {
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 (
<PopoverLayout width={220}>

View File

@@ -173,7 +173,13 @@ class ProfileHeader extends ImmutablePureComponent {
</div>
<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>
@@ -214,7 +220,7 @@ class ProfileHeader extends ImmutablePureComponent {
<input type='hidden' value={account.get('username')} name='username' />
</form>
<div className={[_s.default, _s.flexRow, _s.pb3, _s.mr10].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.mr10].join(' ')}>
<AccountActionButton account={account} />
</div>
@@ -278,7 +284,7 @@ class ProfileHeader extends ImmutablePureComponent {
</div>
<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>

View File

@@ -18,8 +18,8 @@ export default class ProfileNavigationBar extends PureComponent {
<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'
className={[_s.height53PX, _s.pl10, _s.pr10].join(' ')}
iconSize='18px'
iconClassName={[_s.mr5, _s.fillNavigation].join(' ')}
/>

View File

@@ -63,10 +63,6 @@ export default
@injectIntl
class Sidebar extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
}
static propTypes = {
intl: PropTypes.object.isRequired,
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 => {
this.moreBtnRef = n
}
@@ -221,14 +205,16 @@ class Sidebar extends ImmutablePureComponent {
<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.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(' ')}>
{
!!title &&
<div className={[_s.default, _s.flexRow, _s.px5, _s.pt10].join(' ')}>
{
showBackBtn &&
<BackButton />
<BackButton
icon='arrow-left'
/>
}
<Heading size='h1'>
{title}

View File

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