This commit is contained in:
mgabdev 2020-04-29 18:32:49 -04:00
parent 5efe40f301
commit 03de4c4fea
92 changed files with 1132 additions and 787 deletions

View File

@ -41,14 +41,20 @@ export function submitSearch() {
}).then(response => {
if (response.data.accounts) {
dispatch(importFetchedAccounts(response.data.accounts));
dispatch(fetchRelationships(response.data.accounts.map(item => item.id)));
}
if (response.data.statuses) {
dispatch(importFetchedStatuses(response.data.statuses));
}
console.log("response.data.", response.data)
// if (response.data.groups) {
// dispatch(importFetchedStatuses(response.data.statuses));
// }
dispatch(fetchSearchSuccess(response.data));
dispatch(fetchRelationships(response.data.accounts.map(item => item.id)));
}).catch(error => {
dispatch(fetchSearchFail(error));
});

View File

@ -1,5 +1,5 @@
const ErrorIcon = ({
className = _s.fillColorPrimary,
className = _s.fillPrimary,
size = '32px',
title = 'Error',
}) => (

View File

@ -0,0 +1,39 @@
const ExploreIcon = ({
className = '',
size = '12px',
title = 'Explore',
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={size}
height={size}
viewBox='0 0 24 24'
xmlSpace='preserve'
aria-label={title}
>
<g>
<path d='M 11.296875 23.875 L 11.296875 18.773438 C 10.019531 18.824219 8.753906 19.003906 7.550781 19.300781 C 7.742188 19.769531 7.957031 20.21875 8.183594 20.640625 C 9.101562 22.332031 10.242188 23.5 11.296875 23.875 Z M 11.296875 23.875' />
<path d='M 15.8125 20.640625 C 16.042969 20.21875 16.257812 19.769531 16.449219 19.300781 C 15.246094 19.003906 13.980469 18.824219 12.703125 18.773438 L 12.703125 23.875 C 13.757812 23.5 14.898438 22.332031 15.8125 20.640625 Z M 15.8125 20.640625' />
<path d='M 11.296875 17.367188 L 11.296875 12.6875 L 6.167969 12.6875 C 6.234375 14.515625 6.546875 16.332031 7.066406 17.976562 C 8.425781 17.625 9.855469 17.417969 11.296875 17.367188 Z M 11.296875 17.367188' />
<path d='M 11.296875 11.28125 L 11.296875 6.601562 C 9.855469 6.550781 8.425781 6.34375 7.066406 5.996094 C 6.546875 7.640625 6.234375 9.457031 6.167969 11.28125 Z M 11.296875 11.28125' />
<path d='M 17.808594 4.273438 C 18.664062 3.984375 19.476562 3.632812 20.222656 3.222656 C 18.914062 1.996094 17.328125 1.054688 15.574219 0.507812 C 16.097656 1.101562 16.597656 1.820312 17.050781 2.65625 C 17.328125 3.167969 17.582031 3.710938 17.808594 4.273438 Z M 17.808594 4.273438' />
<path d='M 8.1875 3.328125 C 7.957031 3.75 7.742188 4.199219 7.550781 4.667969 C 8.753906 4.96875 10.019531 5.148438 11.296875 5.195312 L 11.296875 0.09375 C 10.242188 0.46875 9.101562 1.636719 8.1875 3.328125 Z M 8.1875 3.328125' />
<path d='M 12.703125 12.6875 L 12.703125 17.367188 C 14.144531 17.417969 15.574219 17.625 16.933594 17.976562 C 17.453125 16.332031 17.765625 14.515625 17.832031 12.6875 Z M 12.703125 12.6875' />
<path d='M 12.703125 6.601562 L 12.703125 11.28125 L 17.832031 11.28125 C 17.765625 9.457031 17.453125 7.640625 16.933594 5.996094 C 15.574219 6.34375 14.144531 6.550781 12.703125 6.601562 Z M 12.703125 6.601562' />
<path d='M 5.714844 18.375 C 5.152344 16.605469 4.824219 14.667969 4.761719 12.6875 L 0 12.6875 C 0.152344 15.34375 1.175781 17.773438 2.78125 19.691406 C 3.679688 19.171875 4.667969 18.730469 5.714844 18.375 Z M 5.714844 18.375' />
<path d='M 17.808594 19.699219 C 17.582031 20.261719 17.328125 20.800781 17.050781 21.3125 C 16.597656 22.148438 16.097656 22.871094 15.574219 23.464844 C 17.328125 22.914062 18.914062 21.976562 20.222656 20.746094 C 19.476562 20.335938 18.664062 19.988281 17.808594 19.699219 Z M 17.808594 19.699219' />
<path d='M 6.191406 19.699219 C 5.335938 19.988281 4.523438 20.335938 3.777344 20.746094 C 5.085938 21.976562 6.671875 22.914062 8.425781 23.464844 C 7.902344 22.871094 7.402344 22.148438 6.949219 21.3125 C 6.671875 20.800781 6.417969 20.261719 6.191406 19.699219 Z M 6.191406 19.699219' />
<path d='M 18.285156 5.59375 C 18.847656 7.363281 19.175781 9.300781 19.238281 11.28125 L 24 11.28125 C 23.847656 8.625 22.824219 6.199219 21.21875 4.277344 C 20.320312 4.796875 19.332031 5.238281 18.285156 5.59375 Z M 18.285156 5.59375' />
<path d='M 18.285156 18.375 C 19.332031 18.730469 20.320312 19.171875 21.21875 19.691406 C 22.824219 17.773438 23.847656 15.34375 24 12.6875 L 19.238281 12.6875 C 19.175781 14.667969 18.847656 16.605469 18.285156 18.375 Z M 18.285156 18.375' />
<path d='M 12.703125 0.09375 L 12.703125 5.195312 C 13.980469 5.148438 15.246094 4.96875 16.449219 4.667969 C 16.257812 4.199219 16.042969 3.75 15.8125 3.328125 C 14.898438 1.636719 13.757812 0.46875 12.703125 0.09375 Z M 12.703125 0.09375' />
<path d='M 5.714844 5.59375 C 4.667969 5.238281 3.679688 4.796875 2.78125 4.277344 C 1.175781 6.199219 0.152344 8.625 0 11.28125 L 4.761719 11.28125 C 4.824219 9.300781 5.152344 7.363281 5.714844 5.59375 Z M 5.714844 5.59375' />
<path d='M 6.191406 4.273438 C 6.417969 3.710938 6.671875 3.167969 6.949219 2.65625 C 7.402344 1.820312 7.902344 1.101562 8.425781 0.507812 C 6.671875 1.054688 5.085938 1.996094 3.777344 3.222656 C 4.523438 3.632812 5.335938 3.984375 6.191406 4.273438 Z M 6.191406 4.273438' />
</g>
</svg>
)
export default ExploreIcon

View File

@ -1,6 +1,5 @@
const GabLogo = ({
className = _s.fillColorBrand,
size = '50px',
className = _s.fillBrand,
}) => (
<svg
className={className}
@ -8,8 +7,8 @@ const GabLogo = ({
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={size}
height={size}
width='50px'
height='30px'
viewBox='0 0 50 30'
xmlSpace='preserve'
>

View File

@ -1,4 +1,3 @@
// : todo : fill, stroke colors
const GlobeIcon = ({
className = '',
size = '12px',

View File

@ -13,7 +13,7 @@ const LoadingIcon = ({
>
<g transform='translate(82,50)'>
<g transform='rotate(0)'>
<circle cx='0' cy='0' r='6' className={_s.fillColorSecondary} fillOpacity='1' transform='scale(1.03405 1.03405)'>
<circle cx='0' cy='0' r='6' className={_s.fillSecondary} fillOpacity='1' transform='scale(1.03405 1.03405)'>
<animateTransform attributeName='transform' type='scale' begin='-1.0294117647058822s' values='1.5 1.5;1 1' keyTimes='0;1' dur='1.176470588235294s' repeatCount='indefinite'></animateTransform>
<animate attributeName='fill-opacity' keyTimes='0;1' dur='1.176470588235294s' repeatCount='indefinite' values='1;0' begin='-1.0294117647058822s'></animate>
</circle>
@ -21,7 +21,7 @@ const LoadingIcon = ({
</g>
<g transform='translate(72.62741699796952,72.62741699796952)'>
<g transform='rotate(45)'>
<circle cx='0' cy='0' r='6' className={_s.fillColorSecondary} fillOpacity='0.875' transform='scale(1.09655 1.09655)'>
<circle cx='0' cy='0' r='6' className={_s.fillSecondary} fillOpacity='0.875' transform='scale(1.09655 1.09655)'>
<animateTransform attributeName='transform' type='scale' begin='-0.8823529411764705s' values='1.5 1.5;1 1' keyTimes='0;1' dur='1.176470588235294s' repeatCount='indefinite'></animateTransform>
<animate attributeName='fill-opacity' keyTimes='0;1' dur='1.176470588235294s' repeatCount='indefinite' values='1;0' begin='-0.8823529411764705s'></animate>
</circle>
@ -29,7 +29,7 @@ const LoadingIcon = ({
</g>
<g transform='translate(50,82)'>
<g transform='rotate(90)'>
<circle cx='0' cy='0' r='6' className={_s.fillColorSecondary} fillOpacity='0.75' transform='scale(1.15905 1.15905)'>
<circle cx='0' cy='0' r='6' className={_s.fillSecondary} fillOpacity='0.75' transform='scale(1.15905 1.15905)'>
<animateTransform attributeName='transform' type='scale' begin='-0.7352941176470588s' values='1.5 1.5;1 1' keyTimes='0;1' dur='1.176470588235294s' repeatCount='indefinite'></animateTransform>
<animate attributeName='fill-opacity' keyTimes='0;1' dur='1.176470588235294s' repeatCount='indefinite' values='1;0' begin='-0.7352941176470588s'></animate>
</circle>
@ -37,7 +37,7 @@ const LoadingIcon = ({
</g>
<g transform='translate(27.37258300203048,72.62741699796952)'>
<g transform='rotate(135)'>
<circle cx='0' cy='0' r='6' className={_s.fillColorSecondary} fillOpacity='0.625' transform='scale(1.22155 1.22155)'>
<circle cx='0' cy='0' r='6' className={_s.fillSecondary} fillOpacity='0.625' transform='scale(1.22155 1.22155)'>
<animateTransform attributeName='transform' type='scale' begin='-0.588235294117647s' values='1.5 1.5;1 1' keyTimes='0;1' dur='1.176470588235294s' repeatCount='indefinite'></animateTransform>
<animate attributeName='fill-opacity' keyTimes='0;1' dur='1.176470588235294s' repeatCount='indefinite' values='1;0' begin='-0.588235294117647s'></animate>
</circle>
@ -45,7 +45,7 @@ const LoadingIcon = ({
</g>
<g transform='translate(18,50)'>
<g transform='rotate(180)'>
<circle cx='0' cy='0' r='6' className={_s.fillColorSecondary} fillOpacity='0.5' transform='scale(1.28405 1.28405)'>
<circle cx='0' cy='0' r='6' className={_s.fillSecondary} fillOpacity='0.5' transform='scale(1.28405 1.28405)'>
<animateTransform attributeName='transform' type='scale' begin='-0.4411764705882352s' values='1.5 1.5;1 1' keyTimes='0;1' dur='1.176470588235294s' repeatCount='indefinite'></animateTransform>
<animate attributeName='fill-opacity' keyTimes='0;1' dur='1.176470588235294s' repeatCount='indefinite' values='1;0' begin='-0.4411764705882352s'></animate>
</circle>
@ -53,7 +53,7 @@ const LoadingIcon = ({
</g>
<g transform='translate(27.372583002030474,27.37258300203048)'>
<g transform='rotate(225)'>
<circle cx='0' cy='0' r='6' className={_s.fillColorSecondary} fillOpacity='0.375' transform='scale(1.34655 1.34655)'>
<circle cx='0' cy='0' r='6' className={_s.fillSecondary} fillOpacity='0.375' transform='scale(1.34655 1.34655)'>
<animateTransform attributeName='transform' type='scale' begin='-0.2941176470588235s' values='1.5 1.5;1 1' keyTimes='0;1' dur='1.176470588235294s' repeatCount='indefinite'></animateTransform>
<animate attributeName='fill-opacity' keyTimes='0;1' dur='1.176470588235294s' repeatCount='indefinite' values='1;0' begin='-0.2941176470588235s'></animate>
</circle>
@ -61,7 +61,7 @@ const LoadingIcon = ({
</g>
<g transform='translate(50,18)'>
<g transform='rotate(270)'>
<circle cx='0' cy='0' r='6' className={_s.fillColorSecondary} fillOpacity='0.25' transform='scale(1.40905 1.40905)'>
<circle cx='0' cy='0' r='6' className={_s.fillSecondary} fillOpacity='0.25' transform='scale(1.40905 1.40905)'>
<animateTransform attributeName='transform' type='scale' begin='-0.14705882352941174s' values='1.5 1.5;1 1' keyTimes='0;1' dur='1.176470588235294s' repeatCount='indefinite'></animateTransform>
<animate attributeName='fill-opacity' keyTimes='0;1' dur='1.176470588235294s' repeatCount='indefinite' values='1;0' begin='-0.14705882352941174s'></animate>
</circle>
@ -69,7 +69,7 @@ const LoadingIcon = ({
</g>
<g transform='translate(72.62741699796952,27.372583002030474)'>
<g transform='rotate(315)'>
<circle cx='0' cy='0' r='6' className={_s.fillColorSecondary} fillOpacity='0.125' transform='scale(1.47155 1.47155)'>
<circle cx='0' cy='0' r='6' className={_s.fillSecondary} fillOpacity='0.125' transform='scale(1.47155 1.47155)'>
<animateTransform attributeName='transform' type='scale' begin='0s' values='1.5 1.5;1 1' keyTimes='0;1' dur='1.176470588235294s' repeatCount='indefinite'></animateTransform>
<animate attributeName='fill-opacity' keyTimes='0;1' dur='1.176470588235294s' repeatCount='indefinite' values='1;0' begin='0s'></animate>
</circle>

View File

@ -115,6 +115,7 @@ class Account extends ImmutablePureComponent {
expanded,
dismissAction,
showDismiss,
withBio,
} = this.props
if (!account) return null
@ -148,13 +149,15 @@ class Account extends ImmutablePureComponent {
onClick={dismissAction}
icon='close'
iconSize='8px'
iconClassName={_s.fillColorSecondary}
iconClassName={_s.fillSecondary}
/>
)
const content = { __html: account.get('note_emojified') }
return (
<div className={[_s.default, _s.px15, _s.py5, _s.backgroundColorSubtle_onHover, _s.mb5].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter].join(' ')}>
<div className={[_s.default, _s.px15, _s.py10, _s.borderBottom1PX, _s.borderColorSecondary, _s.bgSubtle_onHover].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.alignItemsStart].join(' ')}>
<NavLink
className={[_s.default, _s.noUnderline].join(' ')}
@ -164,10 +167,12 @@ class Account extends ImmutablePureComponent {
<Avatar account={account} size={avatarSize} />
</NavLink>
<div className={[_s.default, _s.px10, _s.overflowHidden, _s.flexNormal].join(' ')}>
<div className={[_s.default, _s.flexRow].join(' ')}>
<NavLink
title={account.get('acct')}
to={`/${account.get('acct')}`}
className={[_s.default, _s.alignItemsStart, _s.noUnderline, _s.px10, _s.overflowHidden, _s.flexNormal].join(' ')}
className={[_s.default, _s.alignItemsStart, _s.noUnderline, _s.overflowHidden, _s.flexNormal].join(' ')}
>
<DisplayName account={account} isMultiline={compact} />
{!compact && actionButton}
@ -177,7 +182,13 @@ class Account extends ImmutablePureComponent {
{dismissBtn}
{compact && actionButton}
</div>
</div>
{
withBio &&
<div className={[_s.py5, _s.dangerousContent].join(' ')} dangerouslySetInnerHTML={content} />
}
</div>
</div>
</div>
)

View File

@ -233,12 +233,12 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
text: 1,
displayBlock: 1,
outlineNone: 1,
backgroundColorPrimary: !small,
backgroundColorSubtle: small,
bgPrimary: !small,
bgSubtle: small,
py15: !small,
py10: small,
fontSize16PX: !small,
fontSize14PX: small,
fs16PX: !small,
fs14PX: small,
mr5: small,
})

View File

@ -11,7 +11,7 @@ export default class Block extends PureComponent {
const { children } = this.props
return (
<div className={[_s.default, _s.boxShadowBlock, _s.backgroundColorPrimary, _s.overflowHidden, _s.radiusSmall].join(' ')}>
<div className={[_s.default, _s.boxShadowBlock, _s.bgPrimary, _s.overflowHidden, _s.radiusSmall].join(' ')}>
{children}
</div>
)

View File

@ -37,6 +37,8 @@ const COLORS = {
* @param {func} [props.onMouseEnter] - function to call on button mouse enter
* @param {func} [props.onMouseLeave] - function to call on button mouse leave
* @param {bool} [props.radiusSmall] - if the button has small radius
* @param {bool} [props.rel] - rel for the button
* @param {bool} [props.target] - target for the button
* @param {bool} [props.text] - if the button is just text (i.e. link)
* @param {bool} [props.title] - `title` attribute for button
* @param {bool} [props.to] - `to` to send to on click
@ -68,6 +70,8 @@ export default class Button extends PureComponent {
onMouseLeave: PropTypes.func,
isOutline: PropTypes.bool,
radiusSmall: PropTypes.bool,
rel: PropTypes.string,
target: PropTypes.string,
title: PropTypes.string,
to: PropTypes.string,
type: PropTypes.string,
@ -118,6 +122,8 @@ export default class Button extends PureComponent {
onMouseEnter,
onMouseLeave,
radiusSmall,
rel,
target,
title,
to,
type,
@ -136,13 +142,13 @@ export default class Button extends PureComponent {
cursorNotAllowed: isDisabled,
opacity05: isDisabled,
backgroundColorPrimary: backgroundColor === COLORS.white,
backgroundColorBlack: backgroundColor === COLORS.black,
backgroundColorBrand: backgroundColor === COLORS.brand,
backgroundTransparent: backgroundColor === COLORS.none,
backgroundColorSubtle2: backgroundColor === COLORS.tertiary,
backgroundColorSubtle: backgroundColor === COLORS.secondary,
backgroundColorDanger: backgroundColor === COLORS.danger,
bgPrimary: backgroundColor === COLORS.white,
bgBlack: backgroundColor === COLORS.black,
bgBrand: backgroundColor === COLORS.brand,
bgTransparent: backgroundColor === COLORS.none,
bgSecondary: backgroundColor === COLORS.tertiary,
bgSubtle: backgroundColor === COLORS.secondary,
bgDanger: backgroundColor === COLORS.danger,
colorPrimary: !!children && color === COLORS.primary,
colorSecondary: !!children && color === COLORS.secondary,
@ -164,18 +170,18 @@ export default class Button extends PureComponent {
underline_onHover: underlineOnHover,
backgroundColorSubtle2Dark_onHover: backgroundColor === COLORS.tertiary || backgroundColor === COLORS.secondary && !isDisabled,
backgroundColorBlackOpaque_onHover: backgroundColor === COLORS.black && !isDisabled,
backgroundColorBrandDark_onHover: backgroundColor === COLORS.brand && !isDisabled,
backgroundColorDangerDark_onHover: backgroundColor === COLORS.danger && !isDisabled,
bgSecondaryDark_onHover: backgroundColor === COLORS.tertiary || backgroundColor === COLORS.secondary && !isDisabled,
bgBlackOpaque_onHover: backgroundColor === COLORS.black && !isDisabled,
bgBrandDark_onHover: backgroundColor === COLORS.brand && !isDisabled,
bgDangerDark_onHover: backgroundColor === COLORS.danger && !isDisabled,
backgroundColorBrand_onHover: color === COLORS.brand && isOutline && !isDisabled,
bgBrand_onHover: color === COLORS.brand && isOutline && !isDisabled,
colorWhite_onHover: !!children && color === COLORS.brand && isOutline && !isDisabled,
fillColorSecondary: !!icon && color === COLORS.secondary,
fillColorWhite: !!icon && color === COLORS.white,
fillColorBrand: !!icon && color === COLORS.brand,
fillColorWhite_onHover: !!icon && color === COLORS.brand && isOutline,
fillSecondary: !!icon && color === COLORS.secondary,
fillWhite: !!icon && color === COLORS.white,
fillBrand: !!icon && color === COLORS.brand,
fillWhite_onHover: !!icon && color === COLORS.brand && isOutline,
})
const tagName = !!href ? 'a' : !!to ? 'NavLink' : 'button'
@ -216,6 +222,8 @@ export default class Button extends PureComponent {
}
const options = {
rel,
target,
title,
type,
disabled: isDisabled,

View File

@ -45,14 +45,14 @@ export default class ColumnHeader extends PureComponent {
className={[_s.alignItemsCenter, _s.pl0, _s.justifyContentCenter].join(' ')}
icon='back'
iconSize='20px'
iconClassName={[_s.mr5, _s.fillColorPrimary].join(' ')}
iconClassName={[_s.mr5, _s.fillPrimary].join(' ')}
onClick={this.handleBackClick}
/>
}
<div className={[_s.default, _s.height100PC, _s.justifyContentCenter, _s.mr10].join(' ')}>
<Heading size='h1'>
{title}
</Heading>
</div>
@ -63,7 +63,7 @@ export default class ColumnHeader extends PureComponent {
{
!!actions &&
<div className={[_s.default, _s.backgroundTransparent, _s.flexRow, _s.alignItemsCenter, _s.justifyContentCenter, _s.mlAuto].join(' ')}>
<div className={[_s.default, _s.bgTransparent, _s.flexRow, _s.alignItemsCenter, _s.justifyContentCenter, _s.mlAuto].join(' ')}>
{
actions.map((action, i) => (
<Button

View File

@ -61,7 +61,7 @@ class Comment extends ImmutablePureComponent {
</NavLink>
<div className={[_s.default, _s.flexNormal].join(' ')}>
<div className={[_s.default, _s.px10, _s.pt5, _s.pb10, _s.radiusSmall, _s.backgroundColorSubtle].join(' ')}>
<div className={[_s.default, _s.px10, _s.pt5, _s.pb10, _s.radiusSmall, _s.bgSubtle].join(' ')}>
<CommentHeader status={status} />
<StatusContent
status={status}
@ -103,7 +103,7 @@ class CommentButton extends PureComponent {
radiusSmall
backgroundColor='none'
color='tertiary'
className={[_s.px5, _s.backgroundColorSubtle_onHover, _s.py2, _s.mr5].join(' ')}
className={[_s.px5, _s.bgSubtle_onHover, _s.py2, _s.mr5].join(' ')}
onClick={onClick}
>
<Text size='extraSmall' color='inherit' weight='bold'>

View File

@ -183,8 +183,8 @@ class Composer extends PureComponent {
default: 1,
cursorText: 1,
text: 1,
fontSize16PX: !small,
fontSize14PX: small,
fs16PX: !small,
fs14PX: small,
pt15: !small,
px15: !small,
px10: small,

View File

@ -98,9 +98,9 @@ class DisplayName extends ImmutablePureComponent {
colorPrimary: 1,
mr2: 1,
lineHeight125: !isSmall,
fontSize14PX: isSmall,
fontSize15PX: !isLarge,
fontSize24PX: isLarge && !isSmall,
fs14PX: isSmall,
fs15PX: !isLarge,
fs24PX: isLarge && !isSmall,
})
const usernameClasses = CX({
@ -115,9 +115,9 @@ class DisplayName extends ImmutablePureComponent {
lineHeight15: isMultiline,
lineHeight125: !isMultiline,
ml5: !isMultiline,
fontSize14PX: isSmall,
fontSize15PX: !isLarge,
fontSize16PX: isLarge && !isSmall,
fs14PX: isSmall,
fs15PX: !isLarge,
fs16PX: isLarge && !isSmall,
})
const iconSize =
@ -161,7 +161,7 @@ class DisplayName extends ImmutablePureComponent {
/>
{
!noRelationship && account.get('locked') &&
<Icon id='lock-filled' size={iconSize} className={[_s.fillColorPrimary, _s.ml5].join(' ')} />
<Icon id='lock-filled' size={iconSize} className={[_s.fillPrimary, _s.ml5].join(' ')} />
}
</bdi>
{
@ -180,7 +180,7 @@ class DisplayName extends ImmutablePureComponent {
size='extraSmall'
isBadge
color='tertiary'
className={[_s.backgroundColorSubtle2, _s.py2].join(' ')}
className={[_s.bgSecondary, _s.py2].join(' ')}
>
{relationshipLabel}
</Text>

View File

@ -86,8 +86,8 @@ class GroupCollectionItem extends ImmutablePureComponent {
mb10: 1,
ml5: 1,
mr5: 1,
backgroundColorPrimary: 1,
backgroundColorSubtle_onHover: isMember,
bgPrimary: 1,
bgSubtle_onHover: isMember,
})
return (
@ -107,7 +107,7 @@ class GroupCollectionItem extends ImmutablePureComponent {
{
(!coverSrc || coverMissing) && (isMember || isAdmin) &&
<div className={[_s.default, _s.height40PX, _s.backgroundColorSubtle, _s.borderColorSecondary, _s.borderBottom1PX].join(' ')} />
<div className={[_s.default, _s.height40PX, _s.bgSubtle, _s.borderColorSecondary, _s.borderBottom1PX].join(' ')} />
}
{
@ -117,7 +117,7 @@ class GroupCollectionItem extends ImmutablePureComponent {
isMember &&
<Text
isBadge
className={_s.backgroundColorWhite}
className={_s.bgWhite}
size='extraSmall'
color='brand'
>
@ -128,7 +128,7 @@ class GroupCollectionItem extends ImmutablePureComponent {
isAdmin &&
<Text
isBadge
className={[_s.backgroundColorBlack, _s.ml5].join(' ')}
className={[_s.bgBlack, _s.ml5].join(' ')}
size='extraSmall'
color='white'
>

View File

@ -3,7 +3,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component'
import { Fragment } from 'react'
import { NavLink } from 'react-router-dom'
import { defineMessages, injectIntl } from 'react-intl'
import classNames from 'classnames/bind'
import { CX } from '../constants'
import { PLACEHOLDER_MISSING_HEADER_SRC } from '../constants'
import { shortNumberFormat } from '../utils/numbers'
import Image from './image'
@ -17,11 +17,9 @@ const messages = defineMessages({
const mapStateToProps = (state, { id }) => ({
group: state.getIn(['groups', id]),
relationships: state.getIn(['group_relationships', id]),
relatioships: state.getIn(['group_relationships', id]),
})
const cx = classNames.bind(_s)
export default
@connect(mapStateToProps)
@injectIntl
@ -50,17 +48,21 @@ class GroupListItem extends ImmutablePureComponent {
isHidden,
} = this.props
if (!relationships || !group) return null
if (!group) return null
const unreadCount = relationships.get('unread_count')
let unreadCount, subtitle
const subtitle = unreadCount > 0 ? (
if (relationships) {
unreadCount = relationships.get('unread_count')
subtitle = unreadCount > 0 ? (
<Fragment>
{shortNumberFormat(unreadCount)}
&nbsp;
{intl.formatMessage(messages.new_statuses)}
</Fragment>
) : intl.formatMessage(messages.no_recent_activity)
}
if (isHidden) {
return (
@ -71,22 +73,21 @@ class GroupListItem extends ImmutablePureComponent {
)
}
const containerClasses = cx({
const containerClasses = CX({
default: 1,
noUnderline: 1,
overflowHidden: 1,
backgroundColorSubtle_onHover: 1,
bgSubtle_onHover: 1,
borderColorSecondary: 1,
radiusSmall: !slim,
mt5: !slim,
mb10: !slim,
mb10: !slim && !isLast,
border1PX: !slim,
borderBottom1PX: slim && !isLast,
flexRow: slim,
py5: slim,
})
const imageClasses = cx({
const imageClasses = CX({
height122PX: !slim,
radiusSmall: slim,
height72PX: slim,
@ -94,7 +95,7 @@ class GroupListItem extends ImmutablePureComponent {
ml15: slim,
})
const textContainerClasses = cx({
const textContainerClasses = CX({
default: 1,
px10: 1,
mt5: 1,
@ -134,9 +135,12 @@ class GroupListItem extends ImmutablePureComponent {
</Text>
}
{
subtitle &&
<Text color='secondary' size='small' className={_s.mt5}>
{subtitle}
</Text>
}
</div>
</NavLink>

View File

@ -24,12 +24,12 @@ export default class HashtagItem extends ImmutablePureComponent {
return (
<NavLink
to={`/tags/${hashtag.get('name')}`}
className={[_s.default, _s.noUnderline, _s.backgroundColorSubtle_onHover, _s.px15, _s.py5].join(' ')}
className={[_s.default, _s.noUnderline, _s.bgSubtle_onHover, _s.px15, _s.py5].join(' ')}
>
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter].join(' ')}>
<div>
<Text color='brand' size='medium' weight='bold' className={[_s.py2, _s.lineHeight15].join(' ')}>
{hashtag.get('name')}
#{hashtag.get('name')}
</Text>
</div>
{
@ -41,7 +41,7 @@ export default class HashtagItem extends ImmutablePureComponent {
title='Remove'
icon='close'
iconSize='8px'
iconClassName={_s.fillColorSecondary}
iconClassName={_s.fillSecondary}
className={_s.mlAuto}
/>
}

View File

@ -42,11 +42,11 @@ export default class Heading extends PureComponent {
colorPrimary: [SIZES.h1, SIZES.h2].indexOf(size) > -1,
colorSecondary: [SIZES.h3, SIZES.h4, SIZES.h5].indexOf(size) > -1,
fontSize24PX: size === SIZES.h1,
fontSize19PX: size === SIZES.h2,
fontSize16PX: size === SIZES.h3,
fontSize13PX: size === SIZES.h4,
fontSize12PX: size === SIZES.h5,
fs24PX: size === SIZES.h1,
fs19PX: size === SIZES.h2,
fs16PX: size === SIZES.h3,
fs13PX: size === SIZES.h4,
fs12PX: size === SIZES.h5,
mt5: [SIZES.h4].indexOf(size) > -1,

View File

@ -19,6 +19,7 @@ import DonorIcon from '../assets/donor_icon'
import EllipsisIcon from '../assets/ellipsis_icon'
import EmailIcon from '../assets/email_icon'
import ErrorIcon from '../assets/error_icon'
import ExploreIcon from '../assets/explore_icon'
import FullscreenIcon from '../assets/fullscreen_icon'
import GabLogoIcon from '../assets/gab_logo'
import GifIcon from '../assets/gif_icon'
@ -89,6 +90,7 @@ const ICONS = {
'ellipsis': EllipsisIcon,
'email': EmailIcon,
'error': ErrorIcon,
'explore': ExploreIcon,
'fullscreen': FullscreenIcon,
'gab-logo': GabLogoIcon,
'gif': GifIcon,

View File

@ -50,7 +50,7 @@ export default class Image extends PureComponent {
const classes = cx(className, {
default: 1,
objectFitCover: !!src && fit === 'cover',
backgroundColorSubtle2: 1,
bgSecondary: 1,
})
//If error and not our own image

View File

@ -58,12 +58,12 @@ export default class Input extends PureComponent {
displayBlock: 1,
py10: !small,
py5: small,
backgroundTransparent: !readOnly,
backgroundColorSubtle2: readOnly,
bgTransparent: !readOnly,
bgSecondary: readOnly,
colorPrimary: !readOnly,
colorSecondary: readOnly,
fontSize15PX: !small,
fontSize13PX: small,
fs15PX: !small,
fs13PX: small,
flexGrow1: 1,
circle: 1,
px5: !!prependIcon,
@ -87,10 +87,10 @@ export default class Input extends PureComponent {
</Text>
</div>
}
<div className={[_s.default, _s.backgroundColorPrimary, _s.border1PX, _s.borderColorSecondary, _s.flexRow, _s.circle, _s.alignItemsCenter].join(' ')}>
<div className={[_s.default, _s.bgPrimary, _s.border1PX, _s.borderColorSecondary, _s.flexRow, _s.circle, _s.alignItemsCenter].join(' ')}>
{
!!prependIcon &&
<Icon id={prependIcon} size='16px' className={[_s.fillColorPrimary, _s.ml15, _s.mr5].join(' ')} />
<Icon id={prependIcon} size='16px' className={[_s.fillPrimary, _s.ml15, _s.mr5].join(' ')} />
}
{

View File

@ -56,7 +56,7 @@ export default class ListItem extends PureComponent {
flexRow: 1,
alignItemsCenter: 1,
width100PC: 1,
backgroundColorSubtle_onHover: 1,
bgSubtle_onHover: 1,
borderColorSecondary: !isLast,
borderBottom1PX: !isLast,
})
@ -64,7 +64,7 @@ export default class ListItem extends PureComponent {
const iconClasses = cx({
mr10: !large,
mr15: large,
fillColorPrimary: 1,
fillPrimary: 1,
})
const textSize = small ? 'small' : large ? 'medium' : 'normal'
@ -97,7 +97,7 @@ export default class ListItem extends PureComponent {
<Icon
id='angle-right'
size='10px'
className={[_s.mlAuto, _s.fillColorSecondary, _s.flexShrink1].join(' ')}
className={[_s.mlAuto, _s.fillSecondary, _s.flexShrink1].join(' ')}
/>
}
</Button>

View File

@ -216,7 +216,7 @@ class Item extends ImmutablePureComponent {
playsInline
/>
<div className={[_s.default, _s.posAbs, _s.z2, _s.radiusSmall, _s.backgroundColorBlackOpaque, _s.px5, _s.py5, _s.mr10, _s.mb10, _s.bottom0, _s.right0].join(' ')}>
<div className={[_s.default, _s.posAbs, _s.z2, _s.radiusSmall, _s.bgBlackOpaque, _s.px5, _s.py5, _s.mr10, _s.mb10, _s.bottom0, _s.right0].join(' ')}>
<Text size='extraSmall' color='white' weight='medium'>GIF</Text>
</div>
</div>
@ -574,7 +574,7 @@ class MediaGallery extends PureComponent {
title={intl.formatMessage(messages.toggle_visible)}
icon='hidden'
backgroundColor='none'
className={[_s.px10, _s.backgroundColorBlackOpaque_onHover].join(' ')}
className={[_s.px10, _s.bgBlackOpaque_onHover].join(' ')}
onClick={this.handleOpen}
/>
</div>

View File

@ -137,13 +137,13 @@ export default class MediaItem extends ImmutablePureComponent {
<Icon
id='hidden'
size='22px'
className={[_s.fillColorWhite].join('')}
className={[_s.fillWhite].join('')}
/>
}
{
!!badge &&
<div className={[_s.default, _s.posAbs, _s.radiusSmall, _s.backgroundColorBlackOpaque, _s.px5, _s.py5, _s.mr5, _s.mt5, _s.mb5, _s.bottom0, _s.right0].join(' ')}>
<div className={[_s.default, _s.posAbs, _s.radiusSmall, _s.bgBlackOpaque, _s.px5, _s.py5, _s.mr5, _s.mt5, _s.mb5, _s.bottom0, _s.right0].join(' ')}>
<Text size='extraSmall' color='white'>
{badge}
</Text>

View File

@ -89,7 +89,7 @@ class EmbedModal extends ImmutablePureComponent {
{intl.formatMessage(messages.preview)}
</Text>
<div className={[_s.default, _s.width100PC, _s.backgroundColorSubtle, _s.height220PX, _s.alignItemsCenter, _s.justifyContentCenter].join(' ')}>
<div className={[_s.default, _s.width100PC, _s.bgSubtle, _s.height220PX, _s.alignItemsCenter, _s.justifyContentCenter].join(' ')}>
<iframe
className={[_s.default, _s.width100PC, _s.height100PC, _s.z2].join(' ')}
frameBorder='0'

View File

@ -45,7 +45,7 @@ class HomeTimelineSettingsModal extends ImmutablePureComponent {
icon='pro'
href='https://pro.gab.com'
className={_s.justifyContentCenter}
iconClassName={[_s.mr5, _s.fillColorWhite].join(' ')}
iconClassName={[_s.mr5, _s.fillWhite].join(' ')}
>
<Text color='inherit' weight='bold' align='center'>
{intl.formatMessage(messages.title)}

View File

@ -137,7 +137,7 @@ class ModalBase extends PureComponent {
<Fragment>
<div
role='presentation'
className={[_s.default, _s.backgroundColorBlackOpaque, _s.posFixed, _s.z3, _s.top0, _s.right0, _s.bottom0, _s.left0].join(' ')}
className={[_s.default, _s.bgBlackOpaque, _s.posFixed, _s.z3, _s.top0, _s.right0, _s.bottom0, _s.left0].join(' ')}
/>
<div
ref={this.setDialog}

View File

@ -50,7 +50,7 @@ class ProUpgradeModal extends ImmutablePureComponent {
icon='pro'
href='https://pro.gab.com'
className={_s.justifyContentCenter}
iconClassName={[_s.mr5, _s.fillColorWhite].join(' ')}
iconClassName={[_s.mr5, _s.fillWhite].join(' ')}
>
<Text color='inherit' weight='bold' align='center'>
{intl.formatMessage(messages.title)}

View File

@ -5,8 +5,9 @@ import { BREAKPOINT_EXTRA_SMALL } from '../constants'
import { me } from '../initial_state'
import { makeGetAccount } from '../selectors'
import Responsive from '../features/ui/util/responsive_component'
import ColumnHeader from './column_header'
import { CX } from '../constants'
import Search from './search'
import Avatar from './avatar'
import Icon from './icon'
const mapStateToProps = (state) => ({
@ -25,6 +26,10 @@ class NavigationBar extends ImmutablePureComponent {
showBackBtn: PropTypes.bool,
}
handleProfileClick = () => {
}
render() {
const {
title,
@ -34,40 +39,118 @@ class NavigationBar extends ImmutablePureComponent {
account,
} = this.props
const isPro = account.get('is_pro')
return (
<div className={[_s.default, _s.height53PX, _s.flexRow, _s.backgroundColorPrimary, _s.borderBottom1PX, _s.borderColorSecondary, _s.alignItemsCenter, _s.z3, _s.top0, _s.right0, _s.left0, _s.posFixed].join(' ')} >
<div className={[_s.default, _s.flexGrow1, _s.z3, _s.alignItemsEnd].join(' ')}>
<div className={[_s.default, _s.width240PX].join(' ')}>
<div className={[_s.default, _s.height100PC, _s.alignItemsStart, _s.width240PX].join(' ')}>
<h1 className={[_s.default].join(' ')}>
<NavLink to='/' aria-label='Gab' className={[_s.default, _s.flexRow, _s.noSelect, _s.noUnderline, _s.height50PX, _s.cursorPointer, _s.px10].join(' ')}>
<Icon id='gab-logo' />
<div className={[_s.default, _s.z4, _s.height53PX, _s.width100PC].join(' ')}>
<div className={[_s.default, _s.height53PX, _s.bgBrand, _s.alignItemsCenter, _s.z3, _s.top0, _s.right0, _s.left0, _s.posFixed].join(' ')} >
<div className={[_s.default, _s.flexRow, _s.width1255PX].join(' ')}>
<div className={[_s.default, _s.flexRow].join(' ')}>
<h1 className={[_s.default, _s.mr15].join(' ')}>
<NavLink to='/' 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} />
</NavLink>
</h1>
</div>
</div>
</div>
<div className={[_s.default, _s.flexShrink1, _s.flexGrow1].join(' ')}>
<div className={[_s.default, _s.height53PX, _s.pl15, _s.width1015PX, _s.flexRow, _s.justifyContentSpaceBetween].join(' ')}>
<div className={[_s.default, _s.width645PX].join(' ')}>
<ColumnHeader
title={title}
showBackBtn={showBackBtn}
actions={actions}
tabs={tabs}
/>
</div>
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
<div className={[_s.default, _s.width340PX].join(' ')}>
<Search />
</div>
</Responsive>
</div>
<div className={[_s.default, _s.mlAuto].join(' ')}>
<div className={[_s.default, _s.height53PX, _s.pl15, _s.flexRow, _s.alignItemsCenter, _s.justifyContentSpaceBetween].join(' ')}>
<NavigationBarButton title='Home' icon='home' to='/home' />
<NavigationBarButtonDivider />
<NavigationBarButton icon='notifications' to='/notifications' />
<NavigationBarButton icon='cog' to='/notifications' />
<NavigationBarButtonDivider />
<button onClick={this.handleProfileClick} className={[_s.height53PX, _s.bgTransparent, _s.outlineNone, _s.cursorPointer, _s.default, _s.justifyContentCenter, _s.ml15].join(' ')}>
<Avatar account={account} size={32} />
</button>
</div>
</div>
</div>
</div>
</div>
)
}
}
class NavigationBarButtonDivider extends PureComponent {
render() {
return (
<div className={[_s.default, _s.height20PX, _s.width1PX, _s.mr10, _s.ml10, _s.bgBrandDark].join(' ')} />
)
}
}
class NavigationBarButton extends PureComponent {
static propTypes = {
title: PropTypes.string,
icon: PropTypes.string,
to: PropTypes.string,
onClick: PropTypes.func,
}
render() {
const {
title,
icon,
to,
onClick,
} = this.props
const active = false
const classes = CX({
default: 1,
height53PX: 1,
flexRow: 1,
alignItemsCenter: 1,
justifyContentCenter: 1,
outlineNone: 1,
px10: !!title,
px5: !title,
cursorPointer: 1,
bgTransparent: 1,
colorWhite: !!title,
fs13PX: !!title,
fontWeightNormal: !!title,
textUppercase: !!title,
})
const iconClasses = CX({
fillWhite: !!title || active,
fillBrandDark: !title,
mr10: !!title,
})
const iconSize = !!title ? 16 : 18
return (
<button
noClasses
color='white'
className={classes}
>
<Icon className={iconClasses} id={icon} size={iconSize} />
{title}
</button>
)
}
}

View File

@ -96,11 +96,11 @@ class Notification extends ImmutablePureComponent {
}
return (
<div className={[_s.default, _s.px10, _s.cursorPointer, _s.backgroundColorSubtle_onHover].join(' ')}>
<div className={[_s.default, _s.px10, _s.cursorPointer, _s.bgSubtle_onHover].join(' ')}>
<div className={[_s.default, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.my10, _s.py10, _s.px10].join(' ')}>
<Icon id={icon} size='20px' className={[_s.fillColorPrimary, _s.mt5].join(' ')} />
<Icon id={icon} size='20px' className={[_s.fillPrimary, _s.mt5].join(' ')} />
<div className={[_s.default, _s.ml15, _s.flexNormal].join(' ')}>
<div className={[_s.default, _s.flexRow].join(' ')}>

View File

@ -69,7 +69,7 @@ class GroupInfoPanel extends ImmutablePureComponent {
<Divider isSmall />
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter].join(' ')}>
<Icon id='calendar' size='12px' className={_s.fillColorSecondary} />
<Icon id='calendar' size='12px' className={_s.fillSecondary} />
<Text
size='small'
color='secondary'

View File

@ -17,15 +17,14 @@ const mapStateToProps = (state) => ({
})
const mapDispatchToProps = (dispatch) => ({
onFetchGroups: (type) => {
dispatch(fetchGroups(type))
}
onFetchGroups: (type) => dispatch(fetchGroups(type))
})
export default
@connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class GroupSidebarPanel extends ImmutablePureComponent {
static propTypes = {
groupIds: ImmutablePropTypes.list,
isLazy: PropTypes.bool,
@ -37,6 +36,12 @@ class GroupSidebarPanel extends ImmutablePureComponent {
fetched: false,
}
updateOnProps = [
'groupIds',
'isLazy',
'isSlim',
]
componentDidMount() {
if (!this.props.isLazy) {
this.props.onFetchGroups('member')
@ -76,23 +81,20 @@ class GroupSidebarPanel extends ImmutablePureComponent {
footerButtonTo={count > maxCount ? '/groups/browse/member' : undefined}
noPadding={slim}
>
<div className={_s.default}>
<ScrollableList
scrollKey='groups-panel'
>
<ScrollableList scrollKey='groups_panel'>
{
groupIds.slice(0, maxCount).map((groupId, i) => (
<GroupListItem
key={`group-panel-item-${groupId}`}
id={groupId}
slim={slim}
isLast={groupIds.length - 1 === i}
isLast={groupIds.count() - 1 === i}
/>
))
}
</ScrollableList>
</div>
</PanelLayout>
)
}
}

View File

@ -49,7 +49,7 @@ class ListDetailsPanel extends ImmutablePureComponent {
<Divider isSmall />
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter].join(' ')}>
<Icon id='calendar' size='12px' className={_s.fillColorSecondary} />
<Icon id='calendar' size='12px' className={_s.fillSecondary} />
<Text
size='small'
color='secondary'

View File

@ -17,9 +17,7 @@ const mapStateToProps = (state) => ({
})
const mapDispatchToProps = (dispatch) => ({
onFetchLists() {
return dispatch(fetchLists())
},
onFetchLists: () => dispatch(fetchLists()),
})
export default
@ -64,7 +62,7 @@ class ListsPanel extends ImmutablePureComponent {
const maxCount = 6
const listItems = lists.slice(0, maxCount).map(list => ({
const listItems = lists.slice(0, maxCount).map((list) => ({
to: `/lists/${list.get('id')}`,
title: list.get('title'),
}))
@ -79,10 +77,7 @@ class ListsPanel extends ImmutablePureComponent {
noPadding
>
<div className={[_s.default, _s.boxShadowNone].join(' ')}>
<List
scrollKey='lists_sidebar_panel'
items={listItems}
/>
<List scrollKey='lists_sidebar_panel' items={listItems} />
</div>
</PanelLayout>
)

View File

@ -55,7 +55,6 @@ class MediaGalleryPanel extends ImmutablePureComponent {
} = this.props
if (!account || !attachments) return null
if (attachments.size === 0) return null
return (
<PanelLayout
@ -64,6 +63,8 @@ class MediaGalleryPanel extends ImmutablePureComponent {
headerButtonTitle={intl.formatMessage(messages.show_all)}
headerButtonTo={`/${account.get('acct')}/media`}
>
{
attachments.size > 0 &&
<div className={[_s.default, _s.flexRow, _s.flexWrap, _s.px10, _s.py10].join(' ')}>
{
attachments.slice(0, 16).map((attachment, i) => (
@ -76,6 +77,7 @@ class MediaGalleryPanel extends ImmutablePureComponent {
))
}
</div>
}
</PanelLayout>
)
}

View File

@ -87,7 +87,7 @@ export default class PanelLayout extends PureComponent {
backgroundColor='none'
to={footerButtonTo}
onClick={footerButtonAction}
className={[_s.px15, _s.py15, _s.backgroundColorSubtle_onHover].join(' ')}
className={[_s.px15, _s.py15, _s.bgSubtle_onHover].join(' ')}
>
<Text color='brand' size='medium'>
{footerButtonTitle}

View File

@ -71,7 +71,7 @@ class ProfileInfoPanel extends ImmutablePureComponent {
}
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter].join(' ')}>
<Icon id='calendar' size='12px' className={_s.fillColorSecondary} />
<Icon id='calendar' size='12px' className={_s.fillSecondary} />
<Text
size='small'
color='secondary'

View File

@ -1,23 +1,42 @@
import { me, monthlyExpensesComplete } from '../../initial_state'
import { injectIntl, defineMessages } from 'react-intl'
import { monthlyExpensesComplete } from '../../initial_state'
import { URL_DISSENTER_SHOP } from '../../constants'
import PanelLayout from './panel_layout';
import ProgressBar from '../progress_bar'
export default class ProgressPanel extends PureComponent {
const messages = defineMessages({
progressTitle: { id: 'progress_title', defaultMessage: '{value}% covered this month' },
operationsTitle: { id: 'operations_title', defaultMessage: "Gab's Operational Expenses" },
operationsSubtitle: { id: 'operations_subtitle', defaultMessage: 'We are 100% funded by you' },
})
export default
@injectIntl
class ProgressPanel extends PureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
}
render() {
if (!monthlyExpensesComplete || !me) return null
const { intl } = this.props
if (!monthlyExpensesComplete) return null
const value = Math.min(parseFloat(monthlyExpensesComplete), 100)
return (
<PanelLayout
title="Gab's Operational Expenses"
subtitle="We are 100% funded by you"
hasBackground
title={intl.formatMessage(messages.operationsTitle)}
subtitle={intl.formatMessage(messages.operationsSubtitle)}
>
<ProgressBar
progress={monthlyExpensesComplete}
title={`${Math.min(parseFloat(monthlyExpensesComplete), 100)}% covered this month`}
href='https://shop.dissenter.com/category/donations'
title={intl.formatMessage(messages.progressTitle, { value })}
href={URL_DISSENTER_SHOP}
/>
</PanelLayout>
)
}
}

View File

@ -3,9 +3,8 @@ import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
import { fetchGabTrends } from '../../actions/gab_trends'
import PanelLayout from './panel_layout'
import ColumnIndicator from '../column_indicator'
import ScrollableList from '../scrollable_list'
import TrendingItem from '../trends_item'
import TrendsItem from '../trends_item'
const messages = defineMessages({
title: { id: 'trends.title', defaultMessage: 'Trending right now' },
@ -30,6 +29,10 @@ class TrendsPanel extends ImmutablePureComponent {
onFetchGabTrends: PropTypes.func.isRequired,
}
updateOnProps = [
'gabtrends',
]
componentDidMount() {
this.props.onFetchGabTrends()
}
@ -42,34 +45,21 @@ class TrendsPanel extends ImmutablePureComponent {
noPadding
title={intl.formatMessage(messages.title)}
>
<div className={_s.default}>
{
gabtrends.isEmpty() &&
<ColumnIndicator type='loading' />
}
{
!gabtrends.isEmpty() &&
<ScrollableList
showLoading={gabtrends.size == 0}
scrollKey='trending-items'
>
{
gabtrends.slice(0, 8).map((trend, i) => (
<TrendingItem
<TrendsItem
key={`gab-trend-${i}`}
index={i + 1}
isLast={i === 7}
url={trend.get('url')}
title={trend.get('title')}
description={trend.get('description')}
imageUrl={trend.get('image')}
publishDate={trend.get('date_published')}
author={trend.getIn(['author', 'name'], '')}
trend={trend}
/>
))
}
</ScrollableList>
}
</div>
</PanelLayout>
)
}

View File

@ -2,19 +2,20 @@ import { NavLink } from 'react-router-dom'
import { injectIntl, defineMessages } from 'react-intl'
import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
import classNames from 'classnames/bind'
import { me } from '../../initial_state'
import { makeGetAccount } from '../../selectors'
import { shortNumberFormat } from '../../utils/numbers'
import { openModal } from '../../actions/modal'
import {
CX,
MODAL_EDIT_PROFILE,
} from '../../constants'
import PanelLayout from './panel_layout'
import Avatar from '../avatar'
import Button from '../button'
import DisplayName from '../display_name'
import Avatar from '../avatar'
import Image from '../image'
import UserStat from '../user_stat'
import PanelLayout from './panel_layout'
const cx = classNames.bind(_s)
const messages = defineMessages({
gabs: { id: 'account.posts', defaultMessage: 'Gabs' },
@ -30,7 +31,7 @@ const mapStateToProps = (state) => ({
const mapDispatchToProps = (dispatch) => ({
onOpenEditProfile() {
dispatch(openModal('EDIT_PROFILE'))
dispatch(openModal(MODAL_EDIT_PROFILE))
},
})
@ -38,6 +39,7 @@ export default
@connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class UserPanel extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
intl: PropTypes.object.isRequired,
@ -60,15 +62,15 @@ class UserPanel extends ImmutablePureComponent {
this.setState({ hovering: false })
}
handleOnOpenEditProfile = () => {
this.props.onOpenEditProfile()
}
render() {
const { account, intl } = this.props
const {
account,
intl,
onOpenEditProfile,
} = this.props
const { hovering } = this.state
const buttonClasses = cx({
const buttonClasses = CX({
posAbs: 1,
mt10: 1,
mr10: 1,
@ -96,7 +98,7 @@ class UserPanel extends ImmutablePureComponent {
backgroundColor='secondary'
radiusSmall
className={buttonClasses}
onClick={this.handleOnOpenEditProfile}
onClick={onOpenEditProfile}
>
{intl.formatMessage(messages.edit_profile)}
</Button>
@ -134,4 +136,5 @@ class UserPanel extends ImmutablePureComponent {
</PanelLayout>
)
}
}

View File

@ -0,0 +1,96 @@
import { withRouter } from 'react-router-dom'
import { CX } from '../constants'
import Button from './button'
import Text from './text'
export default
@withRouter
class PillItem extends PureComponent {
static propTypes = {
icon: PropTypes.string,
isActive: PropTypes.bool,
onClick: PropTypes.func,
title: PropTypes.string,
to: PropTypes.string,
}
state = {
isCurrent: -1,
}
componentDidUpdate(prevProps) {
// If user navigates to different page, ensure tab bar item
// with this.props.to that is on location is set to active.
if (this.props.location !== prevProps.location) {
const isCurrent = this.props.to === this.props.location.pathname
if (this.state.isCurrent !== isCurrent) {
this.setState({ isCurrent })
}
}
}
render() {
const {
title,
to,
onClick,
location,
isActive,
} = this.props
const { isCurrent } = this.state
// Combine state, props, location to make absolutely
// sure of active status.
const active = isActive ||
(isCurrent === -1 ? to === location.pathname : false)
const containerClasses = CX({
default: 1,
noUnderline: 1,
text: 1,
alignItemsCenter: 1,
justifyContentCenter: 1,
py5: 1,
outlineNone: 1,
cursorPointer: 1,
circle: 1,
bgSecondary: !active,
bgSecondaryDark_onHover: !active,
bgBrand: active,
mr5: 1,
mb5: 1,
})
const textParentClasses = CX({
default: 1,
height100PC: 1,
alignItemsCenter: 1,
justifyContentCenter: 1,
py2: 1,
px15: 1,
})
const textOptions = {
size: 'small',
color: active ? 'white' : 'secondary',
weight: active ? 'bold' : 'medium',
}
return (
<Button
onClick={onClick}
className={containerClasses}
to={to || undefined}
noClasses
>
<span className={textParentClasses}>
<Text {...textOptions}>
{title}
</Text>
</span>
</Button>
)
}
}

View File

@ -0,0 +1,34 @@
import PillItem from './pill_item'
/**
* Renders pills components
* @param {array} [props.pills] - tab bar data for creating `TabBarItem`
*/
export default class Pills extends PureComponent {
static propTypes = {
pills: PropTypes.array,
}
render() {
const { pills } = this.props
return (
<div className={[_s.default, _s.flexWrap, _s.px5, _s.flexRow].join(' ')}>
{
!!pills &&
pills.map((tab, i) => (
<PillItem
key={`pill-item-${i}`}
title={tab.title}
onClick={tab.onClick}
to={tab.to}
isActive={tab.active}
/>
))
}
</div>
)
}
}

View File

@ -92,8 +92,8 @@ class Poll extends ImmutablePureComponent {
left0: 1,
radiusSmall: 1,
height100PC: 1,
backgroundColorSubtle2: !leading,
backgroundColorBrandLight: leading,
bgSecondary: !leading,
bgBrandLight: leading,
})
const inputClasses = cx('poll__input', {
@ -107,11 +107,11 @@ class Poll extends ImmutablePureComponent {
py10: showResults,
mb10: 1,
border1PX: !showResults,
fillColorSecondary: !showResults,
fillSecondary: !showResults,
circle: !showResults,
cursorPointer: !showResults,
backgroundColorSubtle_onHover: !showResults,
backgroundColorSubtle: !showResults && active,
bgSubtle_onHover: !showResults,
bgSubtle: !showResults && active,
})
const textContainerClasses = cx({

View File

@ -90,14 +90,14 @@ class StatusVisibilityDropdown extends PureComponent {
cursorPointer: 1,
borderBottom1PX: !isLast,
borderColorSecondary: !isLast,
backgroundColorSubtle_onHover: !isActive,
backgroundColorBrand: isActive,
bgSubtle_onHover: !isActive,
bgBrand: isActive,
})
const iconClasses = cx({
ml10: 1,
mt2: 1,
fillColorWhite: isActive,
fillWhite: isActive,
})
return (

View File

@ -108,6 +108,7 @@ class ProfileHeader extends ImmutablePureComponent {
const headerSrc = !!account ? account.get('header') : ''
const headerMissing = headerSrc.indexOf(PLACEHOLDER_MISSING_HEADER_SRC) > -1 || !headerSrc
const avatarSize = headerMissing ? 75 : 150
const top = headerMissing ? -30 : -380
const avatarContainerClasses = CX({
default: 1,
@ -131,10 +132,13 @@ class ProfileHeader extends ImmutablePureComponent {
return (
<div className={[_s.default, _s.z1, _s.width100PC].join(' ')}>
<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.radiusSmall, _s.overflowHidden].join(' ')}>
<div className={[_s.default, _s.height350PX, _s.width100PC, _s.bottomRightRadiusSmall, _s.bottomLeftRadiusSmall, _s.overflowHidden].join(' ')}>
<Image
alt={intl.formatMessage(messages.headerPhoto)}
className={_s.height350PX}
@ -155,8 +159,8 @@ class ProfileHeader extends ImmutablePureComponent {
</div>
</div>
<Sticky enabled onStateChange={this.onStickyStateChange}>
<div className={[_s.default, _s.flexRow, _s.backgroundColorSecondary3, _s.borderBottom1PX, _s.borderColorSecondary, _s.height53PX].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.bgPrimary, _s.height53PX].join(' ')}>
<div className={tabBarContainerClasses}>
<TabBar tabs={tabs} isLarge />
</div>
@ -219,9 +223,11 @@ class ProfileHeader extends ImmutablePureComponent {
</div>
}
</div>
</Sticky>
</div>
</div>
</div>
</Sticky>
</div>
)
}

View File

@ -1,14 +1,14 @@
import classNames from 'classnames/bind'
import { CX } from '../constants'
import Button from './button'
import Text from './text'
const cx = classNames.bind(_s)
export default class ProgressBar extends PureComponent {
static propTypes = {
progress: PropTypes.number,
small: PropTypes.bool,
title: PropTypes.string,
href: PropTypes.string,
}
render() {
@ -16,7 +16,7 @@ export default class ProgressBar extends PureComponent {
progress,
small,
title,
href
href,
} = this.props
const completed = Math.min(parseFloat(progress), 100)
@ -24,10 +24,10 @@ export default class ProgressBar extends PureComponent {
width: `${completed}%`,
}
const containerClassName = cx({
const containerClassName = CX({
default: 1,
backgroundColorLoading: !small,
backgroundColorSubtle2: small,
bgLoading: !small,
bgSecondary: small,
noUnderline: 1,
circle: 1,
overflowHidden: 1,
@ -42,7 +42,7 @@ export default class ProgressBar extends PureComponent {
noClasses
className={containerClassName}
>
<div className={[_s.default, _s.backgroundColorBrand, _s.circle, _s.height100PC, _s.backgroundCandy].join(' ')} style={style} />
<div className={[_s.default, _s.bgBrand, _s.circle, _s.height100PC, _s.backgroundCandy].join(' ')} style={style} />
<div className={[_s.default, _s.posAbs, _s.width100PC, _s.height100PC, _s.alignItemsCenter, _s.justifyContentCenter].join(' ')}>
{
!!title &&

View File

@ -116,7 +116,7 @@ class RichTextEditorBar extends PureComponent {
if (!rteControlsVisible || !isPro) return null
return (
<div className={[_s.default, _s.backgroundColorPrimary, _s.borderBottom1PX, _s.borderColorSecondary, _s.py5, _s.px15, _s.alignItemsCenter, _s.flexRow].join(' ')}>
<div className={[_s.default, _s.bgPrimary, _s.borderBottom1PX, _s.borderColorSecondary, _s.py5, _s.px15, _s.alignItemsCenter, _s.flexRow].join(' ')}>
{
RTE_ITEMS.map((item, i) => (
<StyleButton
@ -179,8 +179,8 @@ class StyleButton extends PureComponent {
px10: 1,
mr5: 1,
noSelect: 1,
backgroundColorSubtle2Dark_onHover: 1,
backgroundColorBrandLight: active,
bgSecondaryDark_onHover: 1,
bgBrandLight: active,
// py10: !small,
// py5: small,
// px5: small,

View File

@ -1,12 +1,13 @@
import { withRouter } from 'react-router-dom'
import queryString from 'query-string'
import { CX } from '../constants'
import {
changeSearch,
clearSearch,
submitSearch,
showSearch,
} from '../actions/search'
import Input from './input'
import Button from './button'
const mapStateToProps = (state) => ({
value: state.getIn(['search', 'value']),
@ -40,7 +41,7 @@ class Search extends PureComponent {
}
state = {
expanded: false,
focused: false,
}
textbox = React.createRef()
@ -57,17 +58,17 @@ class Search extends PureComponent {
}
}
handleChange = (value) => {
this.props.onChange(value)
handleOnChange = (e) => {
this.props.onChange(e.target.value)
}
handleFocus = () => {
this.setState({ expanded: true })
handleOnFocus = () => {
this.setState({ focused: true })
this.props.onShow()
}
handleBlur = () => {
this.setState({ expanded: false })
handleOnBlur = () => {
this.setState({ focused: false })
}
handleKeyUp = (e) => {
@ -88,42 +89,78 @@ class Search extends PureComponent {
this.textbox = n
}
handleSubmit = () => {
this.props.onSubmit()
}
render() {
const {
value,
submitted,
onClear,
withOverlay
} = this.props
const { expanded } = this.state
const { focused } = this.state
const highlighted = focused || `${value}`.length > 0
const hasValue = value ? value.length > 0 || submitted : 0
const inputClasses = CX({
default: 1,
text: 1,
outlineNone: 1,
lineHeight125: 1,
displayBlock: 1,
py7: 1,
bgTransparent: !highlighted,
colorPrimary: 1,
fs14PX: 1,
flexGrow1: 1,
radiusSmall: 1,
pl15: 1,
searchInput: 1,
})
const containerClasses = CX({
default: 1,
bgBrandLight: !highlighted,
bgWhite: highlighted,
flexRow: 1,
radiusSmall: 1,
alignItemsCenter: 1,
})
const prependIconColor = highlighted ? 'brand' : 'white'
const id = 'nav-search'
return (
<div className={[_s.default, _s.justifyContentCenter, _s.height53PX].join(' ')}>
<Input
hasClear
<div className={containerClasses}>
<label className={_s.visiblyHidden} htmlFor={id}>Search</label>
<input
id={id}
className={inputClasses}
type='text'
placeholder='Search for people, groups or news'
ref={this.setTextbox}
value={value}
inputRef={this.setTextbox}
id='search'
prependIcon='search'
placeholder='Search Gab'
onChange={this.handleChange}
onKeyUp={this.handleKeyUp}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
onClear={onClear}
hideLabel
title='Search'
onChange={this.handleOnChange}
onFocus={this.handleOnFocus}
onBlur={this.handleOnBlur}
/>
{
withOverlay &&
{/*<Overlay show={expanded && !hasValue} placement='bottom' target={this}>
<SearchPopout />
</Overlay>*/}
}
<Button
className={[_s.px10, _s.mr5].join(' ')}
tabIndex='0'
title='...'
backgroundColor='none'
color={prependIconColor}
onClick={this.handleSubmit}
icon='search'
iconClassName={_s.inheritFill}
iconSize='16px'
/>
</div>
</div>
)
}

View File

@ -49,7 +49,7 @@ export default class Select extends ImmutablePureComponent {
<Icon
id='select'
size='14px'
className={[_s.fillColorSecondary, _s.posAbs, _s.right0, _s.mr10, _s.bottom0, _s.mb15].join(' ')}
className={[_s.fillSecondary, _s.posAbs, _s.right0, _s.mr10, _s.bottom0, _s.mb15].join(' ')}
/>
</div>
)

View File

@ -24,7 +24,7 @@ class SensitiveMediaItem extends PureComponent {
return (
<div className={[_s.default, _s.px15, _s.pt5].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.radiusSmall, _s.backgroundColorSecondary3, _s.py10, _s.px15, _s.height100PC, _s.width100PC].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.radiusSmall, _s.bgTertiary, _s.py10, _s.px15, _s.height100PC, _s.width100PC].join(' ')}>
<div className={[_s.default, _s.justifyContentCenter, _s.flexNormal].join(' ')}>
<Text color='secondary'>
{intl.formatMessage(messages.warning)}
@ -35,7 +35,7 @@ class SensitiveMediaItem extends PureComponent {
onClick={onClick}
color='tertiary'
backgroundColor='none'
className={_s.backgroundColorSubtle2Dark_onHover}
className={_s.bgSecondaryDark_onHover}
>
<Text color='inherit' weight='bold' size='medium'>
{intl.formatMessage(messages.view)}

View File

@ -11,7 +11,9 @@ import { makeGetAccount } from '../selectors'
import Responsive from '../features/ui/util/responsive_component'
import SidebarSectionTitle from './sidebar_section_title'
import SidebarSectionItem from './sidebar_section_item'
import SidebarHeader from './sidebar_header'
import Heading from './heading'
import Pills from './pills'
import Divider from './divider'
const messages = defineMessages({
followers: { id: 'account.followers', defaultMessage: 'Followers' },
@ -27,6 +29,8 @@ const messages = defineMessages({
lists: { id: 'column.lists', defaultMessage: 'Lists' },
apps: { id: 'tabs_bar.apps', defaultMessage: 'Apps' },
more: { id: 'sidebar.more', defaultMessage: 'More' },
explore: { id: 'explore', defaultMessage: 'Explore' },
menu: { id: 'menu', defaultMessage: 'Menu' },
pro: { id: 'promo.gab_pro', defaultMessage: 'Upgrade to GabPRO' },
trends: { id: 'promo.trends', defaultMessage: 'Trends' },
search: { id: 'tabs_bar.search', defaultMessage: 'Search' },
@ -73,6 +77,10 @@ class Sidebar extends ImmutablePureComponent {
openSidebarMorePopover: PropTypes.func.isRequired,
notificationCount: PropTypes.number.isRequired,
homeItemsQueueCount: PropTypes.number.isRequired,
actions: PropTypes.array,
tabs: PropTypes.array,
title: PropTypes.string,
showBackBtn: PropTypes.bool,
}
handleOpenComposeModal = () => {
@ -98,6 +106,10 @@ class Sidebar extends ImmutablePureComponent {
homeItemsQueueCount,
showCommunityTimeline,
moreOpen,
actions,
tabs,
title,
showBackBtn,
} = this.props
// : todo :
@ -196,13 +208,23 @@ class Sidebar extends ImmutablePureComponent {
return (
<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.top0, _s.height100PC].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(' ')}>
<SidebarHeader />
<div className={_s.default}>
<div className={[_s.default, _s.px5, _s.py10].join(' ')}>
<Heading size='h1'>
{title}
</Heading>
</div>
{
!!tabs &&
<div className={[_s.default, _s.mt10, _s.pb15, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
<Pills pills={tabs} />
</div>
}
</div>
<nav aria-label='Primary' role='navigation' className={[_s.default, _s.width100PC, _s.mb15].join(' ')}>
<SidebarSectionTitle>Menu</SidebarSectionTitle>
<SidebarSectionTitle>{intl.formatMessage(messages.menu)}</SidebarSectionTitle>
{
menuItems.map((menuItem, i) => {
if (menuItem.hidden) return null
@ -212,13 +234,7 @@ class Sidebar extends ImmutablePureComponent {
)
})
}
{ /* <SidebarSectionTitle>Shortcuts</SidebarSectionTitle> */ }
{
shortcutItems.map((shortcutItem, i) => (
<SidebarSectionItem {...shortcutItem} key={`sidebar-item-shortcut-${i}`} />
))
}
<SidebarSectionTitle>Explore</SidebarSectionTitle>
<SidebarSectionTitle>{intl.formatMessage(messages.explore)}</SidebarSectionTitle>
{
exploreItems.map((exploreItem, i) => (
<SidebarSectionItem {...exploreItem} key={`sidebar-item-explore-${i}`} />
@ -230,7 +246,7 @@ class Sidebar extends ImmutablePureComponent {
<Button
isBlock
onClick={this.handleOpenComposeModal}
className={[_s.py15, _s.fontSize15PX, _s.fontWeightBold].join(' ')}
className={[_s.py15, _s.fs15PX, _s.fontWeightBold].join(' ')}
>
Gab
</Button>

View File

@ -1,57 +0,0 @@
import { Fragment } from 'react'
import { NavLink } from 'react-router-dom'
import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
import { me } from '../initial_state'
import { makeGetAccount } from '../selectors'
import Icon from './icon'
import SidebarSectionItem from './sidebar_section_item'
import Text from './text'
const mapStateToProps = (state) => {
const getAccount = makeGetAccount()
return {
account: getAccount(state, me),
}
}
export default
@connect(mapStateToProps)
class SidebarHeader extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
}
render() {
const { account } = this.props
const isPro = account.get('is_pro')
return (
<Fragment>
<h1 className={[_s.default].join(' ')}>
<NavLink to='/' aria-label='Gab' className={[_s.default, _s.flexRow, _s.noSelect, _s.noUnderline, _s.height50PX, _s.cursorPointer, _s.px10].join(' ')}>
<Icon id='gab-logo' className={_s.fillColorBrand} />
{
isPro &&
<Text weight='bold' color='brand' size='extraSmall' className={[_s.pb5].join(' ')}>
PRO
</Text>
}
</NavLink>
</h1>
{
(!!me && !!account) &&
<SidebarSectionItem
image={account.get('avatar')}
title={account.get('acct')}
to={`/${account.get('acct')}`}
/>
}
</Fragment>
)
}
}

View File

@ -69,35 +69,35 @@ export default class SidebarSectionItem extends PureComponent {
outlineNone: 1,
borderColorTransparent: !shouldShowActive,
borderColorSecondary: shouldShowActive,
backgroundTransparent: !shouldShowActive,
backgroundColorPrimary: shouldShowActive,
bgTransparent: !shouldShowActive,
bgPrimary: shouldShowActive,
})
const textClasses = cx({
default: 1,
fontWeightNormal: 1,
fontSize15PX: 1,
fs15PX: 1,
text: 1,
textOverflowEllipsis: 1,
colorPrimary: 1,
})
const iconClasses = cx({
fillColorPrimary: 1,
fillPrimary: 1,
})
const countClasses = cx({
default: 1,
text: 1,
mlAuto: 1,
fontSize12PX: 1,
fs12PX: 1,
px5: 1,
mr2: 1,
lineHeight15: 1,
ml5: 1,
colorSecondary: !isNotifications,
colorWhite: isNotifications,
backgroundColorBrand: isNotifications,
bgBrand: isNotifications,
radiusSmall: isNotifications,
})
@ -110,7 +110,7 @@ export default class SidebarSectionItem extends PureComponent {
buttonRef={buttonRef}
onMouseEnter={() => this.handleOnMouseEnter()}
onMouseLeave={() => this.handleOnMouseLeave()}
className={[_s.default, _s.noUnderline, _s.outlineNone, _s.cursorPointer, _s.width100PC, _s.backgroundTransparent].join(' ')}
className={[_s.default, _s.noUnderline, _s.outlineNone, _s.cursorPointer, _s.width100PC, _s.bgTransparent].join(' ')}
>
<div className={containerClasses}>
{

View File

@ -11,7 +11,7 @@ export default class SidebarSectionTitle extends PureComponent {
return (
<div className={[_s.default, _s.py5, _s.px10, _s.mt10].join(' ')}>
<Text size='small' weight='bold' color='tertiary'>
<Text color='tertiary'>
{children}
</Text>
</div>

View File

@ -444,10 +444,9 @@ class Status extends ImmutablePureComponent {
const containerClasses = cx({
default: 1,
radiusSmall: !isChild,
pb15: isFeatured,
radiusSmall: !isChild,
backgroundColorPrimary: !isChild,
bgPrimary: !isChild,
boxShadowBlock: !isChild,
outlineNone: 1,
mb15: !isChild,
@ -465,7 +464,7 @@ class Status extends ImmutablePureComponent {
pb10: isChild && status.get('media_attachments').size === 0,
pb5: isChild && status.get('media_attachments').size > 1,
cursorPointer: isChild,
backgroundColorSubtle_onHover: isChild,
bgSubtle_onHover: isChild,
})
return (

View File

@ -2,9 +2,13 @@ import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
import { defineMessages, injectIntl } from 'react-intl'
import { NavLink } from 'react-router-dom'
import classNames from 'classnames/bind'
import Text from './text'
import StatusActionBarItem from './status_action_bar_item'
import {
CX,
BREAKPOINT_EXTRA_SMALL,
} from '../constants'
import Responsive from '../features/ui/util/responsive_component'
const messages = defineMessages({
comment: { id: 'status.comment', defaultMessage: 'Comment' },
@ -17,8 +21,6 @@ const messages = defineMessages({
commentsLabel: { id: 'comments.label', defaultMessage: '{number, plural, one {# comment} other {# comments}}' },
})
const cx = classNames.bind(_s)
export default
@injectIntl
class StatusActionBar extends ImmutablePureComponent {
@ -88,14 +90,14 @@ class StatusActionBar extends ImmutablePureComponent {
const statusUrl = `/${status.getIn(['account', 'acct'])}/posts/${status.get('id')}`
const containerClasses = cx({
const containerClasses = CX({
default: 1,
px10: 1,
mt10: !shouldCondense,
mt5: shouldCondense,
})
const innerContainerClasses = cx({
const innerContainerClasses = CX({
default: 1,
py2: 1,
flexRow: 1,
@ -105,14 +107,14 @@ class StatusActionBar extends ImmutablePureComponent {
mt5: hasInteractions,
})
const interactionBtnClasses = cx({
const interactionBtnClasses = CX({
default: 1,
text: 1,
cursorPointer: 1,
fontWeightNormal: 1,
noUnderline: 1,
underline_onHover: 1,
backgroundTransparent: 1,
bgTransparent: 1,
mr10: 1,
py5: 1,
})
@ -179,12 +181,14 @@ class StatusActionBar extends ImmutablePureComponent {
buttonRef={this.setRepostButton}
onClick={this.handleRepostClick}
/>
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
<StatusActionBarItem
buttonRef={this.setShareButton}
title={intl.formatMessage(messages.share)}
icon='share'
onClick={this.handleShareClick}
/>
</Responsive>
</div>
</div>
</div>

View File

@ -34,7 +34,7 @@ export default class StatusActionBarItem extends PureComponent {
justifyContentCenter: 1,
alignItemsCenter: 1,
px10: 1,
backgroundColorSubtle_onHover: !disabled,
bgSubtle_onHover: !disabled,
})
const color = active ? 'brand' : 'secondary'

View File

@ -120,7 +120,7 @@ export default class Card extends ImmutablePureComponent {
return (
<div
ref={this.setRef}
className={[_s.default, _s.backgroundColorSecondary3, _s.posAbs, _s.top0, _s.right0, _s.bottom0, _s.left0, _s.statusCardVideo].join(' ')}
className={[_s.default, _s.bgTertiary, _s.posAbs, _s.top0, _s.right0, _s.bottom0, _s.left0, _s.statusCardVideo].join(' ')}
dangerouslySetInnerHTML={content}
/>
)
@ -141,7 +141,7 @@ export default class Card extends ImmutablePureComponent {
const title = interactive ?
(
<a
className={[_s.default, _s.displayFlex, _s.text, _s.noUnderline, _s.overflowWrapBreakWord, _s.colorPrimary, _s.fontSize15PX, _s.fontWeightMedium].join(' ')}
className={[_s.default, _s.displayFlex, _s.text, _s.noUnderline, _s.overflowWrapBreakWord, _s.colorPrimary, _s.fs15PX, _s.fontWeightMedium].join(' ')}
href={card.get('url')}
title={card.get('title')}
rel='noopener noreferrer'
@ -151,7 +151,7 @@ export default class Card extends ImmutablePureComponent {
</a>
)
: (
<span className={[_s.default, _s.displayFlex, _s.text, _s.overflowWrapBreakWord, _s.colorPrimary, _s.fontSize15PX, _s.fontWeightMedium].join(' ')}>
<span className={[_s.default, _s.displayFlex, _s.text, _s.overflowWrapBreakWord, _s.colorPrimary, _s.fs15PX, _s.fontWeightMedium].join(' ')}>
{card.get('title')}
</span>
)
@ -159,11 +159,11 @@ export default class Card extends ImmutablePureComponent {
const description = (
<div className={[_s.default, _s.flexNormal, _s.px10, _s.py10, _s.borderColorSecondary, _s.borderLeft1PX].join(' ')}>
{title}
<p className={[_s.default, _s.displayFlex, _s.text, _s.mt5, _s.mb5, _s.overflowWrapBreakWord, _s.colorSecondary, _s.fontSize13PX, _s.fontWeightNormal].join(' ')}>
<p className={[_s.default, _s.displayFlex, _s.text, _s.mt5, _s.mb5, _s.overflowWrapBreakWord, _s.colorSecondary, _s.fs13PX, _s.fontWeightNormal].join(' ')}>
{trim(card.get('description') || '', maxDescription)}
</p>
<span className={[_s.default, _s.mtAuto, _s.flexRow, _s.alignItemsCenter, _s.colorSecondary, _s.text, _s.displayFlex, _s.textOverflowEllipsis, _s.fontSize13PX].join(' ')}>
<Icon id='link' size='10px' className={[_s.fillColorSecondary, _s.mr5].join(' ')} fixedWidth />
<span className={[_s.default, _s.mtAuto, _s.flexRow, _s.alignItemsCenter, _s.colorSecondary, _s.text, _s.displayFlex, _s.textOverflowEllipsis, _s.fs13PX].join(' ')}>
<Icon id='link' size='10px' className={[_s.fillSecondary, _s.mr5].join(' ')} fixedWidth />
{provider}
</span>
</div>
@ -197,10 +197,10 @@ export default class Card extends ImmutablePureComponent {
{ !embed &&
<div className={[_s.default, _s.posAbs, _s.top0, _s.right0, _s.left0, _s.bottom0, _s.alignItemsCenter, _s.justifyContentCenter].join(' ')}>
<button
className={[_s.default, _s.cursorPointer, _s.backgroundColorBlackOpaque, _s.radiusSmall, _s.py15, _s.px15].join(' ')}
className={[_s.default, _s.cursorPointer, _s.bgBlackOpaque, _s.radiusSmall, _s.py15, _s.px15].join(' ')}
onClick={this.handleEmbedClick}
>
<Icon id={iconVariant} size='22px' className={[_s.fillColorWhite].join(' ')} />
<Icon id={iconVariant} size='22px' className={[_s.fillWhite].join(' ')} />
</button>
</div>
}
@ -219,7 +219,7 @@ export default class Card extends ImmutablePureComponent {
} else {
embed = (
<div className={[_s.default, _s.py15, _s.px15, _s.width72PX, _s.alignItemsCenter, _s.justifyContentCenter].join(' ')}>
<Icon id='website' size='22px' className={_s.fillColorSecondary} />
<Icon id='website' size='22px' className={_s.fillSecondary} />
</div>
)
}
@ -228,7 +228,7 @@ export default class Card extends ImmutablePureComponent {
<div className={[_s.default, _s.width100PC, _s.px10].join(' ')}>
<a
href={card.get('url')}
className={[_s.default, _s.cursorPointer, _s.flexRow, _s.overflowHidden, _s.noUnderline, _s.width100PC, _s.backgroundColorSubtle_onHover, _s.borderColorSecondary, _s.border1PX, _s.radiusSmall].join(' ')}
className={[_s.default, _s.cursorPointer, _s.flexRow, _s.overflowHidden, _s.noUnderline, _s.width100PC, _s.bgSubtle_onHover, _s.borderColorSecondary, _s.border1PX, _s.radiusSmall].join(' ')}
rel='noopener noreferrer'
ref={this.setRef}
>

View File

@ -85,7 +85,7 @@ class StatusContent extends ImmutablePureComponent {
if (descendent.classList.contains('invisible')) {
descendent.classList.remove('invisible')
descendent.classList.add(_s.fontSize0, _s.text, _s.inherit)
descendent.classList.add(_s.fs0, _s.text, _s.inherit)
}
if (descendent.classList.contains('ellipsis')) {
descendent.classList.remove('ellipsis')
@ -254,7 +254,7 @@ class StatusContent extends ImmutablePureComponent {
<div className={spoilerContainerClasses}>
<div className={[_s.default, _s.flexRow, _s.mr5].join(' ')}>
<Icon id='warning' size='14px' className={[_s.fillColorPrimary, _s.mt2, _s.mr5].join(' ')}/>
<Icon id='warning' size='14px' className={[_s.fillPrimary, _s.mt2, _s.mr5].join(' ')}/>
<div
className={_s.statusContent}
dangerouslySetInnerHTML={spoilerContent}

View File

@ -104,7 +104,7 @@ class StatusHeader extends ImmutablePureComponent {
color='none'
icon='ellipsis'
iconSize='20px'
iconClassName={_s.fillColorSecondary}
iconClassName={_s.fillSecondary}
className={_s.mlAuto}
onClick={this.handleOpenStatusOptionsPopover}
buttonRef={this.setStatusOptionsButton}
@ -127,7 +127,7 @@ class StatusHeader extends ImmutablePureComponent {
<DotTextSeperator />
<Icon id={visibilityIcon} size='12px' className={[_s.default, _s.displayInline, _s.ml5, _s.fillColorSecondary].join(' ')} />
<Icon id={visibilityIcon} size='12px' className={[_s.default, _s.displayInline, _s.ml5, _s.fillSecondary].join(' ')} />
{
!!status.get('group') &&

View File

@ -42,7 +42,7 @@ class StatusPrepend extends ImmutablePureComponent {
return (
<div className={[_s.default, _s.width100PC, _s.alignItemsStart, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
<div className={[_s.default, _s.width100PC, _s.flexRow, _s.alignItemsCenter, _s.py5, _s.px15].join(' ')}>
<Icon id={iconId} size='12px' className={[_s.fillColorSecondary, _s.mr5].join(' ')} />
<Icon id={iconId} size='12px' className={[_s.fillSecondary, _s.mr5].join(' ')} />
{
isRepost &&
<div className={[_s.default, _s.flexRow].join(' ')}>

View File

@ -36,18 +36,18 @@ export default class Switch extends PureComponent {
border1PX: 1,
mlAuto: 1,
borderColorSecondary: 1,
backgroundColorBrand: checked,
bgBrand: checked,
})
const checkboxLabelClasses = cx({
default: 1,
margin1PX: 1,
m1PX: 1,
height20PX: 1,
width20PX: 1,
circle: 1,
posAbs: 1,
backgroundColorSubtle2: !checked,
backgroundColorPrimary: checked,
bgSecondary: !checked,
bgPrimary: checked,
left0: !checked,
right0: checked,
})

View File

@ -26,7 +26,6 @@ export default class TabBar extends PureComponent {
key={`tab-bar-item-${i}`}
title={tab.title}
onClick={tab.onClick}
icon={tab.icon}
to={tab.to}
isActive={tab.active}
isLarge={isLarge}

View File

@ -1,7 +1,6 @@
import { withRouter } from 'react-router-dom'
import classNames from 'classnames/bind'
import Button from './button'
import Icon from './icon'
import Text from './text'
// Bind CSS Modules global variable `_s` to classNames module
@ -9,7 +8,6 @@ const cx = classNames.bind(_s)
/**
* Renders a tab bar item component
* @param {string} [props.icon] - icon to use
* @param {bool} [props.isLarge] - to style the tab bar larger
* @param {bool} [props.isActive] - if item is active
* @param {func} [props.onClick] - function to call on click
@ -21,7 +19,6 @@ export default
class TabBarItem extends PureComponent {
static propTypes = {
icon: PropTypes.string,
isLarge: PropTypes.bool,
isActive: PropTypes.bool,
onClick: PropTypes.func,
@ -52,7 +49,6 @@ class TabBarItem extends PureComponent {
onClick,
location,
isLarge,
icon,
isActive,
} = this.props
const { isCurrent } = this.state
@ -74,7 +70,7 @@ class TabBarItem extends PureComponent {
py5: 1,
outlineNone: 1,
cursorPointer: 1,
backgroundTransparent: 1,
bgTransparent: 1,
borderColorTransparent: !active,
borderColorBrand: active,
mr5: isLarge,
@ -89,7 +85,7 @@ class TabBarItem extends PureComponent {
radiusSmall: 1,
px10: !isLarge,
px15: isLarge,
backgroundColorSubtle2Dark_onHover: !active,
bgSecondaryDark_onHover: !active,
})
const textOptions = {
@ -98,12 +94,6 @@ class TabBarItem extends PureComponent {
weight: active ? 'bold' : isLarge ? 'medium' : 'normal',
}
const iconOptions = {
id: icon,
width: !!isLarge ? 20 : 14,
height: !!isLarge ? 20 : 14,
}
return (
<Button
onClick={onClick}
@ -112,17 +102,9 @@ class TabBarItem extends PureComponent {
noClasses
>
<span className={textParentClasses}>
{
!!title &&
<Text {...textOptions}>
{title}
</Text>
}
{
!!icon &&
<Icon {...iconOptions} />
}
</span>
</Button>
)

View File

@ -103,11 +103,11 @@ export default class Text extends PureComponent {
colorWhite: color === COLORS.white,
inherit: color === COLORS.inherit,
fontSize19PX: size === SIZES.large,
fontSize15PX: size === SIZES.medium,
fontSize14PX: size === SIZES.normal,
fontSize13PX: size === SIZES.small,
fontSize12PX: size === SIZES.extraSmall,
fs19PX: size === SIZES.large,
fs15PX: size === SIZES.medium,
fs14PX: size === SIZES.normal,
fs13PX: size === SIZES.small,
fs12PX: size === SIZES.extraSmall,
fontWeightNormal: weight === WEIGHTS.normal,
fontWeightMedium: weight === WEIGHTS.medium,

View File

@ -8,7 +8,6 @@ export default class Textarea extends PureComponent {
placeholder: PropTypes.string,
prependIcon: PropTypes.string,
value: PropTypes.string,
hasClear: PropTypes.bool,
onChange: PropTypes.func,
onKeyUp: PropTypes.func,
onFocus: PropTypes.func,
@ -25,7 +24,6 @@ export default class Textarea extends PureComponent {
placeholder,
prependIcon,
value,
hasClear,
onKeyUp,
onFocus,
onBlur,
@ -39,14 +37,13 @@ export default class Textarea extends PureComponent {
lineHeight125: 1,
displayBlock: 1,
py10: 1,
backgroundTransparent: 1,
fontSize15PX: 1,
bgTransparent: 1,
fs15PX: 1,
flexGrow1: 1,
heightMax100VH: 1,
resizeVertical: 1,
px5: !!prependIcon,
pl15: !prependIcon,
pr15: !hasClear,
})
return (
@ -59,7 +56,7 @@ export default class Textarea extends PureComponent {
</Text>
</div>
}
<div className={[_s.default, _s.backgroundColorPrimary, _s.border1PX, _s.borderColorSecondary, _s.flexRow, _s.radiusSmall, _s.alignItemsCenter].join(' ')}>
<div className={[_s.default, _s.bgPrimary, _s.border1PX, _s.borderColorSecondary, _s.flexRow, _s.radiusSmall, _s.alignItemsCenter].join(' ')}>
<textarea
className={inputClasses}
type='text'

View File

@ -53,7 +53,7 @@ class TimelineComposeBlock extends ImmutablePureComponent {
return (
<section className={[_s.default, _s.mb15].join(' ')}>
<Block>
<div className={[_s.default, _s.backgroundColorSubtle, _s.borderTop1PX, _s.borderBottom1PX, _s.borderColorSecondary, _s.px15, _s.py2, _s.alignItemsCenter, _s.flexRow].join(' ')}>
<div className={[_s.default, _s.bgSubtle, _s.borderTop1PX, _s.borderBottom1PX, _s.borderColorSecondary, _s.px15, _s.py2, _s.alignItemsCenter, _s.flexRow].join(' ')}>
<div className={_s.mr10}>
<Avatar account={account} size={20} noHover />
</div>

View File

@ -1,27 +1,24 @@
import { Fragment } from 'react'
import classNames from 'classnames/bind'
import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
import { urlRegex } from '../features/ui/util/url_regex'
import {
CX,
DEFAULT_REL,
} from '../constants'
import Button from './button'
import DotTextSeperator from './dot_text_seperator'
import Image from './image'
import RelativeTimestamp from './relative_timestamp'
import Text from './text'
const cx = classNames.bind(_s)
export default class TrendingItem extends PureComponent {
export default class TrendingItem extends ImmutablePureComponent {
static propTypes = {
index: PropTypes.number,
url: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
description: PropTypes.string,
imageUrl: PropTypes.string,
author: PropTypes.string,
publishDate: PropTypes.string,
trend: ImmutablePropTypes.map.isRequired,
isLast: PropTypes.bool,
isHidden: PropTypes.bool,
wide: PropTypes.bool,
}
static defaultProps = {
@ -45,19 +42,18 @@ export default class TrendingItem extends PureComponent {
render() {
const {
index,
url,
title,
description,
imageUrl,
author,
publishDate,
trend,
isLast,
wide,
isHidden,
} = this.props
const { hovering } = this.state
const correctedAuthor = author.replace('www.', '')
if (!trend) return null
const title = trend.get('title')
const description = trend.get('description')
const correctedAuthor = trend.getIn(['author', 'name'], '').replace('www.', '')
const correctedDescription = description.length >= 120 ? `${description.substring(0, 120).trim()}...` : description
const descriptionHasLink = correctedDescription.match(urlRegex)
@ -71,7 +67,7 @@ export default class TrendingItem extends PureComponent {
)
}
const containerClasses = cx({
const containerClasses = CX({
default: 1,
noUnderline: 1,
px15: 1,
@ -82,35 +78,29 @@ export default class TrendingItem extends PureComponent {
backgroundColorSubtle_onHover: 1,
})
const subtitleClasses = cx({
const subtitleClasses = CX({
ml5: 1,
underline: hovering,
})
const image = (
return (
<Button
noClasses
href={trend.get('url')}
target='_blank'
rel={DEFAULT_REL}
className={containerClasses}
onMouseEnter={() => this.handleOnMouseEnter()}
onMouseLeave={() => this.handleOnMouseLeave()}
>
<Image
nullable
width='116px'
height='78px'
alt={title}
src={imageUrl}
src={trend.get('image')}
className={[_s.radiusSmall, _s.overflowHidden, _s.mb10].join(' ')}
/>
)
return (
<Button
noClasses
href={url}
target='_blank'
rel='noopener noreferrer'
className={containerClasses}
onMouseEnter={() => this.handleOnMouseEnter()}
onMouseLeave={() => this.handleOnMouseLeave()}
>
{
!wide && image
}
<div className={[_s.default, _s.flexNormal, _s.pb5].join(' ')}>
<div className={_s.default}>
@ -127,6 +117,7 @@ export default class TrendingItem extends PureComponent {
</Text>
</div>
}
<div className={[_s.default, _s.flexRow].join(' ')}>
<Text color='secondary' size='small'>
{index}
@ -137,13 +128,14 @@ export default class TrendingItem extends PureComponent {
</Text>
<DotTextSeperator />
<Text color='secondary' size='small' className={subtitleClasses}>
<RelativeTimestamp timestamp={publishDate} />
<RelativeTimestamp timestamp={trend.get('date_published')} />
</Text>
{
hovering &&
<Text color='secondary' size='small' className={_s.ml10}></Text>
}
</div>
</div>
</Button>
)

View File

@ -54,7 +54,7 @@ class UploadArea extends PureComponent {
>
{({ backgroundOpacity, backgroundScale }) => (
<div
className={[_s.default, _s.alignItemsCenter, _s.justifyContentCenter, _s.backgroundColorPrimaryOpaque, _s.width100PC, _s.height100PC, _s.posAbs, _s.top0, _s.rightAuto, _s.bottomAuto, _s.left0].join(' ')}
className={[_s.default, _s.alignItemsCenter, _s.justifyContentCenter, _s.bgPrimaryOpaque, _s.width100PC, _s.height100PC, _s.posAbs, _s.top0, _s.rightAuto, _s.bottomAuto, _s.left0].join(' ')}
style={{
visibility: active ? 'visible' : 'hidden',
opacity: backgroundOpacity
@ -62,7 +62,7 @@ class UploadArea extends PureComponent {
>
<div className={[_s.default, _s.width340PX, _s.height260PX, _s.px10, _s.py10].join(' ')}>
<div
className={[_s.default, _s.posAbs, _s.backgroundColorPrimary, _s.height100PC, _s.width100PC, _s.radiusSmall].join(' ')}
className={[_s.default, _s.posAbs, _s.bgPrimary, _s.height100PC, _s.width100PC, _s.radiusSmall].join(' ')}
style={{
transform: `scale(${backgroundScale})`
}}

View File

@ -460,7 +460,7 @@ class Video extends PureComponent {
circle: 1,
px10: 1,
py10: 1,
backgroundColorBrand: 1,
bgBrand: 1,
mlNeg5PX: 1,
z3: 1,
boxShadow1: 1,
@ -479,7 +479,7 @@ class Video extends PureComponent {
const volumeControlClasses = cx({
default: 1,
posAbs: 1,
backgroundColorBlackOpaque: 1,
bgBlackOpaque: 1,
videoPlayerVolume: 1,
height122PX: 1,
circle: 1,
@ -550,19 +550,19 @@ class Video extends PureComponent {
ref={this.setVolumeRef}
>
<div
className={[_s.default, _s.radiusSmall, _s.my10, _s.posAbs, _s.width4PX, _s.ml10, _s.backgroundColorPrimaryOpaque].join(' ')}
className={[_s.default, _s.radiusSmall, _s.my10, _s.posAbs, _s.width4PX, _s.ml10, _s.bgPrimaryOpaque].join(' ')}
style={{
height: '102px',
}}
/>
<div
className={[_s.default, _s.radiusSmall, _s.my10, _s.bottom0, _s.posAbs, _s.width4PX, _s.ml10, _s.backgroundColorPrimary].join(' ')}
className={[_s.default, _s.radiusSmall, _s.my10, _s.bottom0, _s.posAbs, _s.width4PX, _s.ml10, _s.bgPrimary].join(' ')}
style={{
height: `${volumeHeight}px`
}}
/>
<span
className={[_s.default, _s.cursorPointer, _s.posAbs, _s.circle, _s.px5, _s.boxShadow1, _s.mbNeg5PX, _s.py5, _s.backgroundColorPrimary, _s.z3].join(' ')}
className={[_s.default, _s.cursorPointer, _s.posAbs, _s.circle, _s.px5, _s.boxShadow1, _s.mbNeg5PX, _s.py5, _s.bgPrimary, _s.z3].join(' ')}
tabIndex='0'
style={{
marginLeft: '7px',
@ -579,9 +579,9 @@ class Video extends PureComponent {
ref={this.setSeekRef}
>
<div className={[progressClasses, _s.backgroundColorLoading, _s.width100PC].join(' ')} />
<div className={[progressClasses, _s.backgroundColorSubtle].join(' ')} style={{ width: `${buffer}%` }} />
<div className={[progressClasses, _s.backgroundColorBrand].join(' ')} style={{ width: `${progress}%` }} />
<div className={[progressClasses, _s.bgLoading, _s.width100PC].join(' ')} />
<div className={[progressClasses, _s.bgSubtle].join(' ')} style={{ width: `${buffer}%` }} />
<div className={[progressClasses, _s.bgBrand].join(' ')} style={{ width: `${progress}%` }} />
<span
className={seekHandleClasses}
@ -600,7 +600,7 @@ class Video extends PureComponent {
onClick={this.togglePlay}
icon={paused ? 'play' : 'pause'}
iconSize='16px'
iconClassName={_s.fillColorWhite}
iconClassName={_s.fillWhite}
className={_s.pl0}
/>
@ -619,7 +619,7 @@ class Video extends PureComponent {
onClick={this.toggleMute}
icon={muted ? 'audio-mute' : 'audio'}
iconSize='24px'
iconClassName={_s.fillColorWhite}
iconClassName={_s.fillWhite}
className={[_s.px10, _s.ml10].join(' ')}
onMouseEnter={this.handleMouseEnterAudio}
onMouseLeave={this.handleMouseLeaveAudio}
@ -632,7 +632,7 @@ class Video extends PureComponent {
onClick={this.toggleFullscreen}
icon={fullscreen ? 'minimize-fullscreen' : 'fullscreen'}
iconSize='20px'
iconClassName={_s.fillColorWhite}
iconClassName={_s.fillWhite}
className={[_s.px10, _s.pr0].join(' ')}
/>
</div>

View File

@ -3,6 +3,8 @@ export const CX = classNames.bind(_s)
export const APP_NAME = 'Gab'
export const DEFAULT_REL = 'noopener noreferrer'
export const BREAKPOINT_EXTRA_LARGE = 1480
export const BREAKPOINT_LARGE = 1280
export const BREAKPOINT_MEDIUM = 1160
@ -12,6 +14,8 @@ export const BREAKPOINT_EXTRA_SMALL = 992
export const ALLOWED_AROUND_SHORT_CODE = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d'
export const MAX_POST_CHARACTER_COUNT = 3000
export const URL_DISSENTER_SHOP = 'https://shop.dissenter.com'
export const PLACEHOLDER_MISSING_HEADER_SRC = '/original/missing.png'
export const POPOVER_CONTENT_WARNING = 'CONTENT_WARNING'

View File

@ -48,7 +48,13 @@ const makeMapStateToProps = () => {
const getStatus = makeGetStatus();
const mapStateToProps = (state, props) => {
const status = getStatus(state, props)
const statusId = props.id || props.params.statusId
const username = props.params ? props.params.username : undefined
const status = getStatus(state, {
id: statusId,
username: username,
})
// : todo : if is comment (i.e. if any ancestorsIds) use comment not status

View File

@ -27,8 +27,8 @@ export default class ComposeExtraButton extends PureComponent {
} = this.props
const btnClasses = cx({
backgroundColorSubtle_onHover: !active,
backgroundColorBrandLight: active,
bgSubtle_onHover: !active,
bgBrandLight: active,
py10: !small,
px10: !small,
py5: small,
@ -37,8 +37,8 @@ export default class ComposeExtraButton extends PureComponent {
})
const iconClasses = cx({
fillColorSecondary: !active,
fillColorWhite: active,
fillSecondary: !active,
fillWhite: active,
})
const iconSize = !!small ? '14px' : '16px'

View File

@ -257,7 +257,7 @@ class ComposeForm extends ImmutablePureComponent {
alignItemsEnd: shouldCondense,
flexRow: shouldCondense,
radiusSmall: shouldCondense,
backgroundColorSubtle: shouldCondense,
bgSubtle: shouldCondense,
px5: shouldCondense,
})
@ -427,7 +427,7 @@ class ComposeForm extends ImmutablePureComponent {
isDisabled={disabledButton}
backgroundColor='none'
color='brand'
className={[_s.fontSize15PX, _s.px15].join(' ')}
className={[_s.fs15PX, _s.px15].join(' ')}
onClick={this.handleSubmit}
>
{intl.formatMessage(scheduledAt ? messages.schedulePost : messages.publish)}

View File

@ -278,7 +278,7 @@ class PollFormOption extends ImmutablePureComponent {
className={[_s.ml5, _s.justifyContentCenter].join(' ')}
icon='close'
iconSize='8px'
iconClassName={_s.fillColorSecondary}
iconClassName={_s.fillSecondary}
disabled={index <= 1}
title={intl.formatMessage(messages.remove_option)}
onClick={this.handleOptionRemove}

View File

@ -88,7 +88,7 @@ class Followers extends ImmutablePureComponent {
>
{
!!accountIds && accountIds.map((id) => (
<Account key={`follower-${id}`} id={id} compact />
<Account key={`follower-${id}`} id={id} compact withBio />
))
}
</ScrollableList>

View File

@ -88,7 +88,7 @@ class Following extends ImmutablePureComponent {
>
{
!!accountIds && accountIds.map((id) => (
<Account key={`following-${id}`} id={id} compact />
<Account key={`following-${id}`} id={id} compact withBio />
))
}
</ScrollableList>

View File

@ -10,6 +10,7 @@ import StatusList from '../components/status_list'
import ColumnIndicator from '../components/column_indicator'
import Button from '../components/button'
import Text from '../components/text'
import Block from '../components/block'
const mapStateToProps = (state, props) => ({
list: state.getIn(['lists', props.params.id]),
@ -85,7 +86,7 @@ class ListTimeline extends ImmutablePureComponent {
}
const emptyMessage = (
<div className={[_s.default].join(' ')}>
<div className={[_s.default, _s.py15, _s.px15].join(' ')}>
<FormattedMessage
id='empty_column.list'
defaultMessage='There is nothing in this list yet. When members of this list post new statuses, they will appear here.'
@ -95,7 +96,7 @@ class ListTimeline extends ImmutablePureComponent {
onClick={this.handleEditClick}
className={[_s.mt10]}
>
<Text color='inherit'>
<Text color='inherit' align='center'>
<FormattedMessage id='list.click_to_add' defaultMessage='Click here to add people' />
</Text>
</Button>

View File

@ -16,9 +16,7 @@ const mapStateToProps = (state) => ({
})
const mapDispatchToProps = (dispatch) => ({
onFetchLists() {
return dispatch(fetchLists())
},
onFetchLists: () => dispatch(fetchLists()),
})
export default
@ -37,7 +35,7 @@ class ListsDirectory extends ImmutablePureComponent {
}
updateOnProps = [
'lists'
'lists',
]
componentDidMount() {

View File

@ -13,6 +13,7 @@ import Heading from '../components/heading'
import Button from '../components/button'
import Text from '../components/text'
import Account from '../components/account'
import PanelLayout from '../components/panel/panel_layout'
const mapStateToProps = (state) => ({
results: state.getIn(['search', 'results']),
@ -38,14 +39,14 @@ class Search extends ImmutablePureComponent {
isSmallScreen: (window.innerWidth <= 895),
}
render () {
render() {
const { results, location } = this.props
const { isSmallScreen } = this.state
console.log("results:", results)
if (results.isEmpty() && isSmallScreen) {
return (
<div />
)
return null
}
const pathname = location.pathname || ''
@ -53,58 +54,94 @@ class Search extends ImmutablePureComponent {
const showHashtags = pathname === '/search/hashtags'
const showGroups = pathname === '/search/groups'
const isTop = !showPeople && !showHashtags && !showGroups
const theLimit = 10
let accounts, statuses, hashtags, groups
if (results.get('accounts') && results.get('accounts').size > 0 && (isTop || showPeople)) {
const size = isTop ? Math.min(results.get('accounts').size, 5) : results.get('accounts').size;
accounts = (
<Block>
<div className={[_s.default, _s.py15].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.mb15, _s.px15].join(' ')}>
<Heading size='h2'>
People
</Heading>
<div className={[_s.default, _s.mlAuto].join(' ')}>
<Button
isText
backgroundColor='none'
color='brand'
to='/search/people'
>
<Text size='small' color='inherit' weight='bold'>
See All
</Text>
</Button>
</div>
</div>
// : todo : statuses
{
results.get('accounts').slice(0, size).map(accountId => <Account compact key={accountId} id={accountId} />)
}
if (results.get('accounts') && results.get('accounts').size > 0 && (isTop || showPeople)) {
const size = isTop ? Math.min(results.get('accounts').size, theLimit) : results.get('accounts').size;
const isMax = size === results.get('accounts').size
accounts = (
<PanelLayout
title='People'
headerButtonTo={isMax ? undefined : '/search/people'}
headerButtonTitle={isMax ? undefined : 'See more'}
footerButtonTo={isMax ? undefined : '/search/people'}
footerButtonTitle={isMax ? undefined : 'See more'}
noPadding
>
<div className={[_s.default, _s.pb10, _s.px15, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
<Text color='tertiary' size='small'>
Showing {size} of {results.get('accounts').size} results
</Text>
</div>
</Block>
{
results.get('accounts').slice(0, size).map(accountId => (
<Account
compact
withBio
key={accountId}
id={accountId}
/>
))
}
</PanelLayout>
)
}
if (results.get('groups') && results.get('groups').size > 0 && (isTop || showGroups)) {
const size = isTop ? Math.min(results.get('groups').size, 5) : 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
groups = (
<div className='search-results__section'>
<h5><Icon id='users' fixedWidth /><FormattedMessage id='search_results.groups' defaultMessage='Groups' /></h5>
{results.get('groups').slice(0, size).map(group => <GroupListItem key={`search-${group.get('name')}`} group={group} />)}
<PanelLayout
title='Groups'
headerButtonTo={isMax ? undefined : '/search/groups'}
headerButtonTitle={isMax ? undefined : 'See more'}
footerButtonTo={isMax ? undefined : '/search/groups'}
footerButtonTitle={isMax ? undefined : 'See more'}
noPadding
>
<div className={[_s.default, _s.pb10, _s.px15, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
<Text color='tertiary' size='small'>
Showing {size} of {results.get('groups').size} results
</Text>
</div>
);
{
results.get('groups').slice(0, size).map(group => (
<GroupListItem
key={`search-${group.get('name')}`}
id={group.get('id')}
/>
))
}
</PanelLayout>
)
}
if (results.get('hashtags') && results.get('hashtags').size > 0 && (isTop || showHashtags)) {
const size = isTop ? Math.min(results.get('hashtags').size, 5) : 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
hashtags = (
<div className='search-results__section'>
<h5><Icon id='hashtag' fixedWidth /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></h5>
{results.get('hashtags').slice(0, size).map(hashtag => <HashtagItem isCompact key={hashtag.get('name')} hashtag={hashtag} />)}
<PanelLayout
title='Hashtags'
headerButtonTo={isMax ? undefined : '/search/hashtags'}
headerButtonTitle={isMax ? undefined : 'See more'}
footerButtonTo={isMax ? undefined : '/search/hashtags'}
footerButtonTitle={isMax ? undefined : 'See more'}
noPadding
>
<div className={[_s.default, _s.pb10, _s.px15, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
<Text color='tertiary' size='small'>
Showing {size} of {results.get('hashtags').size} results
</Text>
</div>
);
{results.get('hashtags').slice(0, size).map(hashtag => <HashtagItem isCompact key={hashtag.get('name')} hashtag={hashtag} />)}
</PanelLayout>
)
}
return (

View File

@ -0,0 +1,12 @@
import StatusContainer from '../containers/status_container'
export default class Status extends PureComponent {
render() {
console.log("this.props:", this.props)
return (
<StatusContainer {...this.props} />
)
}
}

View File

@ -63,7 +63,7 @@ import {
Notifications,
Search,
// Shortcuts,
Status,
StatusFeature,
StatusLikes,
StatusReposts,
} from './util/async_components'
@ -206,7 +206,7 @@ class SwitchingArea extends PureComponent {
<WrappedRoute path='/:username/likes' page={ProfilePage} component={LikedStatuses} content={children} />
<Redirect from='/@:username/posts/:statusId' to='/:username/posts/:statusId' exact />
<WrappedRoute path='/:username/posts/:statusId' publicRoute exact page={BasicPage} component={Status} content={children} componentParams={{ title: 'Status' }} />
<WrappedRoute path='/:username/posts/:statusId' publicRoute exact page={BasicPage} component={StatusFeature} content={children} componentParams={{ title: 'Status' }} />
<Redirect from='/@:username/posts/:statusId/reposts' to='/:username/posts/:statusId/reposts' />
<WrappedRoute path='/:username/posts/:statusId/reposts' page={BasicPage} component={StatusReposts} content={children} componentParams={{ title: 'Reposts' }} />
@ -497,7 +497,7 @@ class UI extends PureComponent {
return (
<div ref={this.setRef}>
<LoadingBar className={[_s.height1PX, _s.z3, _s.backgroundColorBrandLight].join(' ')} />
<LoadingBar className={[_s.height1PX, _s.z3, _s.bgBrandLight].join(' ')} />
<SwitchingArea location={location} onLayoutChange={this.handleLayoutChange}>
{children}

View File

@ -59,6 +59,7 @@ export function ReportModal() { return import(/* webpackChunkName: "modals/repor
export function RepostOptionsPopover() { return import(/* webpackChunkName: "components/repost_options_popover" */'../../../components/popover/repost_options_popover') }
export function Search() { return import(/*webpackChunkName: "features/search" */'../../search') }
export function Status() { return import(/* webpackChunkName: "components/status" */'../../../components/status') }
export function StatusFeature() { return import(/* webpackChunkName: "features/status" */'../../status') }
export function SearchPopover() { return import(/* webpackChunkName: "components/search_popover" */'../../../components/popover/search_popover') }
export function SidebarMorePopover() { return import(/* webpackChunkName: "components/sidebar_more_popover" */'../../../components/popover/sidebar_more_popover') }
export function StatusLikes() { return import(/* webpackChunkName: "features/status_likes" */'../../status_likes') }

View File

@ -1,9 +1,9 @@
import Sticky from 'react-stickynode'
import * as Constants from '../constants'
import Search from '../components/search'
import ColumnHeader from '../components/column_header'
import Sidebar from '../components/sidebar'
// import Header from '../components/header'
import { BREAKPOINT_EXTRA_SMALL } from '../constants'
import NavigationBar from '../components/navigation_bar'
// import Footer from '../components/footer'
import FloatingActionButton from '../components/floating_action_button'
import Responsive from '../features/ui/util/responsive_component'
@ -36,44 +36,25 @@ export default class Layout extends PureComponent {
} = this.props
return (
<div className={[_s.default, _s.flexRow, _s.width100PC, _s.heightMin100VH, _s.backgroundColorSecondary3].join(' ')}>
<div className={[_s.default, _s.width100PC, _s.heightMin100VH, _s.bgTertiary].join(' ')}>
<NavigationBar
title={title}
tabs={tabs}
actions={actions}
/>
<div className={[_s.default, _s.flexRow, _s.width100PC].join(' ')}>
{
!noSidebar &&
<Responsive min={Constants.BREAKPOINT_EXTRA_SMALL}>
<Sidebar />
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
<Sidebar title={title} tabs={tabs} actions={actions} />
</Responsive>
}
<main role='main' className={[_s.default, _s.flexShrink1, _s.flexGrow1, _s.borderColorSecondary, _s.borderLeft1PX].join(' ')}>
<main role='main' className={[_s.default, _s.flexShrink1, _s.flexGrow1].join(' ')}>
{
!noHeader &&
<div className={[_s.default, _s.height53PX, _s.borderBottom1PX, _s.borderColorSecondary, _s.backgroundColorSecondary3, _s.z3, _s.top0, _s.posFixed].join(' ')}>
<div className={[_s.default, _s.height53PX, _s.pl15, _s.width1015PX, _s.flexRow, _s.justifyContentSpaceBetween].join(' ')}>
<div className={[_s.default, _s.width645PX].join(' ')}>
<ColumnHeader
title={title}
showBackBtn={showBackBtn}
actions={actions}
tabs={tabs}
/>
</div>
<Responsive min={Constants.BREAKPOINT_EXTRA_SMALL}>
<div className={[_s.default, _s.width340PX].join(' ')}>
<Search />
</div>
</Responsive>
</div>
</div>
}
{
!noHeader &&
<div className={[_s.default, _s.height53PX].join(' ')}></div>
}
<div className={[_s.default, _s.width1015PX, _s.flexRow, _s.justifyContentSpaceBetween, _s.pl15, _s.py15].join(' ')}>
<div className={[_s.default, _s.width1015PX, _s.flexRow, _s.justifyContentEnd, _s.py15].join(' ')}>
{
noRightSidebar && children
@ -90,8 +71,8 @@ export default class Layout extends PureComponent {
{
!noRightSidebar &&
<Responsive min={Constants.BREAKPOINT_EXTRA_SMALL}>
<div className={[_s.default, _s.width340PX].join(' ')}>
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
<div className={[_s.default, _s.width340PX, _s.ml15].join(' ')}>
<Sticky top={73} enabled>
<div className={[_s.default, _s.width340PX].join(' ')}>
{layout}
@ -103,7 +84,7 @@ export default class Layout extends PureComponent {
{
!noComposeButton &&
<Responsive max={Constants.BREAKPOINT_EXTRA_SMALL}>
<Responsive max={BREAKPOINT_EXTRA_SMALL}>
<FloatingActionButton />
</Responsive>
}
@ -111,7 +92,7 @@ export default class Layout extends PureComponent {
</div>
</main>
</div>
</div>
)
}

View File

@ -1,8 +1,8 @@
import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
import Sticky from 'react-stickynode'
import Layout from './layout'
import ProfileHeader from '../components/profile_header'
import NavigationBar from '../components/navigation_bar'
export default class ProfileLayout extends ImmutablePureComponent {
static propTypes = {
@ -18,38 +18,48 @@ export default class ProfileLayout extends ImmutablePureComponent {
account,
children,
layout,
title,
showBackBtn,
} = this.props
return (
<Layout
noRightSidebar
noComposeButton
>
<div className={[_s.default, _s.width1015PX, _s.flexRow, _s.justifyContentSpaceBetween, _s.pr15].join(' ')}>
<div className={[_s.default, _s.z1, _s.width100PC].join(' ')}>
<div className={[_s.default, _s.width100PC, _s.heightMin100VH, _s.bgTertiary].join(' ')}>
<NavigationBar />
<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.width100PC, _s.flexRow, _s.justifyContentSpaceBetween, _s.py15].join(' ')}>
<div className={[_s.default, _s.width645PX, _s.z1].join(' ')}>
<div className={_s.default}>
{children}
</div>
</div>
<div className={[_s.default, _s.width340PX].join(' ')}>
<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(' ')}>
{layout}
</div>
</Sticky>
</div>
<div className={[_s.default, _s.width645PX, _s.z1].join(' ')}>
<div className={_s.default}>
{children}
</div>
</div>
</div>
</div>
</div>
</Layout>
</div>
</main>
</div>
)
}

View File

@ -14,13 +14,13 @@ export default class SettingsLayout extends PureComponent {
const { children, actions, tabs, title } = this.props
return (
<div className={[_s.default, _s.flexRow, _s.width100PC, _s.heightMin100VH, _s.backgroundColorSecondary3].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.width100PC, _s.heightMin100VH, _s.bgTertiary].join(' ')}>
<Sidebar />
<main role='main' className={[_s.default, _s.flexShrink1, _s.flexGrow1, _s.borderColorSecondary, _s.borderLeft1PX].join(' ')}>
<div className={[_s.default, _s.height53PX, _s.borderBottom1PX, _s.borderColorSecondary, _s.backgroundColorSecondary3, _s.z3, _s.top0, _s.posFixed].join(' ')}>
<div className={[_s.default, _s.height53PX, _s.borderBottom1PX, _s.borderColorSecondary, _s.bgTertiary, _s.z3, _s.top0, _s.posFixed].join(' ')}>
<div className={[_s.default, _s.height53PX, _s.pl15, _s.width1015PX, _s.flexRow, _s.justifyContentSpaceBetween].join(' ')}>
<div className={[_s.default, _s.width100PC].join(' ')}>
<ColumnHeader

View File

@ -12,7 +12,7 @@ import DefaultLayout from '../layouts/default_layout'
const messages = defineMessages({
groups: { id: 'groups', defaultMessage: 'Groups' },
featured: { id: 'featured', defaultMessage: 'Featured' },
new: { id: 'new', defaultMessage: 'New' },
new: { id: 'new', defaultMessage: 'Just Added' },
myGroups: { id: 'my_groups', defaultMessage: 'My Groups' },
admin: { id: 'admin', defaultMessage: 'Admin' },
})
@ -50,7 +50,7 @@ class GroupsPage extends PureComponent {
const actions = []
const tabs = [
{
title: intl.formatMessage(messages.groups),
title: intl.formatMessage(messages.featured),
to: '/groups',
},
{

View File

@ -38,10 +38,6 @@ class SearchPage extends PureComponent {
title: 'Groups',
to: '/search/groups'
},
{
title: 'Gabs',
to: '/search/gabs'
},
{
title: 'Trends',
to: '/search/trends'

View File

@ -2,6 +2,7 @@ import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
import { GROUPS_FETCH_SUCCESS } from '../actions/groups';
const initialState = ImmutableMap({
new: ImmutableList(),
featured: ImmutableList(),
member: ImmutableList(),
admin: ImmutableList(),

View File

@ -12,8 +12,8 @@
--font_size_extra_large: 19px;
--font_size_extra_extra_large: 24px;
--color_brand-dark: #38a16b;
--color_brand-light: #36e991;
--color_brand-dark: #378e61;
--color_brand-light: #63DA9D;
--color_brand-light-opaque: rgb(54, 233, 145, .125);
--color_brand: #21cf7a;
@ -30,7 +30,7 @@
--solid_color_primary-opaque:rgba(255, 255, 255,.6);
--solid_color_secondary: #e2e8ec;
--solid_color_secondary-dark: #d9e0e5;
--solid_color_tertiary: #f6f6f9;
--solid_color_tertiary: #f5f5f7;
--solid_color_block: #f5f8fa;
--text_color_primary: #2d3436;
@ -214,6 +214,7 @@ body {
.justifyContentSpaceBetween { justify-content: space-between; }
.justifyContentCenter { justify-content: center; }
.justifyContentEnd { justify-content: flex-end; }
.overflowHidden {
overflow-x: hidden;
@ -230,6 +231,8 @@ body {
white-space: nowrap;
}
.textUppercase { text-transform: uppercase; }
.whiteSpaceNoWrap { white-space: nowrap; }
.outlineNone { outline: none; }
@ -295,39 +298,39 @@ body {
);
}
.backgroundTransparent { background-color: transparent; }
.bgTransparent { background-color: transparent; }
.backgroundColorLoading { background-color: #ccc; }
.bgLoading { background-color: #ccc; }
.backgroundColorSubtle { background-color: var(--solid_color_block); }
.backgroundColorSubtle_onHover:hover { background-color: var(--solid_color_block); }
.bgSubtle { background-color: var(--solid_color_block); }
.bgSubtle_onHover:hover { background-color: var(--solid_color_block); }
.backgroundColorSubtle2 { background-color: var(--solid_color_secondary); }
.backgroundColorSubtle2Dark_onHover:hover { background-color: var(--solid_color_secondary-dark); }
.bgSecondary { background-color: var(--solid_color_secondary); }
.bgSecondaryDark_onHover:hover { background-color: var(--solid_color_secondary-dark); }
.backgroundColorSecondary3 { background-color: var(--solid_color_tertiary); }
.bgTertiary { background-color: var(--solid_color_tertiary); }
.backgroundColorPrimary { background-color: var(--solid_color_primary); }
.backgroundColorPrimaryOpaque { background-color: var(--solid_color_primary-opaque) }
.bgPrimary { background-color: var(--solid_color_primary); }
.bgPrimaryOpaque { background-color: var(--solid_color_primary-opaque) }
.backgroundColorWhite { background-color: var(--color_white); }
.bgWhite { background-color: var(--color_white); }
.backgroundColorBlack { background-color: var(--color_black); }
.backgroundColorBlackOpaque { background-color: var(--color_black-opaquer); }
.backgroundColorBlackOpaque_onHover:hover { background-color: var(--color_black-opaque); }
.bgBlack { background-color: var(--color_black); }
.bgBlackOpaque { background-color: var(--color_black-opaquer); }
.bgBlackOpaque_onHover:hover { background-color: var(--color_black-opaque); }
.backgroundColorBrand { background-color: var(--color_brand); }
.backgroundColorBrand_onHover:hover { background-color: var(--color_brand); }
.bgBrand { background-color: var(--color_brand); }
.bgBrand_onHover:hover { background-color: var(--color_brand); }
.backgroundColorBrandLight { background-color: var(--color_brand-light); }
.backgroundColorBrandLightOpaque { background-color: var(--color_brand-light-opaque); }
.backgroundColorBrandLightOpaque_onHover:hover { background-color: var(--color_brand-light-opaque); }
.bgBrandLight { background-color: var(--color_brand-light); }
.bgBrandLightOpaque { background-color: var(--color_brand-light-opaque); }
.bgBrandLightOpaque_onHover:hover { background-color: var(--color_brand-light-opaque); }
.backgroundColorBrandDark { background-color: var(--color_brand-dark); }
.backgroundColorBrandDark_onHover:hover { background-color: var(--color_brand-dark); }
.bgBrandDark { background-color: var(--color_brand-dark); }
.bgBrandDark_onHover:hover { background-color: var(--color_brand-dark); }
.backgroundColorDanger { background-color: var(--color_red); }
.backgroundColorDangerDark_onHover:hover { background-color: var(--color_red-dark); }
.bgDanger { background-color: var(--color_red); }
.bgDangerDark_onHover:hover { background-color: var(--color_red-dark); }
/* */
@ -344,14 +347,15 @@ body {
/* */
.fillColorPrimary { fill: var(--text_color_primary); }
.fillColorSecondary { fill: var(--text_color_secondary); }
.fillPrimary { fill: var(--text_color_primary); }
.fillSecondary { fill: var(--text_color_secondary); }
.fillColorWhite { fill: var(--color_white); }
.fillColorWhite_onHover:hover { fill: var(--color_white); }
.fillWhite { fill: var(--color_white); }
.fillWhite_onHover:hover { fill: var(--color_white); }
.fillColorBrand { fill: var(--color_brand); }
.fillColorBrand_onHover:hover { fill: var(--color_brand);}
.fillBrand { fill: var(--color_brand); }
.fillBrandDark { fill: var(--color_brand-dark); }
.fillBrand_onHover:hover { fill: var(--color_brand);}
.fillColorGabPro { fill: var(--color_gold); }
@ -391,12 +395,12 @@ body {
.heightMax100VH { max-height: 100vh; }
.heightMax80VH { max-height: 80vh; }
.heightMax56PX { max-height: 56px; }
.heightCalc53PX { height: calc(100vh - 53px); }
.heightMin100VH { min-height: 100vh; }
.heightMin50VH { min-height: 50vh; }
.heightMin50PX { min-height: 50px; }
.height100VH { height: 100vh; }
.height100PC { height: 100%; }
.height350PX { height: 350px; }
.height260PX { height: 260px; }
@ -405,7 +409,6 @@ body {
.height122PX { height: 122px; }
.height72PX { height: 72px; }
.height53PX { height: 53px; }
.height50PX { height: 50px; }
.height40PX { height: 40px; }
.height24PX { height: 24px; }
.height22PX { height: 22px; }
@ -418,6 +421,7 @@ body {
.width100PC { width: 100%; }
.width50PC { width: 50%; }
.width25PC { width: 25%; }
.width1255PX { width: 1255px; }
.width1015PX { width: 1015px; }
.width645PX { width: 645px; }
.width340PX { width: 340px; }
@ -429,6 +433,7 @@ body {
.width50PX { width: 50px; }
.width20PX { width: 20px; }
.width4PX { width: 4px; }
.width1PX { width: 1px; }
@media (min-width: 1480px) {
@ -507,6 +512,8 @@ body {
.width1015PX {
max-width: 600px;
width: 100%;
margin-left: auto;
margin-right: auto;
}
.width645PX {
@ -526,14 +533,14 @@ body {
.textAlignLeft { text-align: left; }
.textAlignCenter { text-align: center; }
.fontSize24PX { font-size: var(--font_size_extra_extra_large); }
.fontSize19PX { font-size: var(--font_size_extra_large); }
.fontSize16PX { font-size: var(--font_size_large); }
.fontSize15PX { font-size: var(--font_size_medium); }
.fontSize14PX { font-size: var(--font_size_normal); }
.fontSize13PX { font-size: var(--font_size_small); }
.fontSize12PX { font-size: var(--font_size_extra_small); }
.fontSize0 { font-size: 0; }
.fs24PX { font-size: var(--font_size_extra_extra_large); }
.fs19PX { font-size: var(--font_size_extra_large); }
.fs16PX { font-size: var(--font_size_large); }
.fs15PX { font-size: var(--font_size_medium); }
.fs14PX { font-size: var(--font_size_normal); }
.fs13PX { font-size: var(--font_size_small); }
.fs12PX { font-size: var(--font_size_extra_small); }
.fs0 { font-size: 0; }
.fontWeightNormal { font-weight: 400; }
.fontWeightMedium { font-weight: 500; }
@ -562,7 +569,7 @@ body {
margin-bottom: 10px;
}
.margin1PX { margin: 1px; }
.m1PX { margin: 1px; }
.mr15 { margin-right: 15px; }
.mr10 { margin-right: 10px; }
@ -602,9 +609,12 @@ body {
.pl25 { padding-left: 25px; }
.pl15 { padding-left: 15px; }
.pl10 { padding-left: 10px; }
.pl5 { padding-left: 5px; }
.pl0 { padding-left: 0; }
.pr15 { padding-right: 15px; }
.pr10 { padding-right: 10px; }
.pr5 { padding-right: 5px; }
.pr0 { padding-right: 0; }
@ -618,6 +628,11 @@ body {
padding-bottom: 5px;
}
.py7 {
padding-top: 7px;
padding-bottom: 7px;
}
.py10 {
padding-top: 10px;
padding-bottom: 10px;
@ -658,6 +673,7 @@ body {
.boxShadowNone .boxShadowBlock {
box-shadow: none !important;
border-radius: 0 !important;
}
.boxShadowAvatarPro {
@ -727,6 +743,19 @@ body {
visibility: hidden;
}
.searchInput::placeholder {
color: rgba(255,255,255,0.65);
opacity: 1;
}
.searchInput:-ms-input-placeholder {
color: rgba(255,255,255,0.65);
}
.searchInput::-ms-input-placeholder {
color: rgba(255,255,255,0.65);
}
/**
* Rich Text Editor
*/

View File

@ -2,7 +2,7 @@
class SearchService < BaseService
def call(query, account, limit, options = {})
@query = query.strip
@query = query&.strip
@account = account
@options = options
@limit = limit.to_i
@ -10,8 +10,10 @@ class SearchService < BaseService
@resolve = options[:resolve] || false
default_results.tap do |results|
next if @query.blank? || @limit.zero?
if url_query?
results.merge!(url_resource_results) unless url_resource.nil?
results.merge!(url_resource_results) unless url_resource.nil? || @offset.positive? || (@options[:type].present? && url_resource_symbol != @options[:type].to_sym)
elsif @query.present?
results[:accounts] = perform_accounts_search! if account_searchable?
results[:statuses] = perform_statuses_search! if full_text_searchable?
@ -79,7 +81,7 @@ class SearchService < BaseService
end
def url_query?
@options[:type].blank? && @query =~ /\Ahttps?:\/\//
@resolve && @query =~ /\Ahttps?:\/\//
end
def url_resource_results