This commit is contained in:
mgabdev 2020-02-17 12:50:29 -05:00
parent cdde454915
commit be3daea78b
28 changed files with 456 additions and 176 deletions

View File

@ -53,7 +53,7 @@ class ColumnHeader extends PureComponent {
{ /* <button className={[styles.default, styles.cursorPointer, styles.backgroundTransparent, styles.alignItemsCenter, styles.marginRight10PX, styles.justifyContentCenter].join(' ')}>
<Icon className={[styles.marginRight5PX, styles.fillColorBrand].join(' ')} id='back' width='24px' height='24px' />
</button> */ }
<h1 className={[styles.default, styles.height100PC, styles.justifyContentCenter].join(' ')}>
<h1 role='heading' className={[styles.default, styles.height100PC, styles.justifyContentCenter].join(' ')}>
<span className={[styles.default, styles.text, styles.fontSize24PX, styles.fontWeight500, styles.colorBlack].join(' ')}>
{title}
</span>
@ -62,12 +62,6 @@ class ColumnHeader extends PureComponent {
<button className={[styles.default, styles.marginLeft5PX, styles.cursorPointer, styles.backgroundSubtle2, styles.paddingHorizontal10PX, styles.paddingVertical5PX, styles.radiusSmall].join(' ')}>
<Icon className={styles.fillColorSubtle} id='ellipsis' width='24px' height='24px' />
</button>
<button className={[styles.default, styles.marginLeft5PX, styles.cursorPointer, styles.backgroundSubtle2, styles.paddingHorizontal10PX, styles.paddingVertical5PX, styles.radiusSmall].join(' ')}>
<Icon className={styles.fillColorSubtle} id='ellipsis' width='24px' height='24px' />
</button>
<button className={[styles.default, styles.marginLeft5PX, styles.cursorPointer, styles.backgroundSubtle2, styles.paddingHorizontal10PX, styles.paddingVertical5PX, styles.radiusSmall].join(' ')}>
<Icon className={styles.fillColorSubtle} id='ellipsis' width='24px' height='24px' />
</button>
</div>
</div>
)

View File

@ -107,7 +107,7 @@ class Header extends ImmutablePureComponent {
title: 'Home',
icon: 'home',
to: '/',
count: 0,
count: 124,
},
{
title: 'Notifications',
@ -122,7 +122,7 @@ class Header extends ImmutablePureComponent {
},
{
title: 'Lists',
icon: 'lists',
icon: 'list',
to: '/lists',
},
{
@ -130,14 +130,9 @@ class Header extends ImmutablePureComponent {
icon: 'chat',
to: '/',
},
{
title: 'Profile',
icon: 'profile',
to: '/',
},
{
title: 'More',
icon: 'plus',
icon: 'more',
to: '/',
},
]
@ -150,24 +145,14 @@ class Header extends ImmutablePureComponent {
count: 0,
},
{
title: 'Andrew',
icon: 'user',
title: '@andrew',
image: 'http://localhost:3000/system/accounts/avatars/000/000/001/original/260e8c96c97834da.jpeg?1562898139',
to: '/',
count: 3,
},
]
const exploreItems = [
{
title: 'Trends',
icon: 'trends',
to: '/',
},
{
title: 'Dissenter',
icon: 'dissenter',
to: '/',
},
{
title: 'Apps',
icon: 'apps',
@ -178,6 +163,16 @@ class Header extends ImmutablePureComponent {
icon: 'shop',
to: '/',
},
{
title: 'Trends',
icon: 'trends',
to: '/',
},
{
title: 'Dissenter',
icon: 'dissenter',
to: '/',
},
]
const cx = classNames.bind(styles)
@ -204,6 +199,9 @@ class Header extends ImmutablePureComponent {
<GabLogo />
</NavLink>
</h1>
<div>
<HeaderMenuItem me image='http://localhost:3000/system/accounts/avatars/000/000/001/original/260e8c96c97834da.jpeg?1562898139' title='@admin' to='/profile' />
</div>
<nav aria-label='Primary' role='navigation' className={[styles.default, styles.width100PC, styles.marginBottom15PX].join(' ')}>
<span className={titleClasses}>Menu</span>
{
@ -241,7 +239,10 @@ class HeaderMenuItem extends PureComponent {
to: PropTypes.string,
active: PropTypes.bool,
icon: PropTypes.string,
image: PropTypes.string,
title: PropTypes.string,
me: PropTypes.boolean,
count: PropTypes.number,
}
state = {
@ -257,12 +258,14 @@ class HeaderMenuItem extends PureComponent {
}
render() {
const { to, active, icon, title } = this.props
const { to, active, icon, image, title, me, count } = this.props
const { hovering } = this.state
const cx = classNames.bind(styles)
const iconSize = '16px'
const shouldShowActive = hovering || active
const isNotifications = to === '/notifications'
const containerClasses = cx({
default: 1,
@ -275,7 +278,7 @@ class HeaderMenuItem extends PureComponent {
radiusSmall: 1,
// border1PX: shouldShowActive,
// borderColorSubtle: shouldShowActive,
backgroundColorBrandLightOpaque: shouldShowActive,
backgroundSubtle2: shouldShowActive,
})
const textClasses = cx({
@ -283,14 +286,29 @@ class HeaderMenuItem extends PureComponent {
fontWeightNormal: 1,
fontSize15PX: 1,
text: 1,
fontWeight500: shouldShowActive,
colorBrand: shouldShowActive,
colorBlack: !hovering && !active,
textOverflowEllipsis: 1,
colorBlack: shouldShowActive || me,
colorSubtle: !hovering && !active && !me,
})
const iconClasses = cx({
fillColorBrand: shouldShowActive,
fillColorBlack: !hovering && !active,
fillColorBlack: shouldShowActive,
fillColorSubtle: !hovering && !active,
})
const countClasses = cx({
default: 1,
text: 1,
marginLeftAuto: 1,
fontSize12PX: 1,
paddingHorizontal5PX: 1,
marginRight2PX: 1,
lineHeight15: 1,
marginLeft5PX: 1,
colorSubtle: !isNotifications,
colorWhite: isNotifications,
backgroundColorBrand: isNotifications,
radiusSmall: isNotifications,
})
return (
@ -302,11 +320,24 @@ class HeaderMenuItem extends PureComponent {
>
<div className={containerClasses}>
<div className={[styles.default]}>
<Icon id={icon} className={iconClasses} width='15px' height='15px' />
{ icon && <Icon id={icon} className={iconClasses} width={iconSize} height={iconSize} /> }
{ image &&
<img
className={[styles.default, styles.circle].join(' ')}
width={iconSize}
height={iconSize}
src={image}
/>
}
</div>
<div className={[styles.default, styles.paddingHorizontal10PX, styles.textOverflowEllipsis, styles.overflowWrapBreakWord, styles.displayInline].join(' ')}>
<div className={[styles.default, styles.flexNormal, styles.paddingHorizontal10PX, styles.textOverflowEllipsis, styles.overflowWrapBreakWord, styles.flexRow, styles.width100PC].join(' ')}>
<span className={textClasses}>{title}</span>
</div>
{ count > 0 &&
<span className={countClasses}>
{count}
</span>
}
</div>
</NavLink>
)

View File

@ -1,19 +1,26 @@
import AppsIcon from './svgs/apps_icon'
import BackIcon from './svgs/back_icon'
import CalendarIcon from './svgs/calendar_icon'
import ChatIcon from './svgs/chat_icon'
import CloseIcon from './svgs/close_icon'
import CommentIcon from './svgs/comment_icon'
import DissenterIcon from './svgs/dissenter_icon'
import EllipsisIcon from './svgs/ellipsis_icon'
import GlobeIcon from './svgs/globe_icon'
import GroupIcon from './svgs/group_icon'
import HomeIcon from './svgs/home_icon'
import LikeIcon from './svgs/like_icon'
import ListIcon from './svgs/list_icon'
import LoadingIcon from './svgs/loading_icon'
import MediaIcon from './svgs/media_icon'
import MoreIcon from './svgs/more_icon'
import NotificationsIcon from './svgs/notifications_icon'
import PollIcon from './svgs/poll_icon'
import RepostIcon from './svgs/repost_icon'
import SearchIcon from './svgs/search_icon'
import ShareIcon from './svgs/share_icon'
import ShopIcon from './svgs/shop_icon'
import TrendsIcon from './svgs/trends_icon'
import VerifiedIcon from './svgs/verified_icon'
import WarningIcon from './svgs/warning_icon'
@ -30,14 +37,20 @@ export default class Icon extends PureComponent {
const { id, ...options } = this.props
switch (id) {
case 'apps':
return <AppsIcon {...options} />
case 'back':
return <BackIcon {...options} />
case 'calendar':
return <CalendarIcon {...options} />
case 'chat':
return <ChatIcon {...options} />
case 'close':
return <CloseIcon {...options} />
case 'comment':
return <CommentIcon {...options} />
case 'dissenter':
return <DissenterIcon {...options} />
case 'ellipsis':
return <EllipsisIcon {...options} />
case 'globe':
@ -48,8 +61,12 @@ export default class Icon extends PureComponent {
return <HomeIcon {...options} />
case 'like':
return <LikeIcon {...options} />
case 'list':
return <ListIcon {...options} />
case 'loading':
return <LoadingIcon {...options} />
case 'more':
return <MoreIcon {...options} />
case 'media':
return <MediaIcon {...options} />
case 'notifications':
@ -62,10 +79,14 @@ export default class Icon extends PureComponent {
return <SearchIcon {...options} />
case 'share':
return <ShareIcon {...options} />
case 'shop':
return <ShopIcon {...options} />
case 'trends':
return <TrendsIcon {...options} />
case 'verified':
return <VerifiedIcon {...options} />
case 'warning':
return <WarningIcon {...options} />
return <WarningIcon {...options} />
default:
return <NotificationsIcon {...options} />
}

View File

@ -0,0 +1,35 @@
const AppsIcon = ({
className = '',
width = '16px',
height = '16px',
viewBox = '0 0 80 80',
title = 'Apps',
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={width}
height={height}
viewBox={viewBox}
xmlSpace='preserve'
aria-label={title}
>
<g>
<rect x="0" y="0" width="24" height="24" rx="4" />
<rect x="0" y="28" width="24" height="24" rx="4" />
<rect x="0" y="56" width="24" height="24" rx="4" />
<rect x="28" y="0" width="24" height="24" rx="4" />
<rect x="28" y="28" width="24" height="24" rx="4" />
<rect x="28" y="56" width="24" height="24" rx="4" />
<rect x="56" y="0" width="24" height="24" rx="4" />
<rect x="56" y="28" width="24" height="24" rx="4" />
<rect x="56" y="56" width="24" height="24" rx="4" />
</g>
</svg>
)
export default AppsIcon

View File

@ -0,0 +1,27 @@
const ChatIcon = ({
className = '',
width = '16px',
height = '16px',
viewBox = '0 0 64 64',
title = 'Chat',
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={width}
height={height}
viewBox={viewBox}
xmlSpace='preserve'
aria-label={title}
>
<g>
<path d="M 53.582 59.804 L 47.851 55.964 C 39.121 57.57 30.07 54.253 25.582 48.0625 C 23.726 45.453 22.75 42.496 22.75 39.5 C 22.75 30.195 32 22.625 43.375 22.625 C 47.765 22.625 51.972 23.738 55.542 25.847 C 60.839 29.019 64 34.121 64 39.5 C 64 44.527 61.218 49.328 56.5 52.527 L 56.5 58.25 C 56.5 59.761 54.812 60.636 53.582 59.804 Z M 53.582 59.804" />
<path d="M 19 39.5 C 19 28.128 29.933 18.875 43.375 18.875 C 47.839 18.875 52.125 19.937 55.929 21.859 C 53.308 11.609 41.953 3.875 28.375 3.875 C 12.867 3.875 0 13.96 0 26.375 C 0 32.132 2.906 37.539 7.75 41.695 L 7.75 50.75 C 7.75 52.257 9.429 53.132 10.664 52.308 L 18.121 47.339 C 19.132 47.652344 20.175 47.859 21.218 48.074 C 19.773 45.375 19 42.464 19 39.5 Z M 19 39.5" />
</g>
</svg>
)
export default ChatIcon

View File

@ -0,0 +1,29 @@
const DissenterIcon = ({
className = '',
width = '32px',
height = '32px',
viewBox = '0 0 64 64',
title = 'Dissenter',
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={width}
height={height}
viewBox={viewBox}
xmlSpace='preserve'
aria-label={title}
>
<g>
<path d="M 33.519531 4.734375 L 8.007812 4.734375 C 4.800781 4.734375 2.175781 7.359375 2.175781 10.566406 L 2.175781 53.5625 C 2.175781 56.769531 4.800781 59.390625 8.007812 59.390625 L 33.519531 59.390625 C 52.011719 59.390625 61.953125 46.503906 61.953125 32.0625 C 61.953125 17.625 52.550781 4.734375 33.519531 4.734375" />
<path fill='#F6F6F9' d="M 41.761719 24.574219 L 17.757812 24.574219 C 16.925781 24.574219 16.257812 23.886719 16.257812 23.039062 C 16.257812 22.191406 16.925781 21.503906 17.757812 21.503906 L 41.761719 21.503906 C 42.59375 21.503906 43.265625 22.191406 43.265625 23.039062 C 43.265625 23.886719 42.59375 24.574219 41.761719 24.574219" />
<path fill='#F6F6F9' d="M 41.761719 33.535156 L 17.757812 33.535156 C 16.925781 33.535156 16.257812 32.847656 16.257812 32 C 16.257812 31.152344 16.925781 30.464844 17.757812 30.464844 L 41.761719 30.464844 C 42.59375 30.464844 43.265625 31.152344 43.265625 32 C 43.265625 32.847656 42.59375 33.535156 41.761719 33.535156" />
<path fill='#F6F6F9' d="M 17.765625 42.625 C 16.929688 42.625 16.257812 41.9375 16.257812 41.089844 C 16.257812 40.238281 16.929688 39.550781 17.765625 39.550781 L 33.820312 39.550781 C 34.652344 39.550781 35.328125 40.238281 35.328125 41.089844 C 35.328125 41.9375 34.652344 42.625 33.820312 42.625 Z M 17.765625 42.625" />
</g>
</svg>
)
export default DissenterIcon

View File

@ -0,0 +1,26 @@
const ListIcon = ({
className = '',
width = '26px',
height = '26px',
viewBox = '0 0 64 64',
title = 'List',
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={width}
height={height}
viewBox={viewBox}
xmlSpace='preserve'
aria-label={title}
>
<g>
<path d="M 57.144 0 L 6.855 0 C 3.07 0 0 3.023 0 6.75 L 0 56.25 C 0 59.976 3.07 63 6.855 63 L 57.144 63 C 60.929 63 64 59.976562 64 56.25 L 64 6.75 C 64 3.023438 60.929688 0 57.144531 0 Z M 20.570312 49.5 L 13.714844 49.5 C 12.453125 49.5 11.429688 48.492188 11.429688 47.25 C 11.429688 46.007812 12.453125 45 13.714844 45 L 20.570312 45 C 21.832031 45 22.855469 46.007812 22.855469 47.25 C 22.855469 48.492188 21.832031 49.5 20.570312 49.5 Z M 20.570312 33.75 L 13.714844 33.75 C 12.453125 33.75 11.429688 32.742188 11.429688 31.5 C 11.429688 30.257812 12.453125 29.25 13.714844 29.25 L 20.570312 29.25 C 21.832031 29.25 22.855469 30.257812 22.855469 31.5 C 22.855469 32.742188 21.832031 33.75 20.570312 33.75 Z M 20.570312 18 L 13.714844 18 C 12.453125 18 11.429688 16.992188 11.429688 15.75 C 11.429688 14.507812 12.453125 13.5 13.714844 13.5 L 20.570312 13.5 C 21.832031 13.5 22.855469 14.507812 22.855469 15.75 C 22.855469 16.992188 21.832031 18 20.570312 18 Z M 50.285156 49.5 L 29.714844 49.5 C 28.453125 49.5 27.429688 48.492188 27.429688 47.25 C 27.429688 46.007812 28.453125 45 29.714844 45 L 50.285156 45 C 51.546875 45 52.570312 46.007812 52.570312 47.25 C 52.570312 48.492188 51.546875 49.5 50.285156 49.5 Z M 50.285156 33.75 L 29.714844 33.75 C 28.453125 33.75 27.429688 32.742188 27.429688 31.5 C 27.429688 30.257812 28.453125 29.25 29.714844 29.25 L 50.285156 29.25 C 51.546875 29.25 52.570312 30.257812 52.570312 31.5 C 52.570312 32.742188 51.546875 33.75 50.285156 33.75 Z M 50.285156 18 L 29.714844 18 C 28.453125 18 27.429688 16.992188 27.429688 15.75 C 27.429688 14.507812 28.453125 13.5 29.714844 13.5 L 50.285156 13.5 C 51.546875 13.5 52.570312 14.507812 52.570312 15.75 C 52.570312 16.992188 51.546875 18 50.285156 18 Z M 50.285156 18 "/>
</g>
</svg>
)
export default ListIcon

View File

@ -0,0 +1,27 @@
const MoreIcon = ({
className = '',
width = '16px',
height = '16px',
viewBox = '0 0 64 64',
title = 'More',
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={width}
height={height}
viewBox={viewBox}
xmlSpace='preserve'
aria-label={title}
>
<g>
<path d="M 32 0 C 14.355 0 0 14.355 0 32 C 0 49.644 14.355 64 32 64 C 49.644 64 64 49.644 64 32 C 64 14.355 49.644 0 32 0 Z M 16.484 36.847 C 13.812 36.847 11.636 34.671 11.636 32 C 11.636 29.328 13.812 27.152 16.484 27.152 C 19.16 27.152 21.332 29.328 21.332 32 C 21.332 34.671 19.16 36.847 16.484 36.847 Z M 32 36.847 C 29.328 36.847 27.152 34.671 27.152 32 C 27.152 29.328 29.328 27.152 32 27.152 C 34.671 27.152 36.847 29.328 36.847 32 C 36.847 34.671 34.671 36.847 32 36.847 Z M 47.515 36.847 C 44.839 36.847 42.667 34.671 42.667 32 C 42.667 29.328 44.839 27.152 47.515 27.152 C 50.187 27.152 52.363 29.328 52.363 32 C 52.363 34.671 50.187 36.847 47.515 36.847 Z M 47.515 36.847" />
</g>
</svg>
)
export default MoreIcon

View File

@ -0,0 +1,27 @@
const ShopIcon = ({
className = '',
width = '26px',
height = '26px',
viewBox = '0 0 64 64',
title = 'Shop',
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={width}
height={height}
viewBox={viewBox}
xmlSpace='preserve'
aria-label={title}
>
<g>
<path d="M 49.921875 3.40625 L 30.269531 3.40625 C 29.027344 3.40625 27.832031 3.902344 26.953125 4.78125 L 1.375 30.355469 C -0.457031 32.1875 -0.457031 35.15625 1.375 36.992188 L 21.023438 56.644531 C 22.859375 58.476562 25.828125 58.476562 27.660156 56.644531 L 53.238281 31.070312 C 54.117188 30.1875 54.613281 28.992188 54.613281 27.746094 L 54.613281 8.097656 C 54.613281 5.507812 52.511719 3.40625 49.921875 3.40625 Z M 41.707031 19.832031 C 39.765625 19.832031 38.1875 18.253906 38.1875 16.3125 C 38.1875 14.371094 39.765625 12.792969 41.707031 12.792969 C 43.652344 12.792969 45.226562 14.371094 45.226562 16.3125 C 45.226562 18.253906 43.652344 19.832031 41.707031 19.832031 Z M 41.707031 19.832031" />
<path d="M 59.308594 8.097656 L 59.304688 29.945312 C 59.304688 31.023438 58.875 32.066406 58.109375 32.828125 L 32.117188 58.820312 L 32.515625 59.21875 C 34.347656 61.050781 37.320312 61.050781 39.152344 59.21875 L 62.621094 35.753906 C 63.503906 34.875 64 33.679688 64 32.4375 L 64 12.792969 C 64 10.199219 61.898438 8.097656 59.308594 8.097656 Z M 59.308594 8.097656" />
</g>
</svg>
)
export default ShopIcon

View File

@ -0,0 +1,32 @@
const TrendsIcon = ({
className = '',
width = '32px',
height = '32px',
viewBox = '0 0 80 80',
title = 'Trends',
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={width}
height={height}
viewBox={viewBox}
xmlSpace='preserve'
aria-label={title}
>
<g>
<rect x="0" y="0" width="24" height="56" rx="4" />
<rect x="0" y="60" width="24" height="20" rx="4" />
<rect x="28" y="44" width="24" height="36" rx="4" />
<rect x="28" y="16" width="24" height="24" rx="4" />
<rect x="56" y="64" width="24" height="16" rx="4" />
<rect x="56" y="30" width="24" height="30" rx="4" />
</g>
</svg>
)
export default TrendsIcon

View File

@ -1,7 +1,8 @@
import ColumnHeader from './column_header'
import Header from './header'
import Search from '../search'
import ColumnHeader from '../column_header'
import Header from '../header'
export default class PageLayout extends PureComponent {
export default class DefaultLayout extends PureComponent {
static propTypes = {
layout: PropTypes.object,
title: PropTypes.string,
@ -11,9 +12,6 @@ export default class PageLayout extends PureComponent {
render() {
const { children, title, showBackBtn, layout } = this.props
const right = layout.RIGHT || null
const headerRight = layout.HEADER_RIGHT || null
return (
<div className={[styles.default, styles.flexRow, styles.width100PC, styles.backgroundColorSubtle3].join(' ')}>
@ -27,7 +25,7 @@ export default class PageLayout extends PureComponent {
<ColumnHeader title={title} />
</div>
<div className={[styles.default, styles.width325PX].join(' ')}>
{ headerRight }
<Search />
</div>
</div>
</div>
@ -43,7 +41,7 @@ export default class PageLayout extends PureComponent {
<div className={[styles.default, styles.width325PX].join(' ')}>
<div className={styles.default}>
{right}
{layout}
</div>
</div>
</div>

View File

@ -0,0 +1,40 @@
import ColumnHeader from '../column_header'
import Header from '../header'
export default class ProfileLayout extends PureComponent {
static propTypes = {
layout: PropTypes.object,
title: PropTypes.string,
showBackBtn: PropTypes.boolean,
}
render() {
const { children } = this.props
return (
<div className={[styles.default, styles.flexRow, styles.width100PC, styles.backgroundColorSubtle3].join(' ')}>
<Header />
<main role='main' className={[styles.default, styles.flexShrink1, styles.flexGrow1, styles.borderColorSubtle2, styles.borderLeft1PX].join(' ')}>
<div className={[styles.default, styles.height350PX, styles.width100PC].join(' ')}>
<img
className={[styles.default, styles.height350PX, styles.width100PC, styles.objectFitCover].join(' ')}
src='https://gab.com/media/user/bz-5cf53d08403d4.jpeg'
/>
</div>
<div className={[styles.default, styles.width1015PX, styles.flexRow, styles.justifyContentSpaceBetween, styles.paddingLeft15PX, styles.paddingVertical15PX].join(' ')}>
<div className={[styles.default, styles.z1].join(' ')}>
{children}
</div>
</div>
</main>
</div>
)
}
}

View File

@ -1,10 +1,9 @@
import { injectIntl, defineMessages } from 'react-intl';
import classNames from 'classnames';
import Icon from '../icon';
import { injectIntl, defineMessages } from 'react-intl'
import Icon from './icon'
const messages = defineMessages({
load_more: { id: 'status.load_more', defaultMessage: 'Load more' },
});
})
export default @injectIntl
class LoadMore extends PureComponent {
@ -23,20 +22,16 @@ class LoadMore extends PureComponent {
}
handleClick = () => {
const { gap, maxId } = this.props;
this.props.onClick(gap ? maxId : undefined);
const { gap, maxId } = this.props
this.props.onClick(gap ? maxId : undefined)
}
render() {
const { disabled, visible, gap, intl } = this.props;
const btnClasses = classNames('load-more', {
'load-more--gap': gap,
});
const { disabled, visible, gap, intl } = this.props
return (
<button
className={btnClasses}
className={[styles.default].join(' ')}
disabled={disabled || !visible}
style={{ visibility: visible ? 'visible' : 'hidden' }}
onClick={this.handleClick}
@ -45,7 +40,7 @@ class LoadMore extends PureComponent {
{!gap && intl.formatMessage(messages.load_more)}
{gap && <Icon id='ellipsis-h' />}
</button>
);
)
}
}

View File

@ -1 +0,0 @@
export { default } from './load_more';

View File

@ -1,22 +0,0 @@
.load-more {
display: block;
color: $dark-text-color;
background-color: transparent;
border: 0;
margin: 0;
padding: 15px;
box-sizing: border-box;
width: 100%;
clear: both;
text-decoration: none;
@include text-sizing(14px, 400, 1.2, center);
&:hover {
background: lighten($ui-base-color, 2%);
}
&--gap {
border-bottom: 1px solid lighten($ui-base-color, 8%);
}
}

View File

@ -2,7 +2,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { is } from 'immutable';
import { defineMessages, injectIntl } from 'react-intl';
import classNames from 'classnames';
import classNames from 'classnames/bind'
import { decode } from 'blurhash';
import { autoPlayGif, displayMedia } from '../../initial_state';
import { isIOS } from '../../utils/is_mobile';
@ -117,9 +117,9 @@ class Item extends ImmutablePureComponent {
let width = 100;
let height = '100%';
let top = 'auto';
let top = '0';
let left = 'auto';
let bottom = 'auto';
let bottom = '0';
let right = 'auto';
let float = 'left';
let position = 'relative';
@ -127,9 +127,9 @@ class Item extends ImmutablePureComponent {
if (dimensions) {
width = dimensions.w;
height = dimensions.h;
top = dimensions.t || 'auto';
top = dimensions.t || '0';
right = dimensions.r || 'auto';
bottom = dimensions.b || 'auto';
bottom = dimensions.b || '0';
left = dimensions.l || 'auto';
float = dimensions.float || 'left';
position = dimensions.pos || 'relative';
@ -139,7 +139,7 @@ class Item extends ImmutablePureComponent {
if (attachment.get('type') === 'unknown') {
return (
<div className={classNames('media-gallery__item', { standalone })} key={attachment.get('id')} style={{ position, float, left, top, right, bottom, height, width: `${width}%` }}>
<div className={[styles.default].join(' ')} key={attachment.get('id')} style={{ position, float, left, top, right, bottom, height, width: `${width}%` }}>
<a className='media-gallery__item-thumbnail' href={attachment.get('remote_url')} target='_blank' style={{ cursor: 'pointer' }}>
<canvas width={32} height={32} ref={this.setCanvasRef} className='media-gallery__preview' />
</a>
@ -164,7 +164,7 @@ class Item extends ImmutablePureComponent {
thumbnail = (
<a
className={[styles.default, styles.overflowHidden].join(' ')}
className={[styles.default, styles.overflowHidden, styles.height100PC, styles.width100PC, styles.cursorPointer].join(' ')}
href={attachment.get('remote_url') || originalUrl}
onClick={this.handleClick}
target='_blank'
@ -173,6 +173,7 @@ class Item extends ImmutablePureComponent {
src={previewUrl}
srcSet={srcSet}
sizes={sizes}
className={[styles.height100PC, styles.width100PC, styles.objectFitCover].join(' ')}
alt={attachment.get('description')}
title={attachment.get('description')}
style={{ objectPosition: `${x}% ${y}%` }}
@ -511,9 +512,20 @@ class MediaGallery extends PureComponent {
);
}
const cx = classNames.bind(styles)
const containerClasses = cx({
default: 1,
displayBlock: 1,
overflowHidden: 1,
borderColorSubtle: size === 1,
borderTop1PX: size === 1,
borderBottom1PX: size === 1,
paddingHorizontal5PX: size > 1,
})
return (
<div
className={[styles.default, styles.overflowHidden, styles.borderColorSubtle, styles.borderTop1PX, styles.borderBottom1PX].join(' ')}
className={containerClasses}
style={style}
ref={this.handleRef}
>

View File

@ -185,7 +185,7 @@ class StatusContent extends ImmutablePureComponent {
</Permalink>
)).reduce((aggregate, item) => [...aggregate, item, ' '], []);
const toggleText = intl.formatMessaeg(hidden ? messages.showMore : messages.showLess);
const toggleText = intl.formatMessage(hidden ? messages.showMore : messages.showLess);
if (hidden) {
mentionsPlaceholder = <div>{mentionLinks}</div>;

View File

@ -155,6 +155,7 @@ class Notification extends ImmutablePureComponent {
</span>
</div>
{ /*
<StatusContainer
id={notification.get('status')}
account={notification.get('account')}
@ -165,7 +166,7 @@ class Notification extends ImmutablePureComponent {
updateScrollBottom={this.props.updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
/>
/> */ }
</div>
</HotKeys>
);
@ -186,7 +187,7 @@ class Notification extends ImmutablePureComponent {
<FormattedMessage id='notification.reblog' defaultMessage='{name} reposted your status' values={{ name: link }} />
</span>
</div>
{ /*
<StatusContainer
id={notification.get('status')}
account={notification.get('account')}
@ -197,7 +198,7 @@ class Notification extends ImmutablePureComponent {
updateScrollBottom={this.props.updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
/>
/> */ }
</div>
</HotKeys>
);
@ -218,7 +219,7 @@ class Notification extends ImmutablePureComponent {
<FormattedMessage id='notification.poll' defaultMessage='A poll you have voted in has ended' />
</span>
</div>
{ /*
<StatusContainer
id={notification.get('status')}
account={notification.get('account')}
@ -229,7 +230,7 @@ class Notification extends ImmutablePureComponent {
updateScrollBottom={this.props.updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
/>
/> */}
</div>
</HotKeys>
);
@ -242,16 +243,16 @@ class Notification extends ImmutablePureComponent {
const link = <bdi><Permalink className='notification__display-name' href={`/${account.get('acct')}`} title={account.get('acct')} to={`/${account.get('acct')}`} dangerouslySetInnerHTML={displayNameHtml} /></bdi>;
switch(notification.get('type')) {
case 'follow':
return this.renderFollow(notification, account, link);
case 'mention':
return this.renderMention(notification);
// case 'follow':
// return this.renderFollow(notification, account, link);
// case 'mention':
// return this.renderMention(notification);
case 'favourite':
return this.renderFavourite(notification, link);
case 'reblog':
return this.renderReblog(notification, link);
case 'poll':
return this.renderPoll(notification);
// case 'reblog':
// return this.renderReblog(notification, link);
// case 'poll':
// return this.renderPoll(notification);
}
return null;

View File

@ -10,13 +10,12 @@ import {
dequeueNotifications,
} from '../../actions/notifications';
import NotificationContainer from './containers/notification_container';
import ColumnSettingsContainer from './containers/column_settings_container';
import FilterBarContainer from './containers/filter_bar_container';
// import ColumnSettingsContainer from './containers/column_settings_container';
// import FilterBarContainer from './containers/filter_bar_container';
import ScrollableList from '../../components/scrollable_list';
import LoadMore from '../../components/load_more';
import TimelineQueueButtonHeader from '../../components/timeline_queue_button_header';
// import TimelineQueueButtonHeader from '../../components/timeline_queue_button_header';
import Column from '../../components/column';
import { ColumnHeader } from '../../components/column_header';
const messages = defineMessages({
title: { id: 'column.notifications', defaultMessage: 'Notifications' },
@ -128,9 +127,11 @@ class Notifications extends ImmutablePureComponent {
let scrollableContent = null;
const filterBarContainer = showFilterBar
? (<FilterBarContainer />)
: null;
// const filterBarContainer = showFilterBar
// ? (<FilterBarContainer />)
// : null;
console.log("notifications:", notifications)
if (isLoading && this.scrollableContent) {
scrollableContent = this.scrollableContent;
@ -169,18 +170,15 @@ class Notifications extends ImmutablePureComponent {
onScrollToTop={this.handleScrollToTop}
onScroll={this.handleScroll}
>
{scrollableContent}
{ scrollableContent }
</ScrollableList>
);
return (
<Column ref={this.setColumnRef} heading={intl.formatMessage(messages.title)}>
<ColumnHeader icon='bell' active={isUnread} title={intl.formatMessage(messages.title)}>
<ColumnSettingsContainer />
</ColumnHeader>
{filterBarContainer}
<TimelineQueueButtonHeader onClick={this.handleDequeueNotifications} count={totalQueuedNotificationsCount} itemType='notification' />
{scrollContainer}
{ /* filterBarContainer */ }
{ /* <TimelineQueueButtonHeader onClick={this.handleDequeueNotifications} count={totalQueuedNotificationsCount} itemType='notification' /> */ }
{ scrollContainer }
</Column>
);
}

View File

@ -24,18 +24,19 @@ import { isMobile } from '../../utils/is_mobile';
// import TrendsPanel from './components/trends_panel';
// import { WhoToFollowPanel } from '../../components/panel';
// import LinkFooter from '../../components/link_footer';
// import ProfilePage from '../../pages/profile_page';
import ProfilePage from '../../pages/profile_page'
// import GroupsPage from 'gabsocial/pages/groups_page';
// import GroupPage from '../../pages/group_page';
// import SearchPage from '../../pages/search_page';
import HomePage from '../../pages/home_page';
import HomePage from '../../pages/home_page'
import NotificationsPage from '../../pages/notifications_page'
// import GroupSidebarPanel from '../groups/sidebar_panel';
import {
Status,
// GettingStarted,
// CommunityTimeline,
// AccountTimeline,
AccountTimeline,
// AccountGallery,
HomeTimeline,
// Followers,
@ -44,7 +45,7 @@ import {
// Favourites,
// DirectTimeline,
// HashtagTimeline,
// Notifications,
Notifications,
// FollowRequests,
// GenericNotFound,
// FavouritedStatuses,
@ -194,9 +195,9 @@ class SwitchingColumnsArea extends PureComponent {
<WrappedRoute path='/lists' layout={LAYOUT.DEFAULT} component={Lists} content={children} />
<WrappedRoute path='/list/:id' page={HomePage} component={ListTimeline} content={children} />
<WrappedRoute path='/notifications' layout={LAYOUT.DEFAULT} component={Notifications} content={children} />
*/}
<WrappedRoute path='/notifications' layout={LAYOUT.DEFAULT} page={NotificationsPage} component={Notifications} 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/hashtags' exact page={SearchPage} component={Search} content={children} />
@ -206,10 +207,10 @@ class SwitchingColumnsArea extends PureComponent {
<WrappedRoute path='/blocks' layout={LAYOUT.DEFAULT} component={Blocks} content={children} />
<WrappedRoute path='/domain_blocks' layout={LAYOUT.DEFAULT} component={DomainBlocks} content={children} />
<WrappedRoute path='/mutes' layout={LAYOUT.DEFAULT} component={Mutes} content={children} />
*/ }
<Redirect from='/@:username' to='/:username' exact />
<WrappedRoute path='/:username' publicRoute exact component={AccountTimeline} page={ProfilePage} content={children} />
{ /*
<Redirect from='/@:username/with_replies' to='/:username/with_replies' />
<WrappedRoute path='/:username/with_replies' component={AccountTimeline} page={ProfilePage} content={children} componentParams={{ withReplies: true }} />

View File

@ -1,5 +1,5 @@
import { Route } from 'react-router-dom';
import PageLayout from '../../../components/page_layout';
import DefaultLayout from '../../../components/layouts/default_layout';
import BundleColumnError from '../../../components/bundle_column_error';
import Bundle from './bundle';
import { me } from '../../../initial_state';
@ -42,11 +42,11 @@ export default class WrappedRoute extends Component {
<Bundle fetchComponent={component} loading={this.renderLoading} error={this.renderError}>
{Component =>
(
<PageLayout layout={layout}>
<DefaultLayout layout={layout}>
<Component params={match.params} {...componentParams}>
{content}
</Component>
</PageLayout>
</DefaultLayout>
)
}
</Bundle>

View File

@ -5,7 +5,7 @@ import { fetchGroup } from '../actions/groups';
import HeaderContainer from '../features/groups/timeline/containers/header_container';
import GroupPanel from '../features/groups/timeline/components/panel';
import GroupSidebarPanel from '../features/groups/sidebar_panel';
import PageLayout from '../components/page_layout';
import DefaultLayout from '../components/default_layout';
import { WhoToFollowPanel } from '../components/panel';
import LinkFooter from '../components/link_footer';
@ -34,7 +34,7 @@ class GroupPage extends ImmutablePureComponent {
const top = group ? <HeaderContainer groupId={group.get('id')} /> : null;
return (
<PageLayout
<DefaultLayout
layout={{
TOP: top,
RIGHT: (
@ -56,7 +56,7 @@ class GroupPage extends ImmutablePureComponent {
}}
>
{children}
</PageLayout>
</DefaultLayout>
)
}
}

View File

@ -1,13 +1,10 @@
import { Fragment } from 'react'
import GroupSidebarPanel from '../components/panel/groups_panel'
import LinkFooter from '../components/link_footer'
import SignUpPanel from '../components/panel/sign_up_panel'
import WhoToFollowPanel from '../components/panel/who_to_follow_panel'
import TrendsPanel from '../components/panel/trends_panel'
import ProgressPanel from '../components/panel/progress_panel'
import UserPanel from '../components/user_panel'
import Search from '../components/search'
import PageLayout from '../components/page_layout'
import DefaultLayout from '../components/layouts/default_layout'
import TimelineComposeBlock from '../components/timeline_compose_block'
export default class HomePage extends PureComponent {
@ -15,27 +12,22 @@ export default class HomePage extends PureComponent {
const { children } = this.props
return (
<PageLayout
<DefaultLayout
title='Home'
layout={{
HEADER_RIGHT: <Search />,
RIGHT: (
<Fragment>
<UserPanel />
<WhoToFollowPanel />
<TrendsPanel />
<GroupSidebarPanel />
<SignUpPanel />
<ProgressPanel />
<LinkFooter />
</Fragment>
),
}}
layout={(
<Fragment>
<UserPanel />
<ProgressPanel />
<WhoToFollowPanel />
<GroupSidebarPanel />
<LinkFooter />
</Fragment>
)}
>
<TimelineComposeBlock autoFocus={false} shouldCondense />
<div className={[styles.default, styles.borderBottom1PX, styles.borderColorSubtle2, styles.marginBottom15PX, styles.width100PC].join(' ')} />
{children}
</PageLayout>
</DefaultLayout>
)
}
}

View File

@ -0,0 +1,26 @@
import { Fragment } from 'react'
import LinkFooter from '../components/link_footer'
import WhoToFollowPanel from '../components/panel/who_to_follow_panel'
import TrendsPanel from '../components/panel/trends_panel'
import DefaultLayout from '../components/layouts/default_layout'
export default class NotificationsPage extends PureComponent {
render() {
const { children } = this.props
return (
<DefaultLayout
title='Notifications'
layout={(
<Fragment>
<TrendsPanel />
<WhoToFollowPanel />
<LinkFooter />
</Fragment>
)}
>
{children}
</DefaultLayout>
)
}
}

View File

@ -1,11 +1,11 @@
import { Fragment } from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import HeaderContainer from '../features/account_timeline/containers/header_container';
import ProfileInfoPanel from '../features/account_timeline/components/profile_info_panel/profile_info_panel';
import { WhoToFollowPanel, SignUpPanel } from '../components/panel';
import LinkFooter from '../components/link_footer';
import PageLayout from '../components/page_layout';
// import HeaderContainer from '../features/account_timeline/containers/header_container';
// import ProfileInfoPanel from '../features/account_timeline/components/profile_info_panel/profile_info_panel';
// import { WhoToFollowPanel, SignUpPanel } from '../components/panel';
// import LinkFooter from '../components/link_footer';
import ProfileLayout from '../components/layouts/profile_layout';
const mapStateToProps = (state, { params: { username }, withReplies = false }) => {
const accounts = state.getIn(['accounts']);
@ -48,21 +48,9 @@ class ProfilePage extends ImmutablePureComponent {
const { accountId, account, accountUsername } = this.props;
return (
<PageLayout
layout={{
TOP: <HeaderContainer accountId={accountId} username={accountUsername} />,
RIGHT: (
<Fragment>
<SignUpPanel />
<WhoToFollowPanel />
<LinkFooter />
</Fragment>
),
LEFT: <ProfileInfoPanel username={accountUsername} account={account} />,
}}
>
{this.props.children}
</PageLayout>
<ProfileLayout>
{ /*this.props.children */ }
</ProfileLayout>
)
}
}

View File

@ -2,7 +2,7 @@ import { Fragment } from 'react';
import Header from '../features/search/components/header';
import LinkFooter from '../components/link_footer';
import { WhoToFollowPanel, SignUpPanel } from '../components/panel';
import PageLayout from '../components/page_layout';
import DefaultLayout from '../components/layouts/default_layout';
export default class SearchPage extends PureComponent {
@ -12,7 +12,7 @@ export default class SearchPage extends PureComponent {
render() {
return (
<PageLayout
<DefaultLayout
layout={{
TOP: <Header/>,
RIGHT: (
@ -25,7 +25,7 @@ export default class SearchPage extends PureComponent {
}}
>
{this.props.children}
</PageLayout>
</DefaultLayout>
)
}

View File

@ -13,6 +13,7 @@ body {
margin-top: 0;
margin-bottom: 0;
font-size: 15px;
overflow-wrap: break-word;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif;
}
@ -139,7 +140,7 @@ body {
.backgroundColorBrandDark_onHover:hover { background-color: #38A16B; }
.colorBlack { color: #000; }
.colorWhite { color: #fff; }
.colorSubtle { color: #666; }
.colorSubtle { color: #4B4F55; }
.colorBrand { color: #21cf7a }
.fillColorBlack { fill: #000; }
.fillColorWhite { fill: #fff; }
@ -170,6 +171,7 @@ body {
.height72PX { height: 72px; }
.height122PX { height: 122px; }
.height260PX { height: 260px; }
.height350PX { height: 350px; }
.width1015PX { width: 1015px; }
.width660PX { width: 660px; }

View File

@ -108,6 +108,7 @@
"is-nan": "^1.2.1",
"js-yaml": "^3.13.1",
"lodash": "^4.7.11",
"lodash.isobject": "^3.0.2",
"mark-loader": "^0.1.6",
"marky": "^1.2.1",
"mini-css-extract-plugin": "^0.9.0",