Progress
This commit is contained in:
parent
c1131db577
commit
a026d86b86
@ -246,7 +246,7 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
|
|||||||
fs14PX: small,
|
fs14PX: small,
|
||||||
heightMax200PX: small,
|
heightMax200PX: small,
|
||||||
heightMax80VH: !small,
|
heightMax80VH: !small,
|
||||||
heightMin100PX: !small,
|
heightMin80PX: !small,
|
||||||
})
|
})
|
||||||
|
|
||||||
const textareaContainerClasses = cx({
|
const textareaContainerClasses = cx({
|
||||||
|
17
app/javascript/gabsocial/components/card_view.js
Normal file
17
app/javascript/gabsocial/components/card_view.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
export default class CardView extends PureComponent {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
children: PropTypes.any,
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { children } = this.props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={[_s.default, _s.boxShadowBlock, _s.bgPrimary, _s.overflowHidden, _s.radiusSmall].join(' ')}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -31,7 +31,7 @@ class FloatingActionButton extends PureComponent {
|
|||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
onClick={onOpenCompose}
|
onClick={onOpenCompose}
|
||||||
className={[_s.posFixed, _s.z4, _s.py15, _s.mb15, _s.mr15, _s.bottom50PX, _s.height60PX, _s.width60PX, _s.right0, _s.justifyContentCenter, _s.alignItemsCenter].join(' ')}
|
className={[_s.posFixed, _s.z4, _s.py15, _s.mb15, _s.mr15, _s.bottom55PX, _s.height60PX, _s.width60PX, _s.right0, _s.justifyContentCenter, _s.alignItemsCenter].join(' ')}
|
||||||
title={message}
|
title={message}
|
||||||
aria-label={message}
|
aria-label={message}
|
||||||
icon='pencil'
|
icon='pencil'
|
||||||
|
@ -1,50 +1,18 @@
|
|||||||
import { NavLink, withRouter } from 'react-router-dom';
|
import { withRouter } from 'react-router-dom'
|
||||||
import { FormattedMessage, injectIntl } from 'react-intl';
|
import { me } from '../initial_state'
|
||||||
import Button from './button'
|
import Button from './button'
|
||||||
import Icon from './icon'
|
|
||||||
|
|
||||||
const links = [
|
|
||||||
<NavLink key='pr1' className='footer-bar__link' to='/home' data-preview-title-id='column.home'>
|
|
||||||
<i className='tabs-bar__link__icon home' />
|
|
||||||
<FormattedMessage id='tabs_bar.home' defaultMessage='Home' />
|
|
||||||
</NavLink>,
|
|
||||||
<NavLink key='pr2' className='footer-bar__link' to='/notifications' data-preview-title-id='column.notifications'>
|
|
||||||
<i className='tabs-bar__link__icon notifications' />
|
|
||||||
<FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' />
|
|
||||||
</NavLink>,
|
|
||||||
<a key='pl5' className='footer-bar__link footer-bar__link--chat' href='https://chat.gab.com' data-preview-title-id='tabs_bar.chat'>
|
|
||||||
<FormattedMessage id='tabs_bar.chat' defaultMessage='Chat' />
|
|
||||||
</a>,
|
|
||||||
<a key='pl4' className='footer-bar__link footer-bar__link--trends' href='https://trends.gab.com' data-preview-title-id='tabs_bar.trends'>
|
|
||||||
<i className='tabs-bar__link__icon trends' />
|
|
||||||
<FormattedMessage id='tabs_bar.trends' defaultMessage='Trends' />
|
|
||||||
</a>,
|
|
||||||
<NavLink key='pr3' className='footer-bar__link' to='/groups' data-preview-title-id='column.groups'>
|
|
||||||
<i className='tabs-bar__link__icon groups' />
|
|
||||||
<FormattedMessage id='tabs_bar.groups' defaultMessage='Groups' />
|
|
||||||
</NavLink>,
|
|
||||||
]
|
|
||||||
|
|
||||||
export default
|
export default
|
||||||
@injectIntl
|
|
||||||
@withRouter
|
@withRouter
|
||||||
class FooterBar extends PureComponent {
|
class FooterBar extends PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
intl: PropTypes.object.isRequired,
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSettings = () => {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { intl } = this.props
|
if (!me) return false
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={[_s.default, _s.z4, _s.height53PX, _s.width100PC].join(' ')}>
|
<div className={[_s.default, _s.z4, _s.heightMin58PX, _s.width100PC].join(' ')}>
|
||||||
<div className={[_s.default, _s.posFixed, _s.left0, _s.right0, _s.bottom0, _s.height53PX, _s.width100PC, _s.bgPrimary, _s.borderTop1PX, _s.borderColorSecondary].join(' ')}>
|
<div className={[_s.default, _s.posFixed, _s.left0, _s.right0, _s.bottom0, _s.heightMin58PX, _s.width100PC, _s.bgPrimary, _s.borderTop1PX, _s.borderColorSecondary].join(' ')}>
|
||||||
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter, _s.justifyContentSpaceAround].join(' ')}>
|
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter, _s.height100PC, _s.heightMin58PX, _s.footerChin, _s.justifyContentSpaceAround].join(' ')}>
|
||||||
<Button
|
<Button
|
||||||
backgroundColor='none'
|
backgroundColor='none'
|
||||||
color='secondary'
|
color='secondary'
|
||||||
@ -52,13 +20,6 @@ class FooterBar extends PureComponent {
|
|||||||
icon='home'
|
icon='home'
|
||||||
iconSize='20px'
|
iconSize='20px'
|
||||||
/>
|
/>
|
||||||
<Button
|
|
||||||
backgroundColor='none'
|
|
||||||
color='secondary'
|
|
||||||
to='/search'
|
|
||||||
icon='search'
|
|
||||||
iconSize='20px'
|
|
||||||
/>
|
|
||||||
<Button
|
<Button
|
||||||
backgroundColor='none'
|
backgroundColor='none'
|
||||||
color='secondary'
|
color='secondary'
|
||||||
@ -69,15 +30,22 @@ class FooterBar extends PureComponent {
|
|||||||
<Button
|
<Button
|
||||||
backgroundColor='none'
|
backgroundColor='none'
|
||||||
color='secondary'
|
color='secondary'
|
||||||
to='/groups'
|
href='https://chat.gab.com'
|
||||||
icon='group'
|
icon='chat'
|
||||||
iconSize='20px'
|
iconSize='20px'
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
backgroundColor='none'
|
backgroundColor='none'
|
||||||
color='secondary'
|
color='secondary'
|
||||||
onClick={this.handleSettings}
|
href='https://trends.gab.com'
|
||||||
icon='hamburger'
|
icon='trends'
|
||||||
|
iconSize='20px'
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
backgroundColor='none'
|
||||||
|
color='secondary'
|
||||||
|
to='/groups'
|
||||||
|
icon='group'
|
||||||
iconSize='20px'
|
iconSize='20px'
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
import { defineMessages, injectIntl } from 'react-intl'
|
||||||
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
|
import ModalLayout from './modal_layout'
|
||||||
|
import GroupCreate from '../../features/group_create'
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
title: { id: 'create_group', defaultMessage: 'Create group' },
|
||||||
|
})
|
||||||
|
|
||||||
|
export default
|
||||||
|
@injectIntl
|
||||||
|
class GroupMembersModal extends ImmutablePureComponent {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
intl: PropTypes.object.isRequired,
|
||||||
|
onClose: PropTypes.func.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { intl, onClose } = this.props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ModalLayout
|
||||||
|
title={intl.formatMessage(messages.title)}
|
||||||
|
width={440}
|
||||||
|
onClose={onClose}
|
||||||
|
>
|
||||||
|
<GroupCreate onCloseModal={onClose} />
|
||||||
|
</ModalLayout>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -1,103 +0,0 @@
|
|||||||
.media-modal {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
@include size(100%);
|
|
||||||
|
|
||||||
&__closer {
|
|
||||||
@include abs-position(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
&__navigation {
|
|
||||||
pointer-events: none;
|
|
||||||
transition: opacity 0.3s linear;
|
|
||||||
will-change: opacity;
|
|
||||||
|
|
||||||
@include abs-position(0, 0, 0, 0);
|
|
||||||
|
|
||||||
* {
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.media-modal__navigation--hidden {
|
|
||||||
opacity: 0;
|
|
||||||
|
|
||||||
* {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__nav {
|
|
||||||
background: rgba($base-overlay-background, 0.5);
|
|
||||||
box-sizing: border-box;
|
|
||||||
border: 0;
|
|
||||||
color: $primary-text-color;
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 24px;
|
|
||||||
height: 20vmax;
|
|
||||||
margin: auto 0;
|
|
||||||
padding: 30px 15px;
|
|
||||||
|
|
||||||
@include abs-position(0, auto, 0, auto);
|
|
||||||
|
|
||||||
&--left {
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--right {
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__meta,
|
|
||||||
&__pagination {
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
pointer-events: none;
|
|
||||||
|
|
||||||
@include abs-position(auto, auto, 20px, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
&__meta {
|
|
||||||
&--shifted {
|
|
||||||
bottom: 62px;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
font-weight: 500;
|
|
||||||
color: $ui-secondary-color;
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:focus,
|
|
||||||
&:active {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__page-dot {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__button {
|
|
||||||
background-color: $primary-text-color;
|
|
||||||
border-radius: 6px;
|
|
||||||
margin: 10px;
|
|
||||||
padding: 0;
|
|
||||||
border: 0;
|
|
||||||
font-size: 0;
|
|
||||||
|
|
||||||
@include size(12px);
|
|
||||||
|
|
||||||
&--active {
|
|
||||||
background-color: $highlight-text-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__close {
|
|
||||||
@include abs-position(8px, 8px);
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,6 +18,7 @@ import {
|
|||||||
MODAL_GROUP_CREATE,
|
MODAL_GROUP_CREATE,
|
||||||
MODAL_GROUP_DELETE,
|
MODAL_GROUP_DELETE,
|
||||||
MODAL_GROUP_EDITOR,
|
MODAL_GROUP_EDITOR,
|
||||||
|
MODAL_GROUP_MEMBERS,
|
||||||
MODAL_HASHTAG_TIMELINE_SETTINGS,
|
MODAL_HASHTAG_TIMELINE_SETTINGS,
|
||||||
MODAL_HOME_TIMELINE_SETTINGS,
|
MODAL_HOME_TIMELINE_SETTINGS,
|
||||||
MODAL_HOTKEYS,
|
MODAL_HOTKEYS,
|
||||||
@ -51,6 +52,7 @@ import {
|
|||||||
GroupCreateModal,
|
GroupCreateModal,
|
||||||
GroupDeleteModal,
|
GroupDeleteModal,
|
||||||
GroupEditorModal,
|
GroupEditorModal,
|
||||||
|
GroupMembersModal,
|
||||||
HashtagTimelineSettingsModal,
|
HashtagTimelineSettingsModal,
|
||||||
HomeTimelineSettingsModal,
|
HomeTimelineSettingsModal,
|
||||||
HotkeysModal,
|
HotkeysModal,
|
||||||
@ -85,6 +87,7 @@ MODAL_COMPONENTS[MODAL_GIF_PICKER] = GifPickerModal
|
|||||||
MODAL_COMPONENTS[MODAL_GROUP_CREATE] = GroupCreateModal
|
MODAL_COMPONENTS[MODAL_GROUP_CREATE] = GroupCreateModal
|
||||||
MODAL_COMPONENTS[MODAL_GROUP_DELETE] = GroupDeleteModal
|
MODAL_COMPONENTS[MODAL_GROUP_DELETE] = GroupDeleteModal
|
||||||
MODAL_COMPONENTS[MODAL_GROUP_EDITOR] = GroupEditorModal
|
MODAL_COMPONENTS[MODAL_GROUP_EDITOR] = GroupEditorModal
|
||||||
|
MODAL_COMPONENTS[MODAL_GROUP_MEMBERS] = GroupMembersModal
|
||||||
MODAL_COMPONENTS[MODAL_HASHTAG_TIMELINE_SETTINGS] = HashtagTimelineSettingsModal
|
MODAL_COMPONENTS[MODAL_HASHTAG_TIMELINE_SETTINGS] = HashtagTimelineSettingsModal
|
||||||
MODAL_COMPONENTS[MODAL_HOME_TIMELINE_SETTINGS] = HomeTimelineSettingsModal
|
MODAL_COMPONENTS[MODAL_HOME_TIMELINE_SETTINGS] = HomeTimelineSettingsModal
|
||||||
MODAL_COMPONENTS[MODAL_HOTKEYS] = HotkeysModal
|
MODAL_COMPONENTS[MODAL_HOTKEYS] = HotkeysModal
|
||||||
@ -156,6 +159,8 @@ class ModalRoot extends PureComponent {
|
|||||||
const { type, props } = this.props
|
const { type, props } = this.props
|
||||||
const visible = !!type
|
const visible = !!type
|
||||||
|
|
||||||
|
// : todo : init card view if mobile
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalBase onClose={this.onClickClose} type={type}>
|
<ModalBase onClose={this.onClickClose} type={type}>
|
||||||
{
|
{
|
||||||
|
23
app/javascript/gabsocial/components/pull_to_refresher.js
Normal file
23
app/javascript/gabsocial/components/pull_to_refresher.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { BREAKPOINT_EXTRA_SMALL } from '../constants'
|
||||||
|
import Responsive from '../features/ui//util/responsive_component'
|
||||||
|
import Icon from './icon'
|
||||||
|
|
||||||
|
export default class PullToRefresher extends PureComponent {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
children: PropTypes.any,
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { children } = this.props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Responsive max={BREAKPOINT_EXTRA_SMALL}>
|
||||||
|
<div className={[_s.default, _s.posAbs, _s.left0, _s.right0, _s.topNeg60PX].join(' ')}>
|
||||||
|
<Icon id='loading' size='20px' />
|
||||||
|
</div>
|
||||||
|
</Responsive>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
import throttle from 'lodash.throttle'
|
import throttle from 'lodash.throttle'
|
||||||
import { List as ImmutableList } from 'immutable'
|
import { List as ImmutableList } from 'immutable'
|
||||||
|
import { BREAKPOINT_EXTRA_SMALL } from '../constants'
|
||||||
import IntersectionObserverArticle from './intersection_observer_article'
|
import IntersectionObserverArticle from './intersection_observer_article'
|
||||||
import IntersectionObserverWrapper from '../features/ui/util/intersection_observer_wrapper'
|
import IntersectionObserverWrapper from '../features/ui/util/intersection_observer_wrapper'
|
||||||
|
import Responsive from '../features/ui/util/responsive_component'
|
||||||
import Block from './block'
|
import Block from './block'
|
||||||
import ColumnIndicator from './column_indicator'
|
import ColumnIndicator from './column_indicator'
|
||||||
import LoadMore from './load_more'
|
import LoadMore from './load_more'
|
||||||
@ -17,6 +19,7 @@ export default class ScrollableList extends PureComponent {
|
|||||||
static propTypes = {
|
static propTypes = {
|
||||||
scrollKey: PropTypes.string.isRequired,
|
scrollKey: PropTypes.string.isRequired,
|
||||||
onLoadMore: PropTypes.func,
|
onLoadMore: PropTypes.func,
|
||||||
|
onReload: PropTypes.func,
|
||||||
isLoading: PropTypes.bool,
|
isLoading: PropTypes.bool,
|
||||||
showLoading: PropTypes.bool,
|
showLoading: PropTypes.bool,
|
||||||
hasMore: PropTypes.bool,
|
hasMore: PropTypes.bool,
|
||||||
@ -259,3 +262,4 @@ export default class ScrollableList extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,15 +17,13 @@ import ColumnIndicator from './column_indicator';
|
|||||||
const makeGetStatusIds = () => createSelector([
|
const makeGetStatusIds = () => createSelector([
|
||||||
(state, { type, id }) => state.getIn(['settings', type], ImmutableMap()),
|
(state, { type, id }) => state.getIn(['settings', type], ImmutableMap()),
|
||||||
(state, { type, id }) => state.getIn(['timelines', id, 'items'], ImmutableList()),
|
(state, { type, id }) => state.getIn(['timelines', id, 'items'], ImmutableList()),
|
||||||
(state) => state.get('statuses'),
|
(state) => state.get('statuses'),
|
||||||
], (columnSettings, statusIds, statuses) => {
|
], (columnSettings, statusIds, statuses) => {
|
||||||
return statusIds.filter(id => {
|
return statusIds.filter(id => {
|
||||||
if (id === null) return true;
|
if (id === null) return true;
|
||||||
|
|
||||||
const statusForId = statuses.get(id);
|
const statusForId = statuses.get(id);
|
||||||
let showStatus = true;
|
let showStatus = true;
|
||||||
|
|
||||||
console.log("columnSettings:", columnSettings)
|
|
||||||
|
|
||||||
if (columnSettings.getIn(['shows', 'reblog']) === false) {
|
if (columnSettings.getIn(['shows', 'reblog']) === false) {
|
||||||
showStatus = showStatus && statusForId.get('reblog') === null;
|
showStatus = showStatus && statusForId.get('reblog') === null;
|
||||||
@ -41,12 +39,12 @@ const makeGetStatusIds = () => createSelector([
|
|||||||
|
|
||||||
const mapStateToProps = (state, { timelineId }) => {
|
const mapStateToProps = (state, { timelineId }) => {
|
||||||
if (!timelineId) return {}
|
if (!timelineId) return {}
|
||||||
|
|
||||||
const getStatusIds = makeGetStatusIds();
|
const getStatusIds = makeGetStatusIds();
|
||||||
const promotion = promotions.length > 0 && sample(promotions.filter(p => p.timeline_id === timelineId));
|
const promotion = promotions.length > 0 && sample(promotions.filter(p => p.timeline_id === timelineId));
|
||||||
|
|
||||||
const statusIds = getStatusIds(state, {
|
const statusIds = getStatusIds(state, {
|
||||||
type: timelineId.substring(0,5) === 'group' ? 'group' : timelineId,
|
type: timelineId.substring(0, 5) === 'group' ? 'group' : timelineId,
|
||||||
id: timelineId
|
id: timelineId
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -136,10 +134,14 @@ class StatusList extends ImmutablePureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleLoadOlder = debounce(() => {
|
handleLoadOlder = debounce(() => {
|
||||||
this.props.onLoadMore(this.props.statusIds.size > 0 ? this.props.statusIds.last() : undefined);
|
this.props.onLoadMore(this.props.statusIds.size > 0 ? this.props.statusIds.last() : undefined)
|
||||||
}, 300, { leading: true })
|
}, 300, { leading: true })
|
||||||
|
|
||||||
_selectChild (index, align_top) {
|
handleReload = debounce(() => {
|
||||||
|
this.props.onLoadMore()
|
||||||
|
}, 300, { leading: true })
|
||||||
|
|
||||||
|
_selectChild(index, align_top) {
|
||||||
const container = this.node.node;
|
const container = this.node.node;
|
||||||
const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
|
const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
|
||||||
|
|
||||||
@ -164,7 +166,7 @@ class StatusList extends ImmutablePureComponent {
|
|||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render() {
|
||||||
const {
|
const {
|
||||||
statusIds,
|
statusIds,
|
||||||
featuredStatusIds,
|
featuredStatusIds,
|
||||||
@ -177,7 +179,7 @@ class StatusList extends ImmutablePureComponent {
|
|||||||
promotion,
|
promotion,
|
||||||
promotedStatus,
|
promotedStatus,
|
||||||
...other
|
...other
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
if (isPartial) {
|
if (isPartial) {
|
||||||
return <ColumnIndicator type='loading' />
|
return <ColumnIndicator type='loading' />
|
||||||
@ -192,15 +194,15 @@ class StatusList extends ImmutablePureComponent {
|
|||||||
onClick={onLoadMore}
|
onClick={onLoadMore}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<StatusContainer
|
<StatusContainer
|
||||||
key={statusId}
|
key={statusId}
|
||||||
id={statusId}
|
id={statusId}
|
||||||
onMoveUp={this.handleMoveUp}
|
onMoveUp={this.handleMoveUp}
|
||||||
onMoveDown={this.handleMoveDown}
|
onMoveDown={this.handleMoveDown}
|
||||||
contextType={timelineId}
|
contextType={timelineId}
|
||||||
commentsLimited
|
commentsLimited
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
if (scrollableContent && featuredStatusIds) {
|
if (scrollableContent && featuredStatusIds) {
|
||||||
|
@ -2,10 +2,11 @@ import ImmutablePureComponent from 'react-immutable-pure-component'
|
|||||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import { injectIntl, defineMessages } from 'react-intl'
|
import { injectIntl, defineMessages } from 'react-intl'
|
||||||
import { me } from '../initial_state'
|
import { me } from '../initial_state'
|
||||||
|
import { BREAKPOINT_EXTRA_SMALL } from '../constants'
|
||||||
import ComposeFormContainer from '../features/compose/containers/compose_form_container'
|
import ComposeFormContainer from '../features/compose/containers/compose_form_container'
|
||||||
import ResponsiveClassesComponent from '../features/ui/util/responsive_classes_component'
|
import ResponsiveClassesComponent from '../features/ui/util/responsive_classes_component'
|
||||||
|
import Responsive from '../features/ui/util/responsive_component'
|
||||||
import Avatar from './avatar'
|
import Avatar from './avatar'
|
||||||
import Block from './block'
|
|
||||||
import Heading from './heading'
|
import Heading from './heading'
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
@ -42,7 +43,6 @@ class TimelineComposeBlock extends ImmutablePureComponent {
|
|||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
if (modal) {
|
if (modal) {
|
||||||
console.log("modal timeline composer: ", this.props)
|
|
||||||
return (
|
return (
|
||||||
<section className={_s.default}>
|
<section className={_s.default}>
|
||||||
<div className={[_s.default, _s.flexRow].join(' ')}>
|
<div className={[_s.default, _s.flexRow].join(' ')}>
|
||||||
@ -58,14 +58,16 @@ class TimelineComposeBlock extends ImmutablePureComponent {
|
|||||||
classNames={[_s.default, _s.boxShadowBlock, _s.bgPrimary, _s.overflowHidden, _s.radiusSmall].join(' ')}
|
classNames={[_s.default, _s.boxShadowBlock, _s.bgPrimary, _s.overflowHidden, _s.radiusSmall].join(' ')}
|
||||||
classNamesXS={[_s.default, _s.boxShadowBlock, _s.bgPrimary, _s.overflowHidden].join(' ')}
|
classNamesXS={[_s.default, _s.boxShadowBlock, _s.bgPrimary, _s.overflowHidden].join(' ')}
|
||||||
>
|
>
|
||||||
<div className={[_s.default, _s.bgSubtle, _s.borderTop1PX, _s.borderBottom1PX, _s.borderColorSecondary, _s.px15, _s.py2, _s.alignItemsCenter, _s.flexRow].join(' ')}>
|
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
|
||||||
<div className={_s.mr10}>
|
<div className={[_s.default, _s.bgSubtle, _s.borderTop1PX, _s.borderBottom1PX, _s.borderColorSecondary, _s.px15, _s.py2, _s.alignItemsCenter, _s.flexRow].join(' ')}>
|
||||||
<Avatar account={account} size={20} noHover />
|
<div className={_s.mr10}>
|
||||||
|
<Avatar account={account} size={20} noHover />
|
||||||
|
</div>
|
||||||
|
<Heading size='h5'>
|
||||||
|
{intl.formatMessage(messages.createPost)}
|
||||||
|
</Heading>
|
||||||
</div>
|
</div>
|
||||||
<Heading size='h5'>
|
</Responsive>
|
||||||
{intl.formatMessage(messages.createPost)}
|
|
||||||
</Heading>
|
|
||||||
</div>
|
|
||||||
<ComposeFormContainer {...rest} />
|
<ComposeFormContainer {...rest} />
|
||||||
</ResponsiveClassesComponent>
|
</ResponsiveClassesComponent>
|
||||||
</section>
|
</section>
|
||||||
|
@ -45,6 +45,7 @@ export const MODAL_GIF_PICKER = 'GIF_PICKER'
|
|||||||
export const MODAL_GROUP_CREATE = 'GROUP_CREATE'
|
export const MODAL_GROUP_CREATE = 'GROUP_CREATE'
|
||||||
export const MODAL_GROUP_DELETE = 'GROUP_DELETE'
|
export const MODAL_GROUP_DELETE = 'GROUP_DELETE'
|
||||||
export const MODAL_GROUP_EDITOR = 'GROUP_EDITOR'
|
export const MODAL_GROUP_EDITOR = 'GROUP_EDITOR'
|
||||||
|
export const MODAL_GROUP_MEMBERS = 'GROUP_MEMBERS'
|
||||||
export const MODAL_HASHTAG_TIMELINE_SETTINGS = 'HASHTAG_TIMELINE_SETTINGS'
|
export const MODAL_HASHTAG_TIMELINE_SETTINGS = 'HASHTAG_TIMELINE_SETTINGS'
|
||||||
export const MODAL_HOME_TIMELINE_SETTINGS = 'HOME_TIMELINE_SETTINGS'
|
export const MODAL_HOME_TIMELINE_SETTINGS = 'HOME_TIMELINE_SETTINGS'
|
||||||
export const MODAL_HOTKEYS = 'HOTKEYS'
|
export const MODAL_HOTKEYS = 'HOTKEYS'
|
||||||
|
@ -8,8 +8,10 @@ import {
|
|||||||
CX,
|
CX,
|
||||||
MAX_POST_CHARACTER_COUNT,
|
MAX_POST_CHARACTER_COUNT,
|
||||||
ALLOWED_AROUND_SHORT_CODE,
|
ALLOWED_AROUND_SHORT_CODE,
|
||||||
|
BREAKPOINT_EXTRA_SMALL,
|
||||||
} from '../../../constants'
|
} from '../../../constants'
|
||||||
import AutosuggestTextbox from '../../../components/autosuggest_textbox'
|
import AutosuggestTextbox from '../../../components/autosuggest_textbox'
|
||||||
|
import Responsive from '../../ui/util/responsive_component'
|
||||||
import Avatar from '../../../components/avatar'
|
import Avatar from '../../../components/avatar'
|
||||||
import Button from '../../../components/button'
|
import Button from '../../../components/button'
|
||||||
import CharacterCounter from '../../../components/character_counter'
|
import CharacterCounter from '../../../components/character_counter'
|
||||||
@ -462,7 +464,9 @@ class ComposeForm extends ImmutablePureComponent {
|
|||||||
{ /* !shouldCondense && <RichTextEditorButton /> */}
|
{ /* !shouldCondense && <RichTextEditorButton /> */}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<CharacterCounter max={MAX_POST_CHARACTER_COUNT} text={text} />
|
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
|
||||||
|
<CharacterCounter max={MAX_POST_CHARACTER_COUNT} text={text} />
|
||||||
|
</Responsive>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
isOutline
|
isOutline
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
import { fetchGroups } from '../actions/groups'
|
import { fetchGroups } from '../actions/groups'
|
||||||
|
import { BREAKPOINT_EXTRA_SMALL } from '../constants'
|
||||||
|
import Responsive from './ui/util/responsive_component'
|
||||||
import ColumnIndicator from '../components/column_indicator'
|
import ColumnIndicator from '../components/column_indicator'
|
||||||
import ScrollableList from '../components/scrollable_list'
|
import ScrollableList from '../components/scrollable_list'
|
||||||
import GroupCollectionItem from '../components/group_collection_item'
|
import GroupCollectionItem from '../components/group_collection_item'
|
||||||
@ -40,24 +42,37 @@ class GroupsCollection extends ImmutablePureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={[_s.default, _s.flexRow, _s.flexWrap].join(' ')}>
|
<div className={[_s.default, _s.flexRow, _s.flexWrap].join(' ')}>
|
||||||
<div className={[_s.default, _s.flexNormal].join(' ')}>
|
<Responsive max={BREAKPOINT_EXTRA_SMALL}>
|
||||||
<ScrollableList scrollKey='group-collection-column-1'>
|
<div className={[_s.default, _s.width100PC, _s.px5].join(' ')}>
|
||||||
{
|
<ScrollableList scrollKey='group-collection-column-1'>
|
||||||
groupIds.slice(0, halfCount).map((groupId, i) => (
|
{
|
||||||
<GroupCollectionItem key={`group-collection-item-${i}`} id={groupId} />
|
groupIds.map((groupId, i) => (
|
||||||
))
|
<GroupCollectionItem key={`group-collection-item-${i}`} id={groupId} />
|
||||||
}
|
))
|
||||||
</ScrollableList>
|
}
|
||||||
</div>
|
</ScrollableList>
|
||||||
<div className={[_s.default, _s.flexNormal].join(' ')}>
|
</div>
|
||||||
<ScrollableList scrollKey='group-collection-column-2'>
|
</Responsive>
|
||||||
{
|
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
|
||||||
groupIds.slice(halfCount, groupIds.size).map((groupId, i) => (
|
<div className={[_s.default, _s.flexNormal].join(' ')}>
|
||||||
<GroupCollectionItem key={`group-collection-item-${i}`} id={groupId} />
|
<ScrollableList scrollKey='group-collection-column-1'>
|
||||||
))
|
{
|
||||||
}
|
groupIds.slice(0, halfCount).map((groupId, i) => (
|
||||||
</ScrollableList>
|
<GroupCollectionItem key={`group-collection-item-${i}`} id={groupId} />
|
||||||
</div>
|
))
|
||||||
|
}
|
||||||
|
</ScrollableList>
|
||||||
|
</div>
|
||||||
|
<div className={[_s.default, _s.flexNormal].join(' ')}>
|
||||||
|
<ScrollableList scrollKey='group-collection-column-2'>
|
||||||
|
{
|
||||||
|
groupIds.slice(halfCount, groupIds.size).map((groupId, i) => (
|
||||||
|
<GroupCollectionItem key={`group-collection-item-${i}`} id={groupId} />
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</ScrollableList>
|
||||||
|
</div>
|
||||||
|
</Responsive>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class HomeTimeline extends PureComponent {
|
|||||||
isPartial: PropTypes.bool,
|
isPartial: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
handleLoadMore = maxId => {
|
handleLoadMore = (maxId) => {
|
||||||
this.props.dispatch(expandHomeTimeline({ maxId }))
|
this.props.dispatch(expandHomeTimeline({ maxId }))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ export function GroupCreate() { return import(/* webpackChunkName: "features/gro
|
|||||||
export function GroupCreateModal() { return import(/* webpackChunkName: "components/group_create_modal" */'../../../components/modal/group_create_modal') }
|
export function GroupCreateModal() { return import(/* webpackChunkName: "components/group_create_modal" */'../../../components/modal/group_create_modal') }
|
||||||
export function GroupDeleteModal() { return import(/* webpackChunkName: "components/group_delete_modal" */'../../../components/modal/group_delete_modal') }
|
export function GroupDeleteModal() { return import(/* webpackChunkName: "components/group_delete_modal" */'../../../components/modal/group_delete_modal') }
|
||||||
export function GroupEditorModal() { return import(/* webpackChunkName: "components/group_editor_modal" */'../../../components/modal/group_editor_modal') }
|
export function GroupEditorModal() { return import(/* webpackChunkName: "components/group_editor_modal" */'../../../components/modal/group_editor_modal') }
|
||||||
|
export function GroupMembersModal() { return import(/* webpackChunkName: "components/group_members_modal" */'../../../components/modal/group_members_modal') }
|
||||||
export function GroupInfoPopover() { return import(/* webpackChunkName: "components/group_info_popover" */'../../../components/popover/group_info_popover') }
|
export function GroupInfoPopover() { return import(/* webpackChunkName: "components/group_info_popover" */'../../../components/popover/group_info_popover') }
|
||||||
export function GroupMembers() { return import(/* webpackChunkName: "features/group_members" */'../../group_members') }
|
export function GroupMembers() { return import(/* webpackChunkName: "features/group_members" */'../../group_members') }
|
||||||
export function GroupRemovedAccounts() { return import(/* webpackChunkName: "features/group_removed_accounts" */'../../group_removed_accounts') }
|
export function GroupRemovedAccounts() { return import(/* webpackChunkName: "features/group_removed_accounts" */'../../group_removed_accounts') }
|
||||||
|
@ -65,7 +65,10 @@ export default class Layout extends PureComponent {
|
|||||||
>
|
>
|
||||||
<main role='main'>
|
<main role='main'>
|
||||||
|
|
||||||
<div className={[_s.default, _s.width1015PX, _s.flexRow, _s.justifyContentEnd, _s.py15].join(' ')}>
|
<ResponsiveClassesComponent
|
||||||
|
classNames={[_s.default, _s.width1015PX, _s.flexRow, _s.justifyContentEnd, _s.py15].join(' ')}
|
||||||
|
classNamesXS={[_s.default, _s.width1015PX, _s.justifyContentEnd, _s.pb15].join(' ')}
|
||||||
|
>
|
||||||
|
|
||||||
{
|
{
|
||||||
noRightSidebar && children
|
noRightSidebar && children
|
||||||
@ -78,7 +81,7 @@ export default class Layout extends PureComponent {
|
|||||||
{
|
{
|
||||||
!!tabs &&
|
!!tabs &&
|
||||||
<Responsive max={BREAKPOINT_EXTRA_SMALL}>
|
<Responsive max={BREAKPOINT_EXTRA_SMALL}>
|
||||||
<div className={[_s.default, _s.pb15].join(' ')}>
|
<div className={[_s.default, _s.py15].join(' ')}>
|
||||||
<Pills pills={tabs} />
|
<Pills pills={tabs} />
|
||||||
</div>
|
</div>
|
||||||
</Responsive>
|
</Responsive>
|
||||||
@ -110,7 +113,7 @@ export default class Layout extends PureComponent {
|
|||||||
</Responsive>
|
</Responsive>
|
||||||
}
|
}
|
||||||
|
|
||||||
</div>
|
</ResponsiveClassesComponent>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
</ResponsiveClassesComponent>
|
</ResponsiveClassesComponent>
|
||||||
|
@ -59,10 +59,11 @@ class GroupPage extends ImmutablePureComponent {
|
|||||||
group={group}
|
group={group}
|
||||||
relationships={relationships}
|
relationships={relationships}
|
||||||
actions={[
|
actions={[
|
||||||
{
|
// : todo :
|
||||||
icon: 'ellipsis',
|
// {
|
||||||
onClick: null,
|
// icon: 'ellipsis',
|
||||||
},
|
// onClick: null,
|
||||||
|
// },
|
||||||
]}
|
]}
|
||||||
layout={(
|
layout={(
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
@ -2,7 +2,10 @@ import { Fragment } from 'react'
|
|||||||
import { me } from '../initial_state'
|
import { me } from '../initial_state'
|
||||||
import { defineMessages, injectIntl } from 'react-intl'
|
import { defineMessages, injectIntl } from 'react-intl'
|
||||||
import { openModal } from '../actions/modal'
|
import { openModal } from '../actions/modal'
|
||||||
import { MODAL_GROUP_CREATE } from '../constants'
|
import {
|
||||||
|
MODAL_GROUP_CREATE,
|
||||||
|
MODAL_PRO_UPGRADE,
|
||||||
|
} from '../constants'
|
||||||
import PageTitle from '../features/ui/util/page_title'
|
import PageTitle from '../features/ui/util/page_title'
|
||||||
import LinkFooter from '../components/link_footer'
|
import LinkFooter from '../components/link_footer'
|
||||||
import GroupsPanel from '../components/panel/groups_panel'
|
import GroupsPanel from '../components/panel/groups_panel'
|
||||||
@ -22,8 +25,12 @@ const mapStateToProps = (state) => ({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
onOpenGroupCreateModal() {
|
onOpenGroupCreateModal(isPro) {
|
||||||
dispatch(openModal(MODAL_GROUP_CREATE))
|
if (!isPro) {
|
||||||
|
dispatch(openModal(MODAL_PRO_UPGRADE))
|
||||||
|
} else {
|
||||||
|
dispatch(openModal(MODAL_GROUP_CREATE))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -39,6 +46,10 @@ class GroupsPage extends PureComponent {
|
|||||||
onOpenGroupCreateModal: PropTypes.func.isRequired,
|
onOpenGroupCreateModal: PropTypes.func.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleOnOpenGroupCreateModal = () => {
|
||||||
|
this.props.onOpenGroupCreateModal(this.props.isPro)
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
intl,
|
intl,
|
||||||
@ -47,7 +58,12 @@ class GroupsPage extends PureComponent {
|
|||||||
onOpenGroupCreateModal,
|
onOpenGroupCreateModal,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
const actions = []
|
const actions = [
|
||||||
|
{
|
||||||
|
icon: 'add',
|
||||||
|
onClick: this.handleOnOpenGroupCreateModal,
|
||||||
|
},
|
||||||
|
]
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{
|
{
|
||||||
title: intl.formatMessage(messages.featured),
|
title: intl.formatMessage(messages.featured),
|
||||||
@ -64,11 +80,6 @@ class GroupsPage extends PureComponent {
|
|||||||
]
|
]
|
||||||
|
|
||||||
if (isPro) {
|
if (isPro) {
|
||||||
actions.push({
|
|
||||||
icon: 'add',
|
|
||||||
onClick: onOpenGroupCreateModal,
|
|
||||||
})
|
|
||||||
|
|
||||||
tabs.push({
|
tabs.push({
|
||||||
title: intl.formatMessage(messages.admin),
|
title: intl.formatMessage(messages.admin),
|
||||||
to: '/groups/browse/admin',
|
to: '/groups/browse/admin',
|
||||||
@ -79,7 +90,6 @@ class GroupsPage extends PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<DefaultLayout
|
<DefaultLayout
|
||||||
showBackBtn
|
|
||||||
title={title}
|
title={title}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
tabs={tabs}
|
tabs={tabs}
|
||||||
|
@ -15,6 +15,7 @@ import TrendsPanel from '../components/panel/trends_panel'
|
|||||||
import DefaultLayout from '../layouts/default_layout'
|
import DefaultLayout from '../layouts/default_layout'
|
||||||
import TimelineComposeBlock from '../components/timeline_compose_block'
|
import TimelineComposeBlock from '../components/timeline_compose_block'
|
||||||
import Divider from '../components/divider'
|
import Divider from '../components/divider'
|
||||||
|
import PullToRefresher from '../components/pull_to_refresher'
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
home: { id: 'home', defaultMessage: 'Home' },
|
home: { id: 'home', defaultMessage: 'Home' },
|
||||||
@ -116,6 +117,8 @@ class HomePage extends PureComponent {
|
|||||||
badge={totalQueuedItemsCount}
|
badge={totalQueuedItemsCount}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<PullToRefresher />
|
||||||
|
|
||||||
<TimelineComposeBlock autoFocus={false} />
|
<TimelineComposeBlock autoFocus={false} />
|
||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
@ -47,6 +47,7 @@ class SearchPage extends PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout
|
<Layout
|
||||||
|
noComposeButton
|
||||||
title={title}
|
title={title}
|
||||||
showBackBtn
|
showBackBtn
|
||||||
tabs={tabs}
|
tabs={tabs}
|
||||||
|
@ -386,13 +386,14 @@ body {
|
|||||||
|
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
|
.topNeg60PX { top: -60px; }
|
||||||
.top0 { top: 0; }
|
.top0 { top: 0; }
|
||||||
.top80PX { top: 80px; }
|
.top80PX { top: 80px; }
|
||||||
.top60PC { top: 60%; }
|
.top60PC { top: 60%; }
|
||||||
.top50PC { top: 50%; }
|
.top50PC { top: 50%; }
|
||||||
|
|
||||||
.bottom0 { bottom: 0; }
|
.bottom0 { bottom: 0; }
|
||||||
.bottom50PX { bottom: 50px; }
|
.bottom55PX { bottom: 55px; }
|
||||||
.bottomAuto { bottom: auto; }
|
.bottomAuto { bottom: auto; }
|
||||||
|
|
||||||
.left0 { left: 0px; }
|
.left0 { left: 0px; }
|
||||||
@ -429,7 +430,8 @@ body {
|
|||||||
|
|
||||||
.heightMin100VH { min-height: 100vh; }
|
.heightMin100VH { min-height: 100vh; }
|
||||||
.heightMin50VH { min-height: 50vh; }
|
.heightMin50VH { min-height: 50vh; }
|
||||||
.heightMin100PX { min-height: 100px; }
|
.heightMin80PX { min-height: 80px; }
|
||||||
|
.heightMin58PX { min-height: 58px; }
|
||||||
.heightMin50PX { min-height: 50px; }
|
.heightMin50PX { min-height: 50px; }
|
||||||
|
|
||||||
.height100PC { height: 100%; }
|
.height100PC { height: 100%; }
|
||||||
@ -843,6 +845,11 @@ body {
|
|||||||
-ms-overflow-style: none;
|
-ms-overflow-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.footerChin {
|
||||||
|
padding-bottom: 0;
|
||||||
|
padding-bottom: env(safe-area-inset-bottom, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rich Text Editor
|
* Rich Text Editor
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user