Added Gab Deck initial mvp
• Added: - Gab Deck initial mvp
This commit is contained in:
parent
2f798ca1bd
commit
ba8e8942dc
|
@ -52,7 +52,7 @@ class ReactController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_route_matches
|
def find_route_matches
|
||||||
request.path.match(/\A\/(home|news|api|suggestions|links|chat_conversations|chat_conversation_accounts|messages|shortcuts|group|groups|list|lists|notifications|tags|compose|follow_requests|admin|account|settings|filters|timeline|blocks|mutes)/)
|
request.path.match(/\A\/(home|news|api|deck|suggestions|links|chat_conversations|chat_conversation_accounts|messages|shortcuts|group|groups|list|lists|notifications|tags|compose|follow_requests|admin|account|settings|filters|timeline|blocks|mutes)/)
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_public_route_matches
|
def find_public_route_matches
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import DeckColumnHeader from './deck_column_header'
|
||||||
|
|
||||||
|
class DeckColumn extends React.PureComponent {
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
title,
|
||||||
|
subtitle,
|
||||||
|
icon,
|
||||||
|
children,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={[_s.d, _s.w360PX, _s.px2, _s.bgSecondary, _s.h100VH].join(' ')}>
|
||||||
|
<div className={[_s.d, _s.w100PC, _s.bgPrimary, _s.h100VH].join(' ')}>
|
||||||
|
<DeckColumnHeader title={title} subtitle={subtitle} icon={icon} />
|
||||||
|
<div className={[_s.d, _s.w100PC, _s.overflowYScroll, _s.boxShadowNone, _s.posAbs, _s.top60PX, _s.left0, _s.right0, _s.bottom0].join(' ')}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DeckColumn.propTypes = {
|
||||||
|
title: PropTypes.string,
|
||||||
|
subtitle: PropTypes.string,
|
||||||
|
icon: PropTypes.string,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DeckColumn
|
|
@ -0,0 +1,43 @@
|
||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import Icon from './icon'
|
||||||
|
import Text from './text'
|
||||||
|
import Button from './button'
|
||||||
|
|
||||||
|
class DeckColumnHeader extends React.PureComponent {
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
title,
|
||||||
|
subtitle,
|
||||||
|
icon,
|
||||||
|
children,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={[_s.d, _s.w100PC, _s.flexRow, _s.aiCenter, _s.h60PX, _s.px15, _s.py10, _s.borderBottom1PX, _s.borderColorSecondary, _s.bgPrimary].join(' ')}>
|
||||||
|
<Icon id={icon} className={_s.cPrimary} size='20px' />
|
||||||
|
<div className={[_s.d, _s.flexRow, _s.aiEnd, _s.ml15].join(' ')}>
|
||||||
|
<Text size='large' weight='medium'>{title}</Text>
|
||||||
|
{ !!subtitle && <Text className={_s.ml5} size='small' color='secondary'>{subtitle}</Text> }
|
||||||
|
</div>
|
||||||
|
<div className={[_s.d, _s.aiCenter, _s.mlAuto, _s.jcCenter].join(' ')}>
|
||||||
|
<Button
|
||||||
|
color='primary'
|
||||||
|
backgroundColor='none'
|
||||||
|
icon='list'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DeckColumnHeader.propTypes = {
|
||||||
|
title: PropTypes.string,
|
||||||
|
subtitle: PropTypes.string,
|
||||||
|
icon: PropTypes.string,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DeckColumnHeader
|
|
@ -75,6 +75,7 @@ class DisplayName extends ImmutablePureComponent {
|
||||||
isSmall,
|
isSmall,
|
||||||
isComment,
|
isComment,
|
||||||
isCentered,
|
isCentered,
|
||||||
|
isInline,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
if (!account) return null
|
if (!account) return null
|
||||||
|
@ -86,6 +87,7 @@ class DisplayName extends ImmutablePureComponent {
|
||||||
flexRow: !isMultiline,
|
flexRow: !isMultiline,
|
||||||
cursorPointer: !noHover,
|
cursorPointer: !noHover,
|
||||||
aiCenter: isCentered,
|
aiCenter: isCentered,
|
||||||
|
displayInlineBlock: isInline,
|
||||||
})
|
})
|
||||||
|
|
||||||
const displayNameClasses = CX({
|
const displayNameClasses = CX({
|
||||||
|
@ -209,6 +211,7 @@ DisplayName.propTypes = {
|
||||||
noUsername: PropTypes.bool,
|
noUsername: PropTypes.bool,
|
||||||
isComment: PropTypes.bool,
|
isComment: PropTypes.bool,
|
||||||
isCentered: PropTypes.bool,
|
isCentered: PropTypes.bool,
|
||||||
|
isInline: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (connect(null, mapDispatchToProps)(DisplayName))
|
export default (connect(null, mapDispatchToProps)(DisplayName))
|
|
@ -33,6 +33,7 @@ class Notification extends ImmutablePureComponent {
|
||||||
statusId,
|
statusId,
|
||||||
isHidden,
|
isHidden,
|
||||||
isUnread,
|
isUnread,
|
||||||
|
isCompact,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
const count = !!accounts ? accounts.size : 0
|
const count = !!accounts ? accounts.size : 0
|
||||||
|
@ -92,7 +93,7 @@ class Notification extends ImmutablePureComponent {
|
||||||
|
|
||||||
const containerClasses = CX({
|
const containerClasses = CX({
|
||||||
d: 1,
|
d: 1,
|
||||||
px10: 1,
|
px10: !isCompact,
|
||||||
cursorPointer: 1,
|
cursorPointer: 1,
|
||||||
bgSubtle_onHover: !isUnread,
|
bgSubtle_onHover: !isUnread,
|
||||||
highlightedComment: isUnread,
|
highlightedComment: isUnread,
|
||||||
|
@ -107,9 +108,12 @@ class Notification extends ImmutablePureComponent {
|
||||||
<div className={[_s.d, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
|
<div className={[_s.d, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
|
||||||
<div className={[_s.d, _s.flexRow, _s.my10, _s.py10, _s.px10].join(' ')}>
|
<div className={[_s.d, _s.flexRow, _s.my10, _s.py10, _s.px10].join(' ')}>
|
||||||
|
|
||||||
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
|
{
|
||||||
<Icon id={icon} size='20px' className={[_s.cPrimary, _s.minW20PX, _s.mt5, _s.mr15].join(' ')} />
|
!isCompact &&
|
||||||
</Responsive>
|
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
|
||||||
|
<Icon id={icon} size='20px' className={[_s.cPrimary, _s.minW20PX, _s.mt5, _s.mr15].join(' ')} />
|
||||||
|
</Responsive>
|
||||||
|
}
|
||||||
|
|
||||||
<div className={[_s.d, _s.flexNormal].join(' ')}>
|
<div className={[_s.d, _s.flexNormal].join(' ')}>
|
||||||
<div className={[_s.d, _s.flexRow, _s.flexWrap].join(' ')}>
|
<div className={[_s.d, _s.flexRow, _s.flexWrap].join(' ')}>
|
||||||
|
@ -126,11 +130,11 @@ class Notification extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className={[_s.d, _s.pt5].join(' ')}>
|
<div className={[_s.d, _s.pt5].join(' ')}>
|
||||||
<div className={[_s.d, _s.flexRow, _s.aiEnd].join(' ')}>
|
<div className={[_s.d, _s.displayInline].join(' ')}>
|
||||||
<div className={_s.text}>
|
<div className={_s.text}>
|
||||||
{
|
{
|
||||||
accounts && accounts.slice(0, 1).map((account, i) => (
|
accounts && accounts.slice(0, 1).map((account, i) => (
|
||||||
<DisplayName key={i} account={account} noUsername />
|
<DisplayName key={i} account={account} noUsername isInline />
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@ -191,6 +195,7 @@ Notification.propTypes = {
|
||||||
type: PropTypes.string.isRequired,
|
type: PropTypes.string.isRequired,
|
||||||
isHidden: PropTypes.bool,
|
isHidden: PropTypes.bool,
|
||||||
isUnread: PropTypes.bool,
|
isUnread: PropTypes.bool,
|
||||||
|
isCompact: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default injectIntl(Notification)
|
export default injectIntl(Notification)
|
|
@ -14,6 +14,10 @@ class SidebarMorePopover extends React.PureComponent {
|
||||||
this.props.onOpenDisplayModal()
|
this.props.onOpenDisplayModal()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleOnClosePopover = () => {
|
||||||
|
this.props.onClosePopover()
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { intl, isXS } = this.props
|
const { intl, isXS } = this.props
|
||||||
|
|
||||||
|
@ -29,6 +33,11 @@ class SidebarMorePopover extends React.PureComponent {
|
||||||
title: intl.formatMessage(messages.help),
|
title: intl.formatMessage(messages.help),
|
||||||
href: 'https://help.gab.com',
|
href: 'https://help.gab.com',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Gab Deck',
|
||||||
|
to: '/deck',
|
||||||
|
onClick: this.handleOnClosePopover,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: intl.formatMessage(messages.display),
|
title: intl.formatMessage(messages.display),
|
||||||
onClick: this.handleOnOpenDisplayModal,
|
onClick: this.handleOnOpenDisplayModal,
|
||||||
|
@ -66,6 +75,9 @@ const messages = defineMessages({
|
||||||
})
|
})
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
onClosePopover() {
|
||||||
|
dispatch(closePopover())
|
||||||
|
},
|
||||||
onOpenDisplayModal: () => {
|
onOpenDisplayModal: () => {
|
||||||
dispatch(closePopover())
|
dispatch(closePopover())
|
||||||
dispatch(openModal(MODAL_DISPLAY_OPTIONS))
|
dispatch(openModal(MODAL_DISPLAY_OPTIONS))
|
||||||
|
|
|
@ -0,0 +1,205 @@
|
||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
|
import { openPopover } from '../../actions/popover'
|
||||||
|
import { changeSetting, saveSettings } from '../../actions/settings'
|
||||||
|
import { resendUserConfirmationEmail } from '../../actions/user'
|
||||||
|
import { openModal } from '../../actions/modal'
|
||||||
|
import {
|
||||||
|
BREAKPOINT_EXTRA_SMALL,
|
||||||
|
MODAL_EMAIL_CONFIRMATION_REMINDER,
|
||||||
|
} from '../../constants'
|
||||||
|
import {
|
||||||
|
me,
|
||||||
|
meEmail,
|
||||||
|
emailConfirmed,
|
||||||
|
} from '../../initial_state'
|
||||||
|
import { makeGetAccount } from '../../selectors'
|
||||||
|
import Responsive from '../../features/ui/util/responsive_component'
|
||||||
|
import {
|
||||||
|
CX,
|
||||||
|
THEMES,
|
||||||
|
DEFAULT_THEME,
|
||||||
|
POPOVER_NAV_SETTINGS,
|
||||||
|
} from '../../constants'
|
||||||
|
import Avatar from '../avatar'
|
||||||
|
import BackButton from '../back_button'
|
||||||
|
import Button from '../button'
|
||||||
|
import Heading from '../heading'
|
||||||
|
import Icon from '../icon'
|
||||||
|
import NavigationBarButton from '../navigation_bar_button'
|
||||||
|
import Search from '../search'
|
||||||
|
import Text from '../text'
|
||||||
|
import Divider from '../divider'
|
||||||
|
|
||||||
|
class DeckSidebar extends ImmutablePureComponent {
|
||||||
|
|
||||||
|
handleOnClickLightBulb = () => {
|
||||||
|
let index = THEMES.findIndex((t) => t === this.props.theme)
|
||||||
|
const nextIndex = (index === THEMES.length -1) ? 0 : index += 1
|
||||||
|
const newTheme = THEMES[nextIndex]
|
||||||
|
this.props.onChange('theme', newTheme)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOnOpenNavSettingsPopover = () => {
|
||||||
|
this.props.onOpenNavSettingsPopover(this.avatarNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOnClickResendConfirmationEmail = () => {
|
||||||
|
const { emailConfirmationResends } = this.props
|
||||||
|
if (emailConfirmationResends % 2 === 0 && emailConfirmationResends > 0) {
|
||||||
|
this.props.onOpenEmailModal()
|
||||||
|
}
|
||||||
|
this.props.onResendUserConfirmationEmail()
|
||||||
|
}
|
||||||
|
|
||||||
|
setAvatarNode = (c) => {
|
||||||
|
this.avatarNode = c
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
title,
|
||||||
|
showBackBtn,
|
||||||
|
actions,
|
||||||
|
tabs,
|
||||||
|
account,
|
||||||
|
noActions,
|
||||||
|
logoDisabled,
|
||||||
|
unreadChatsCount,
|
||||||
|
notificationCount,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
|
const navigationContainerClasses = CX({
|
||||||
|
d: 1,
|
||||||
|
z4: 1,
|
||||||
|
w76PX: 1,
|
||||||
|
w100PC: 1,
|
||||||
|
})
|
||||||
|
|
||||||
|
const innerNavigationContainerClasses = CX({
|
||||||
|
d: 1,
|
||||||
|
w76PX: 1,
|
||||||
|
bgNavigation: 1,
|
||||||
|
aiCenter: 1,
|
||||||
|
z3: 1,
|
||||||
|
top0: 1,
|
||||||
|
bottom0: 1,
|
||||||
|
left0: 1,
|
||||||
|
borderRight1PX: 1,
|
||||||
|
borderColorSecondary: 1,
|
||||||
|
posFixed: 1,
|
||||||
|
})
|
||||||
|
|
||||||
|
const isHome = title === 'Home'
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={navigationContainerClasses}>
|
||||||
|
|
||||||
|
<div className={innerNavigationContainerClasses}>
|
||||||
|
|
||||||
|
<div className={[_s.d, _s.flexRow, _s.w76PX, _s.h100PC].join(' ')}>
|
||||||
|
|
||||||
|
<div className={[_s.d].join(' ')}>
|
||||||
|
|
||||||
|
<h1 className={[_s.d].join(' ')}>
|
||||||
|
<Button
|
||||||
|
to='/'
|
||||||
|
isText
|
||||||
|
title='Gab'
|
||||||
|
aria-label='Gab'
|
||||||
|
color='none'
|
||||||
|
backgroundColor='none'
|
||||||
|
className={[_s.d, _s.jcCenter, _s.noSelect, _s.noUnderline, _s.h53PX, _s.cursorPointer, _s.px10, _s.mr5].join(' ')}
|
||||||
|
>
|
||||||
|
<Icon id='logo' className={_s.fillNavigationBrand} minimizeLogo={logoDisabled} />
|
||||||
|
</Button>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<div className={[_s.d, _s.px10].join(' ')}>
|
||||||
|
|
||||||
|
<NavigationBarButton icon='pencil' />
|
||||||
|
|
||||||
|
<NavigationBarButton icon='search' />
|
||||||
|
|
||||||
|
<Divider isSmall />
|
||||||
|
|
||||||
|
<Divider isSmall />
|
||||||
|
|
||||||
|
<NavigationBarButton title=' ' icon='add' />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={[_s.d, _s.mtAuto, _s.aiCenter].join(' ')}>
|
||||||
|
|
||||||
|
<Divider isSmall />
|
||||||
|
|
||||||
|
<NavigationBarButton attrTitle='Dark/Muted/Light/White Mode' icon='light-bulb' onClick={this.handleOnClickLightBulb} />
|
||||||
|
|
||||||
|
<button
|
||||||
|
ref={this.setAvatarNode}
|
||||||
|
title={account.get('display_name')}
|
||||||
|
onClick={this.handleOnOpenNavSettingsPopover}
|
||||||
|
className={[_s.h53PX, _s.bgTransparent, _s.outlineNone, _s.cursorPointer, _s.d, _s.jcCenter].join(' ')}
|
||||||
|
>
|
||||||
|
<Avatar account={account} size={34} noHover />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({
|
||||||
|
account: makeGetAccount()(state, me),
|
||||||
|
emailConfirmationResends: state.getIn(['user', 'emailConfirmationResends'], 0),
|
||||||
|
theme: state.getIn(['settings', 'displayOptions', 'theme'], DEFAULT_THEME),
|
||||||
|
logoDisabled: state.getIn(['settings', 'displayOptions', 'logoDisabled'], false),
|
||||||
|
notificationCount: state.getIn(['notifications', 'unread']),
|
||||||
|
unreadChatsCount: state.getIn(['chats', 'chatsUnreadCount']),
|
||||||
|
})
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
onOpenNavSettingsPopover(targetRef) {
|
||||||
|
dispatch(openPopover(POPOVER_NAV_SETTINGS, {
|
||||||
|
targetRef,
|
||||||
|
position: 'left-end',
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
onOpenEmailModal() {
|
||||||
|
dispatch(openModal(MODAL_EMAIL_CONFIRMATION_REMINDER))
|
||||||
|
},
|
||||||
|
onResendUserConfirmationEmail() {
|
||||||
|
dispatch(resendUserConfirmationEmail())
|
||||||
|
},
|
||||||
|
onChange(key, value) {
|
||||||
|
dispatch(changeSetting(['displayOptions', key], value))
|
||||||
|
dispatch(saveSettings())
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
DeckSidebar.propTypes = {
|
||||||
|
account: ImmutablePropTypes.map,
|
||||||
|
actions: PropTypes.array,
|
||||||
|
tabs: PropTypes.array,
|
||||||
|
title: PropTypes.string,
|
||||||
|
showBackBtn: PropTypes.bool,
|
||||||
|
notificationCount: PropTypes.number.isRequired,
|
||||||
|
unreadChatsCount: PropTypes.number.isRequired,
|
||||||
|
onOpenNavSettingsPopover: PropTypes.func.isRequired,
|
||||||
|
onOpenEmailModal: PropTypes.func.isRequired,
|
||||||
|
onResendUserConfirmationEmail: PropTypes.func.isRequired,
|
||||||
|
emailConfirmationResends: PropTypes.number.isRequired,
|
||||||
|
noActions: PropTypes.bool,
|
||||||
|
theme: PropTypes.string,
|
||||||
|
logoDisabled: PropTypes.bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(DeckSidebar)
|
|
@ -309,6 +309,7 @@ class Status extends ImmutablePureComponent {
|
||||||
isComposeModalOpen,
|
isComposeModalOpen,
|
||||||
commentSortingType,
|
commentSortingType,
|
||||||
onOpenProModal,
|
onOpenProModal,
|
||||||
|
isCompact,
|
||||||
} = this.props
|
} = this.props
|
||||||
// const { height } = this.state
|
// const { height } = this.state
|
||||||
|
|
||||||
|
@ -361,7 +362,7 @@ class Status extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
const parentClasses = CX({
|
const parentClasses = CX({
|
||||||
pb15: !isChild,
|
pb15: !isChild && !isCompact,
|
||||||
})
|
})
|
||||||
|
|
||||||
const containerClasses = CX({
|
const containerClasses = CX({
|
||||||
|
@ -437,6 +438,7 @@ class Status extends ImmutablePureComponent {
|
||||||
<StatusHeader
|
<StatusHeader
|
||||||
status={status}
|
status={status}
|
||||||
reduced={isChild}
|
reduced={isChild}
|
||||||
|
isCompact={isCompact}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className={_s.d}>
|
<div className={_s.d}>
|
||||||
|
@ -451,7 +453,7 @@ class Status extends ImmutablePureComponent {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<StatusMedia
|
<StatusMedia
|
||||||
isChild={isChild}
|
isChild={isChild || isCompact}
|
||||||
isComposeModalOpen={isComposeModalOpen}
|
isComposeModalOpen={isComposeModalOpen}
|
||||||
status={status}
|
status={status}
|
||||||
onOpenMedia={this.props.onOpenMedia}
|
onOpenMedia={this.props.onOpenMedia}
|
||||||
|
@ -490,11 +492,12 @@ class Status extends ImmutablePureComponent {
|
||||||
onOpenLikes={this.props.onOpenLikes}
|
onOpenLikes={this.props.onOpenLikes}
|
||||||
onOpenReposts={this.props.onOpenReposts}
|
onOpenReposts={this.props.onOpenReposts}
|
||||||
onQuote={this.handleOnQuote}
|
onQuote={this.handleOnQuote}
|
||||||
|
isCompact={isCompact}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
!isChild && !!me &&
|
!isChild && !!me && !isCompact &&
|
||||||
<ResponsiveClassesComponent
|
<ResponsiveClassesComponent
|
||||||
classNames={[_s.d, _s.borderTop1PX, _s.borderColorSecondary, _s.pt10, _s.px15, _s.mb10].join(' ')}
|
classNames={[_s.d, _s.borderTop1PX, _s.borderColorSecondary, _s.pt10, _s.px15, _s.mb10].join(' ')}
|
||||||
classNamesXS={[_s.d, _s.borderTop1PX, _s.borderColorSecondary, _s.pt10, _s.px10, _s.mb10].join(' ')}
|
classNamesXS={[_s.d, _s.borderTop1PX, _s.borderColorSecondary, _s.pt10, _s.px10, _s.mb10].join(' ')}
|
||||||
|
|
|
@ -46,7 +46,11 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { status, intl } = this.props
|
const {
|
||||||
|
status,
|
||||||
|
intl,
|
||||||
|
isCompact,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'))
|
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'))
|
||||||
|
|
||||||
|
@ -66,7 +70,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
|
|
||||||
const containerClasses = CX({
|
const containerClasses = CX({
|
||||||
d: 1,
|
d: 1,
|
||||||
px10: 1,
|
px10: !isCompact,
|
||||||
mt10: !shouldCondense,
|
mt10: !shouldCondense,
|
||||||
mt5: shouldCondense,
|
mt5: shouldCondense,
|
||||||
})
|
})
|
||||||
|
@ -76,8 +80,9 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
py2: 1,
|
py2: 1,
|
||||||
flexRow: 1,
|
flexRow: 1,
|
||||||
w100PC: 1,
|
w100PC: 1,
|
||||||
borderTop1PX: !shouldCondense,
|
borderTop1PX: !shouldCondense && !isCompact,
|
||||||
borderColorSecondary: !shouldCondense,
|
borderColorSecondary: !shouldCondense || isCompact,
|
||||||
|
borderBottom1PX: isCompact,
|
||||||
mt5: hasInteractions,
|
mt5: hasInteractions,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -105,11 +110,19 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
py5: 1,
|
py5: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const interactionContainerClasses = CX({
|
||||||
|
d: 1,
|
||||||
|
flexRow: 1,
|
||||||
|
aiEnd: 1,
|
||||||
|
px5: !isCompact,
|
||||||
|
px15: isCompact,
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={containerClasses}>
|
<div className={containerClasses}>
|
||||||
{
|
{
|
||||||
hasInteractions &&
|
hasInteractions &&
|
||||||
<div className={[_s.d, _s.flexRow, _s.aiEnd, _s.px5].join(' ')}>
|
<div className={interactionContainerClasses}>
|
||||||
{
|
{
|
||||||
favoriteCount > 0 &&
|
favoriteCount > 0 &&
|
||||||
<button
|
<button
|
||||||
|
@ -156,11 +169,13 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
icon={!!status.get('favourited') ? 'liked' : 'like'}
|
icon={!!status.get('favourited') ? 'liked' : 'like'}
|
||||||
active={!!status.get('favourited')}
|
active={!!status.get('favourited')}
|
||||||
onClick={this.handleFavoriteClick}
|
onClick={this.handleFavoriteClick}
|
||||||
|
isCompact={isCompact}
|
||||||
/>
|
/>
|
||||||
<StatusActionBarItem
|
<StatusActionBarItem
|
||||||
title={intl.formatMessage(messages.comment)}
|
title={intl.formatMessage(messages.comment)}
|
||||||
icon='comment'
|
icon='comment'
|
||||||
onClick={this.handleReplyClick}
|
onClick={this.handleReplyClick}
|
||||||
|
isCompact={isCompact}
|
||||||
/>
|
/>
|
||||||
<StatusActionBarItem
|
<StatusActionBarItem
|
||||||
title={intl.formatMessage(messages.repost)}
|
title={intl.formatMessage(messages.repost)}
|
||||||
|
@ -169,6 +184,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
disabled={!publicStatus}
|
disabled={!publicStatus}
|
||||||
active={!!status.get('reblogged')}
|
active={!!status.get('reblogged')}
|
||||||
onClick={this.handleRepostClick}
|
onClick={this.handleRepostClick}
|
||||||
|
isCompact={isCompact}
|
||||||
/>
|
/>
|
||||||
<StatusActionBarItem
|
<StatusActionBarItem
|
||||||
title={intl.formatMessage(messages.quote)}
|
title={intl.formatMessage(messages.quote)}
|
||||||
|
@ -176,6 +192,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
icon={!publicStatus ? 'lock' : 'quote'}
|
icon={!publicStatus ? 'lock' : 'quote'}
|
||||||
disabled={!publicStatus}
|
disabled={!publicStatus}
|
||||||
onClick={this.handleQuoteClick}
|
onClick={this.handleQuoteClick}
|
||||||
|
isCompact={isCompact}
|
||||||
/>
|
/>
|
||||||
<StatusActionBarItem
|
<StatusActionBarItem
|
||||||
title={intl.formatMessage(messages.share)}
|
title={intl.formatMessage(messages.share)}
|
||||||
|
@ -183,6 +200,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
buttonRef={this.setShareButton}
|
buttonRef={this.setShareButton}
|
||||||
icon='share'
|
icon='share'
|
||||||
onClick={this.handleShareClick}
|
onClick={this.handleShareClick}
|
||||||
|
isCompact={isCompact}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -214,6 +232,7 @@ StatusActionBar.propTypes = {
|
||||||
status: ImmutablePropTypes.map.isRequired,
|
status: ImmutablePropTypes.map.isRequired,
|
||||||
onOpenLikes: PropTypes.func.isRequired,
|
onOpenLikes: PropTypes.func.isRequired,
|
||||||
onOpenReposts: PropTypes.func.isRequired,
|
onOpenReposts: PropTypes.func.isRequired,
|
||||||
|
isCompact: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default injectIntl(StatusActionBar)
|
export default injectIntl(StatusActionBar)
|
|
@ -18,20 +18,21 @@ class StatusActionBarItem extends React.PureComponent {
|
||||||
active,
|
active,
|
||||||
disabled,
|
disabled,
|
||||||
buttonRef,
|
buttonRef,
|
||||||
altTitle
|
altTitle,
|
||||||
|
isCompact,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
const btnClasses = CX({
|
const btnClasses = CX({
|
||||||
jcCenter: 1,
|
jcCenter: 1,
|
||||||
aiCenter: 1,
|
aiCenter: 1,
|
||||||
px10: 1,
|
px10: !isCompact,
|
||||||
bgSubtle_onHover: !disabled,
|
bgSubtle_onHover: !disabled,
|
||||||
})
|
})
|
||||||
|
|
||||||
const iconClasses = CX({
|
const iconClasses = CX({
|
||||||
d: 1,
|
d: 1,
|
||||||
inheritFill: 1,
|
inheritFill: 1,
|
||||||
mr10: !!title,
|
mr10: !!title && !isCompact,
|
||||||
})
|
})
|
||||||
|
|
||||||
const color = active ? 'brand' : 'secondary'
|
const color = active ? 'brand' : 'secondary'
|
||||||
|
@ -54,7 +55,7 @@ class StatusActionBarItem extends React.PureComponent {
|
||||||
iconClassName={iconClasses}
|
iconClassName={iconClasses}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
!!title &&
|
!!title && !isCompact &&
|
||||||
<Responsive min={BREAKPOINT_SMALL}>
|
<Responsive min={BREAKPOINT_SMALL}>
|
||||||
<Text color='inherit' size='small' weight={weight}>
|
<Text color='inherit' size='small' weight={weight}>
|
||||||
{title}
|
{title}
|
||||||
|
@ -75,6 +76,7 @@ StatusActionBarItem.propTypes = {
|
||||||
icon: PropTypes.string.isRequired,
|
icon: PropTypes.string.isRequired,
|
||||||
active: PropTypes.bool,
|
active: PropTypes.bool,
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
|
isCompact: PropTypes.bool,
|
||||||
buttonRef: PropTypes.oneOf([
|
buttonRef: PropTypes.oneOf([
|
||||||
PropTypes.func,
|
PropTypes.func,
|
||||||
PropTypes.node,
|
PropTypes.node,
|
||||||
|
|
|
@ -37,6 +37,7 @@ class StatusHeader extends ImmutablePureComponent {
|
||||||
intl,
|
intl,
|
||||||
reduced,
|
reduced,
|
||||||
status,
|
status,
|
||||||
|
isCompact,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
const statusUrl = `/${status.getIn(['account', 'acct'])}/posts/${status.get('id')}`
|
const statusUrl = `/${status.getIn(['account', 'acct'])}/posts/${status.get('id')}`
|
||||||
|
@ -48,7 +49,7 @@ class StatusHeader extends ImmutablePureComponent {
|
||||||
pb10: reduced,
|
pb10: reduced,
|
||||||
})
|
})
|
||||||
|
|
||||||
const avatarSize = reduced ? 20 : 46
|
const avatarSize = reduced ? 20 : isCompact ? 38 : 46
|
||||||
|
|
||||||
const visibility = status.get('visibility')
|
const visibility = status.get('visibility')
|
||||||
|
|
||||||
|
@ -75,6 +76,13 @@ class StatusHeader extends ImmutablePureComponent {
|
||||||
timeUntilExpiration = moment(expirationDate).fromNow()
|
timeUntilExpiration = moment(expirationDate).fromNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const textContainerClasses = CX({
|
||||||
|
d: 1,
|
||||||
|
aiStart: 1,
|
||||||
|
flexGrow1 :1,
|
||||||
|
mt5: !isCompact,
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={containerClasses}>
|
<div className={containerClasses}>
|
||||||
<div className={[_s.d, _s.flexRow, _s.mt5].join(' ')}>
|
<div className={[_s.d, _s.flexRow, _s.mt5].join(' ')}>
|
||||||
|
@ -90,7 +98,7 @@ class StatusHeader extends ImmutablePureComponent {
|
||||||
</NavLink>
|
</NavLink>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div className={[_s.d, _s.aiStart, _s.flexGrow1, _s.mt5].join(' ')}>
|
<div className={textContainerClasses}>
|
||||||
|
|
||||||
<div className={[_s.d, _s.flexRow, _s.w100PC, _s.aiStart].join(' ')}>
|
<div className={[_s.d, _s.flexRow, _s.w100PC, _s.aiStart].join(' ')}>
|
||||||
<NavLink
|
<NavLink
|
||||||
|
|
|
@ -40,6 +40,7 @@ class TimelineInjectionLayout extends React.PureComponent {
|
||||||
buttonHref,
|
buttonHref,
|
||||||
buttonTitle,
|
buttonTitle,
|
||||||
isXS,
|
isXS,
|
||||||
|
isCompact,
|
||||||
} = this.props
|
} = this.props
|
||||||
const { dismissed } = this.state
|
const { dismissed } = this.state
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ class TimelineInjectionLayout extends React.PureComponent {
|
||||||
borderTop1PX: isXS,
|
borderTop1PX: isXS,
|
||||||
borderBottom1PX: isXS,
|
borderBottom1PX: isXS,
|
||||||
border1PX: !isXS,
|
border1PX: !isXS,
|
||||||
radiusSmall: !isXS,
|
radiusSmall: !isXS && !isCompact,
|
||||||
borderColorSecondary: 1,
|
borderColorSecondary: 1,
|
||||||
bgPrimary: 1,
|
bgPrimary: 1,
|
||||||
overflowHidden: 1,
|
overflowHidden: 1,
|
||||||
|
@ -105,6 +106,11 @@ class TimelineInjectionLayout extends React.PureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({
|
||||||
|
isCompact: state.getIn(['settings', 'isCompact']),
|
||||||
|
})
|
||||||
|
|
||||||
TimelineInjectionLayout.propTypes = {
|
TimelineInjectionLayout.propTypes = {
|
||||||
title: PropTypes.string,
|
title: PropTypes.string,
|
||||||
buttonLink: PropTypes.string,
|
buttonLink: PropTypes.string,
|
||||||
|
@ -115,4 +121,4 @@ TimelineInjectionLayout.propTypes = {
|
||||||
isXS: PropTypes.bool,
|
isXS: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect()(TimelineInjectionLayout)
|
export default connect(mapStateToProps)(TimelineInjectionLayout)
|
|
@ -18,6 +18,7 @@ const makeMapStateToProps = () => {
|
||||||
const isReposts = !!props.notification.get('repost')
|
const isReposts = !!props.notification.get('repost')
|
||||||
const isGrouped = isFollows || isLikes || isReposts
|
const isGrouped = isFollows || isLikes || isReposts
|
||||||
const lastReadId = state.getIn(['notifications', 'lastReadId'])
|
const lastReadId = state.getIn(['notifications', 'lastReadId'])
|
||||||
|
const isCompact = state.getIn(['settings', 'isCompact'])
|
||||||
|
|
||||||
if (isFollows) {
|
if (isFollows) {
|
||||||
let lastUpdated
|
let lastUpdated
|
||||||
|
@ -40,6 +41,7 @@ const makeMapStateToProps = () => {
|
||||||
createdAt: lastUpdated,
|
createdAt: lastUpdated,
|
||||||
isUnread: isUnread,
|
isUnread: isUnread,
|
||||||
statusId: undefined,
|
statusId: undefined,
|
||||||
|
isCompact,
|
||||||
}
|
}
|
||||||
} else if (isLikes || isReposts) {
|
} else if (isLikes || isReposts) {
|
||||||
const theType = isLikes ? 'like' : 'repost'
|
const theType = isLikes ? 'like' : 'repost'
|
||||||
|
@ -62,6 +64,7 @@ const makeMapStateToProps = () => {
|
||||||
createdAt: lastUpdated,
|
createdAt: lastUpdated,
|
||||||
isUnread: isUnread,
|
isUnread: isUnread,
|
||||||
statusId: list.get('status'),
|
statusId: list.get('status'),
|
||||||
|
isCompact,
|
||||||
}
|
}
|
||||||
} else if (!isGrouped) {
|
} else if (!isGrouped) {
|
||||||
const notification = getNotification(state, props.notification, props.notification.get('account'))
|
const notification = getNotification(state, props.notification, props.notification.get('account'))
|
||||||
|
@ -74,6 +77,7 @@ const makeMapStateToProps = () => {
|
||||||
createdAt: notification.get('created_at'),
|
createdAt: notification.get('created_at'),
|
||||||
isUnread: lastReadId < notification.get('id'),
|
isUnread: lastReadId < notification.get('id'),
|
||||||
statusId: statusId || undefined,
|
statusId: statusId || undefined,
|
||||||
|
isCompact,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,6 +183,7 @@ const makeMapStateToProps = () => {
|
||||||
isComment,
|
isComment,
|
||||||
commentSortingType,
|
commentSortingType,
|
||||||
isComposeModalOpen: state.getIn(['modal', 'modalType']) === 'COMPOSE',
|
isComposeModalOpen: state.getIn(['modal', 'modalType']) === 'COMPOSE',
|
||||||
|
isCompact: state.getIn(['settings', 'isCompact']),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
import WrappedBundle from './ui/util/wrapped_bundle'
|
||||||
|
import DeckColumn from '../components/deck_column'
|
||||||
|
import {
|
||||||
|
AccountTimeline,
|
||||||
|
HomeTimeline,
|
||||||
|
Notifications,
|
||||||
|
HashtagTimeline,
|
||||||
|
} from './ui/util/async_components'
|
||||||
|
|
||||||
|
class Deck extends React.PureComponent {
|
||||||
|
|
||||||
|
static contextTypes = {
|
||||||
|
router: PropTypes.object,
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
// this.props.connectDeck()
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
// this.props.disconnectDeck()
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { account, children } = this.props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={[_s.d, _s.flexRow].join(' ')}>
|
||||||
|
<DeckColumn title='Home' icon='home'>
|
||||||
|
<WrappedBundle component={HomeTimeline} />
|
||||||
|
</DeckColumn>
|
||||||
|
<DeckColumn title='Notifications' icon='notifications'>
|
||||||
|
<WrappedBundle component={Notifications} />
|
||||||
|
</DeckColumn>
|
||||||
|
<DeckColumn title='Cashtag' icon='list' subtitle='$BTC'>
|
||||||
|
<WrappedBundle component={HashtagTimeline} componentParams={{ params: { id: 'btc' } }} />
|
||||||
|
</DeckColumn>
|
||||||
|
<DeckColumn title='Jonny' icon='group' subtitle='@admin'>
|
||||||
|
<WrappedBundle component={AccountTimeline} componentParams={{ account }} />
|
||||||
|
</DeckColumn>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({
|
||||||
|
account: state.getIn(['accounts', '1']),
|
||||||
|
})
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
Deck.propTypes = {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(Deck)
|
|
@ -23,6 +23,7 @@ export function ComposeForm() { return import(/* webpackChunkName: "components/c
|
||||||
export function ComposeModal() { return import(/* webpackChunkName: "components/compose_modal" */'../../../components/modal/compose_modal') }
|
export function ComposeModal() { return import(/* webpackChunkName: "components/compose_modal" */'../../../components/modal/compose_modal') }
|
||||||
export function ConfirmationModal() { return import(/* webpackChunkName: "components/confirmation_modal" */'../../../components/modal/confirmation_modal') }
|
export function ConfirmationModal() { return import(/* webpackChunkName: "components/confirmation_modal" */'../../../components/modal/confirmation_modal') }
|
||||||
export function DatePickerPopover() { return import(/* webpackChunkName: "components/date_picker_popover" */'../../../components/popover/date_picker_popover') }
|
export function DatePickerPopover() { return import(/* webpackChunkName: "components/date_picker_popover" */'../../../components/popover/date_picker_popover') }
|
||||||
|
export function Deck() { return import(/* webpackChunkName: "features/deck" */'../../deck') }
|
||||||
export function DisplayOptionsModal() { return import(/* webpackChunkName: "components/display_options_modal" */'../../../components/modal/display_options_modal') }
|
export function DisplayOptionsModal() { return import(/* webpackChunkName: "components/display_options_modal" */'../../../components/modal/display_options_modal') }
|
||||||
export function DMCA() { return import(/* webpackChunkName: "features/about/dmca" */'../../about/dmca') }
|
export function DMCA() { return import(/* webpackChunkName: "features/about/dmca" */'../../about/dmca') }
|
||||||
export function EditProfileModal() { return import(/* webpackChunkName: "components/edit_profile_modal" */'../../../components/modal/edit_profile_modal') }
|
export function EditProfileModal() { return import(/* webpackChunkName: "components/edit_profile_modal" */'../../../components/modal/edit_profile_modal') }
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import {
|
||||||
|
CX,
|
||||||
|
BREAKPOINT_EXTRA_SMALL,
|
||||||
|
} from '../constants'
|
||||||
|
import { me } from '../initial_state'
|
||||||
|
import DeckSidebar from '../components/sidebar/deck_sidebar'
|
||||||
|
import WrappedBundle from '../features/ui/util/wrapped_bundle'
|
||||||
|
|
||||||
|
class DeckLayout extends React.PureComponent {
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { children, title } = this.props
|
||||||
|
|
||||||
|
const mainBlockClasses = CX({
|
||||||
|
d: 1,
|
||||||
|
w1015PX: 1,
|
||||||
|
flexRow: 1,
|
||||||
|
jcEnd: 1,
|
||||||
|
py15: 1,
|
||||||
|
mlAuto: !me,
|
||||||
|
mrAuto: !me,
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={[_s.d, _s.w100PC, _s.h100VH, _s.bgTertiary].join(' ')}>
|
||||||
|
<DeckSidebar />
|
||||||
|
<div className={[_s.d, _s.flexRow, _s.w100PC].join(' ')}>
|
||||||
|
<div className={[_s.d, _s.w76PX, _s.h100VH].join(' ')} />
|
||||||
|
<main role='main' className={[_s.d, _s.z1, _s.overflowXScroll, _s.noScrollbar].join(' ')}>
|
||||||
|
{children}
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DeckLayout.propTypes = {
|
||||||
|
title: PropTypes.string,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DeckLayout
|
|
@ -0,0 +1,25 @@
|
||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import PageTitle from '../features/ui/util/page_title'
|
||||||
|
import DeckLayout from '../layouts/deck_layout'
|
||||||
|
|
||||||
|
class DeckPage extends React.PureComponent {
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { children } = this.props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DeckLayout>
|
||||||
|
<PageTitle path={'Deck'} />
|
||||||
|
{children}
|
||||||
|
</DeckLayout>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DeckPage.propTypes = {
|
||||||
|
children: PropTypes.node.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DeckPage
|
|
@ -21,6 +21,7 @@ const initialState = ImmutableMap({
|
||||||
saved: true,
|
saved: true,
|
||||||
shownOnboarding: false,
|
shownOnboarding: false,
|
||||||
skinTone: 1,
|
skinTone: 1,
|
||||||
|
isCompact: false,
|
||||||
commentSorting: COMMENT_SORTING_TYPE_OLDEST,
|
commentSorting: COMMENT_SORTING_TYPE_OLDEST,
|
||||||
|
|
||||||
// every dismiss reduces by half or set to zero for pwa, shop, pro
|
// every dismiss reduces by half or set to zero for pwa, shop, pro
|
||||||
|
|
|
@ -389,6 +389,7 @@ pre {
|
||||||
.displayNone { display: none; }
|
.displayNone { display: none; }
|
||||||
.displayBlock { display: block; }
|
.displayBlock { display: block; }
|
||||||
.displayInline { display: inline; }
|
.displayInline { display: inline; }
|
||||||
|
.displayInlineBlock { display: inline-block; }
|
||||||
.displayFlex { display: flex !important; }
|
.displayFlex { display: flex !important; }
|
||||||
|
|
||||||
.cursorText { cursor: text; }
|
.cursorText { cursor: text; }
|
||||||
|
@ -547,6 +548,7 @@ pre {
|
||||||
.minH40PX { min-height: 40px; }
|
.minH40PX { min-height: 40px; }
|
||||||
.minH28PX { min-height: 28px; }
|
.minH28PX { min-height: 28px; }
|
||||||
|
|
||||||
|
.h100VH { height: 100vh; }
|
||||||
.h100PC { height: 100%; }
|
.h100PC { height: 100%; }
|
||||||
.h350PX { height: 350px; }
|
.h350PX { height: 350px; }
|
||||||
.h260PX { height: 260px; }
|
.h260PX { height: 260px; }
|
||||||
|
@ -590,6 +592,7 @@ pre {
|
||||||
.w1255PX { width: 1255px; }
|
.w1255PX { width: 1255px; }
|
||||||
.w1015PX { width: 1015px; }
|
.w1015PX { width: 1015px; }
|
||||||
.w645PX { width: 645px; }
|
.w645PX { width: 645px; }
|
||||||
|
.w360PX { width: 360px; }
|
||||||
.w340PX { width: 340px; }
|
.w340PX { width: 340px; }
|
||||||
.w330PX { width: 330px; }
|
.w330PX { width: 330px; }
|
||||||
.w300PX { width: 300px; }
|
.w300PX { width: 300px; }
|
||||||
|
|
|
@ -10,8 +10,6 @@ class ProcessHashtagsService < BaseService
|
||||||
|
|
||||||
status.tags << tag
|
status.tags << tag
|
||||||
records << tag
|
records << tag
|
||||||
|
|
||||||
TrendingTags.record_use!(tag, status.account, status.created_at) if status.public_visibility?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return unless status.public_visibility? || status.unlisted_visibility?
|
return unless status.public_visibility? || status.unlisted_visibility?
|
||||||
|
|
|
@ -82,6 +82,7 @@ defaults: &defaults
|
||||||
- links
|
- links
|
||||||
- messages
|
- messages
|
||||||
- message
|
- message
|
||||||
|
- deck
|
||||||
bootstrap_timeline_accounts: ''
|
bootstrap_timeline_accounts: ''
|
||||||
|
|
||||||
development:
|
development:
|
||||||
|
|
Loading…
Reference in New Issue