This commit is contained in:
mgabdev 2020-05-07 00:03:34 -04:00
parent c1131db577
commit a026d86b86
22 changed files with 217 additions and 221 deletions

@ -246,7 +246,7 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
fs14PX: small,
heightMax200PX: small,
heightMax80VH: !small,
heightMin100PX: !small,
heightMin80PX: !small,
})
const textareaContainerClasses = cx({

@ -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 (
<Button
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}
aria-label={message}
icon='pencil'

@ -1,50 +1,18 @@
import { NavLink, withRouter } from 'react-router-dom';
import { FormattedMessage, injectIntl } from 'react-intl';
import { withRouter } from 'react-router-dom'
import { me } from '../initial_state'
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
@injectIntl
@withRouter
class FooterBar extends PureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
}
handleSettings = () => {
//
}
render() {
const { intl } = this.props
if (!me) return false
return (
<div className={[_s.default, _s.z4, _s.height53PX, _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.flexRow, _s.alignItemsCenter, _s.justifyContentSpaceAround].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.heightMin58PX, _s.width100PC, _s.bgPrimary, _s.borderTop1PX, _s.borderColorSecondary].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter, _s.height100PC, _s.heightMin58PX, _s.footerChin, _s.justifyContentSpaceAround].join(' ')}>
<Button
backgroundColor='none'
color='secondary'
@ -52,13 +20,6 @@ class FooterBar extends PureComponent {
icon='home'
iconSize='20px'
/>
<Button
backgroundColor='none'
color='secondary'
to='/search'
icon='search'
iconSize='20px'
/>
<Button
backgroundColor='none'
color='secondary'
@ -69,15 +30,22 @@ class FooterBar extends PureComponent {
<Button
backgroundColor='none'
color='secondary'
to='/groups'
icon='group'
href='https://chat.gab.com'
icon='chat'
iconSize='20px'
/>
<Button
backgroundColor='none'
color='secondary'
onClick={this.handleSettings}
icon='hamburger'
href='https://trends.gab.com'
icon='trends'
iconSize='20px'
/>
<Button
backgroundColor='none'
color='secondary'
to='/groups'
icon='group'
iconSize='20px'
/>
</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_DELETE,
MODAL_GROUP_EDITOR,
MODAL_GROUP_MEMBERS,
MODAL_HASHTAG_TIMELINE_SETTINGS,
MODAL_HOME_TIMELINE_SETTINGS,
MODAL_HOTKEYS,
@ -51,6 +52,7 @@ import {
GroupCreateModal,
GroupDeleteModal,
GroupEditorModal,
GroupMembersModal,
HashtagTimelineSettingsModal,
HomeTimelineSettingsModal,
HotkeysModal,
@ -85,6 +87,7 @@ MODAL_COMPONENTS[MODAL_GIF_PICKER] = GifPickerModal
MODAL_COMPONENTS[MODAL_GROUP_CREATE] = GroupCreateModal
MODAL_COMPONENTS[MODAL_GROUP_DELETE] = GroupDeleteModal
MODAL_COMPONENTS[MODAL_GROUP_EDITOR] = GroupEditorModal
MODAL_COMPONENTS[MODAL_GROUP_MEMBERS] = GroupMembersModal
MODAL_COMPONENTS[MODAL_HASHTAG_TIMELINE_SETTINGS] = HashtagTimelineSettingsModal
MODAL_COMPONENTS[MODAL_HOME_TIMELINE_SETTINGS] = HomeTimelineSettingsModal
MODAL_COMPONENTS[MODAL_HOTKEYS] = HotkeysModal
@ -156,6 +159,8 @@ class ModalRoot extends PureComponent {
const { type, props } = this.props
const visible = !!type
// : todo : init card view if mobile
return (
<ModalBase onClose={this.onClickClose} type={type}>
{

@ -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 { List as ImmutableList } from 'immutable'
import { BREAKPOINT_EXTRA_SMALL } from '../constants'
import IntersectionObserverArticle from './intersection_observer_article'
import IntersectionObserverWrapper from '../features/ui/util/intersection_observer_wrapper'
import Responsive from '../features/ui/util/responsive_component'
import Block from './block'
import ColumnIndicator from './column_indicator'
import LoadMore from './load_more'
@ -17,6 +19,7 @@ export default class ScrollableList extends PureComponent {
static propTypes = {
scrollKey: PropTypes.string.isRequired,
onLoadMore: PropTypes.func,
onReload: PropTypes.func,
isLoading: PropTypes.bool,
showLoading: 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([
(state, { type, id }) => state.getIn(['settings', type], ImmutableMap()),
(state, { type, id }) => state.getIn(['timelines', id, 'items'], ImmutableList()),
(state) => state.get('statuses'),
(state) => state.get('statuses'),
], (columnSettings, statusIds, statuses) => {
return statusIds.filter(id => {
if (id === null) return true;
const statusForId = statuses.get(id);
let showStatus = true;
console.log("columnSettings:", columnSettings)
let showStatus = true;
if (columnSettings.getIn(['shows', 'reblog']) === false) {
showStatus = showStatus && statusForId.get('reblog') === null;
@ -41,12 +39,12 @@ const makeGetStatusIds = () => createSelector([
const mapStateToProps = (state, { timelineId }) => {
if (!timelineId) return {}
const getStatusIds = makeGetStatusIds();
const promotion = promotions.length > 0 && sample(promotions.filter(p => p.timeline_id === timelineId));
const statusIds = getStatusIds(state, {
type: timelineId.substring(0,5) === 'group' ? 'group' : timelineId,
type: timelineId.substring(0, 5) === 'group' ? 'group' : timelineId,
id: timelineId
})
@ -136,10 +134,14 @@ class StatusList extends ImmutablePureComponent {
}
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 })
_selectChild (index, align_top) {
handleReload = debounce(() => {
this.props.onLoadMore()
}, 300, { leading: true })
_selectChild(index, align_top) {
const container = this.node.node;
const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
@ -164,7 +166,7 @@ class StatusList extends ImmutablePureComponent {
this.node = c;
}
render () {
render() {
const {
statusIds,
featuredStatusIds,
@ -177,7 +179,7 @@ class StatusList extends ImmutablePureComponent {
promotion,
promotedStatus,
...other
} = this.props
} = this.props
if (isPartial) {
return <ColumnIndicator type='loading' />
@ -192,15 +194,15 @@ class StatusList extends ImmutablePureComponent {
onClick={onLoadMore}
/>
) : (
<StatusContainer
key={statusId}
id={statusId}
onMoveUp={this.handleMoveUp}
onMoveDown={this.handleMoveDown}
contextType={timelineId}
commentsLimited
/>
))
<StatusContainer
key={statusId}
id={statusId}
onMoveUp={this.handleMoveUp}
onMoveDown={this.handleMoveDown}
contextType={timelineId}
commentsLimited
/>
))
) : null;
if (scrollableContent && featuredStatusIds) {

@ -2,10 +2,11 @@ import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
import { injectIntl, defineMessages } from 'react-intl'
import { me } from '../initial_state'
import { BREAKPOINT_EXTRA_SMALL } from '../constants'
import ComposeFormContainer from '../features/compose/containers/compose_form_container'
import ResponsiveClassesComponent from '../features/ui/util/responsive_classes_component'
import Responsive from '../features/ui/util/responsive_component'
import Avatar from './avatar'
import Block from './block'
import Heading from './heading'
const messages = defineMessages({
@ -42,7 +43,6 @@ class TimelineComposeBlock extends ImmutablePureComponent {
} = this.props
if (modal) {
console.log("modal timeline composer: ", this.props)
return (
<section className={_s.default}>
<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(' ')}
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(' ')}>
<div className={_s.mr10}>
<Avatar account={account} size={20} noHover />
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
<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>
<Heading size='h5'>
{intl.formatMessage(messages.createPost)}
</Heading>
</div>
<Heading size='h5'>
{intl.formatMessage(messages.createPost)}
</Heading>
</div>
</Responsive>
<ComposeFormContainer {...rest} />
</ResponsiveClassesComponent>
</section>

@ -45,6 +45,7 @@ export const MODAL_GIF_PICKER = 'GIF_PICKER'
export const MODAL_GROUP_CREATE = 'GROUP_CREATE'
export const MODAL_GROUP_DELETE = 'GROUP_DELETE'
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_HOME_TIMELINE_SETTINGS = 'HOME_TIMELINE_SETTINGS'
export const MODAL_HOTKEYS = 'HOTKEYS'

@ -8,8 +8,10 @@ import {
CX,
MAX_POST_CHARACTER_COUNT,
ALLOWED_AROUND_SHORT_CODE,
BREAKPOINT_EXTRA_SMALL,
} from '../../../constants'
import AutosuggestTextbox from '../../../components/autosuggest_textbox'
import Responsive from '../../ui/util/responsive_component'
import Avatar from '../../../components/avatar'
import Button from '../../../components/button'
import CharacterCounter from '../../../components/character_counter'
@ -462,7 +464,9 @@ class ComposeForm extends ImmutablePureComponent {
{ /* !shouldCondense && <RichTextEditorButton /> */}
</div>
<CharacterCounter max={MAX_POST_CHARACTER_COUNT} text={text} />
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
<CharacterCounter max={MAX_POST_CHARACTER_COUNT} text={text} />
</Responsive>
<Button
isOutline

@ -1,6 +1,8 @@
import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
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 ScrollableList from '../components/scrollable_list'
import GroupCollectionItem from '../components/group_collection_item'
@ -40,24 +42,37 @@ class GroupsCollection extends ImmutablePureComponent {
return (
<div className={[_s.default, _s.flexRow, _s.flexWrap].join(' ')}>
<div className={[_s.default, _s.flexNormal].join(' ')}>
<ScrollableList scrollKey='group-collection-column-1'>
{
groupIds.slice(0, halfCount).map((groupId, i) => (
<GroupCollectionItem key={`group-collection-item-${i}`} id={groupId} />
))
}
</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 max={BREAKPOINT_EXTRA_SMALL}>
<div className={[_s.default, _s.width100PC, _s.px5].join(' ')}>
<ScrollableList scrollKey='group-collection-column-1'>
{
groupIds.map((groupId, i) => (
<GroupCollectionItem key={`group-collection-item-${i}`} id={groupId} />
))
}
</ScrollableList>
</div>
</Responsive>
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
<div className={[_s.default, _s.flexNormal].join(' ')}>
<ScrollableList scrollKey='group-collection-column-1'>
{
groupIds.slice(0, halfCount).map((groupId, i) => (
<GroupCollectionItem key={`group-collection-item-${i}`} id={groupId} />
))
}
</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>
)
}

@ -22,7 +22,7 @@ class HomeTimeline extends PureComponent {
isPartial: PropTypes.bool,
}
handleLoadMore = maxId => {
handleLoadMore = (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 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 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 GroupMembers() { return import(/* webpackChunkName: "features/group_members" */'../../group_members') }
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'>
<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
@ -78,7 +81,7 @@ export default class Layout extends PureComponent {
{
!!tabs &&
<Responsive max={BREAKPOINT_EXTRA_SMALL}>
<div className={[_s.default, _s.pb15].join(' ')}>
<div className={[_s.default, _s.py15].join(' ')}>
<Pills pills={tabs} />
</div>
</Responsive>
@ -110,7 +113,7 @@ export default class Layout extends PureComponent {
</Responsive>
}
</div>
</ResponsiveClassesComponent>
</main>
</ResponsiveClassesComponent>

@ -59,10 +59,11 @@ class GroupPage extends ImmutablePureComponent {
group={group}
relationships={relationships}
actions={[
{
icon: 'ellipsis',
onClick: null,
},
// : todo :
// {
// icon: 'ellipsis',
// onClick: null,
// },
]}
layout={(
<Fragment>

@ -2,7 +2,10 @@ import { Fragment } from 'react'
import { me } from '../initial_state'
import { defineMessages, injectIntl } from 'react-intl'
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 LinkFooter from '../components/link_footer'
import GroupsPanel from '../components/panel/groups_panel'
@ -22,8 +25,12 @@ const mapStateToProps = (state) => ({
})
const mapDispatchToProps = (dispatch) => ({
onOpenGroupCreateModal() {
dispatch(openModal(MODAL_GROUP_CREATE))
onOpenGroupCreateModal(isPro) {
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,
}
handleOnOpenGroupCreateModal = () => {
this.props.onOpenGroupCreateModal(this.props.isPro)
}
render() {
const {
intl,
@ -47,7 +58,12 @@ class GroupsPage extends PureComponent {
onOpenGroupCreateModal,
} = this.props
const actions = []
const actions = [
{
icon: 'add',
onClick: this.handleOnOpenGroupCreateModal,
},
]
const tabs = [
{
title: intl.formatMessage(messages.featured),
@ -64,11 +80,6 @@ class GroupsPage extends PureComponent {
]
if (isPro) {
actions.push({
icon: 'add',
onClick: onOpenGroupCreateModal,
})
tabs.push({
title: intl.formatMessage(messages.admin),
to: '/groups/browse/admin',
@ -79,7 +90,6 @@ class GroupsPage extends PureComponent {
return (
<DefaultLayout
showBackBtn
title={title}
actions={actions}
tabs={tabs}

@ -15,6 +15,7 @@ import TrendsPanel from '../components/panel/trends_panel'
import DefaultLayout from '../layouts/default_layout'
import TimelineComposeBlock from '../components/timeline_compose_block'
import Divider from '../components/divider'
import PullToRefresher from '../components/pull_to_refresher'
const messages = defineMessages({
home: { id: 'home', defaultMessage: 'Home' },
@ -116,6 +117,8 @@ class HomePage extends PureComponent {
badge={totalQueuedItemsCount}
/>
<PullToRefresher />
<TimelineComposeBlock autoFocus={false} />
<Divider />

@ -47,6 +47,7 @@ class SearchPage extends PureComponent {
return (
<Layout
noComposeButton
title={title}
showBackBtn
tabs={tabs}

@ -386,13 +386,14 @@ body {
/* */
.topNeg60PX { top: -60px; }
.top0 { top: 0; }
.top80PX { top: 80px; }
.top60PC { top: 60%; }
.top50PC { top: 50%; }
.bottom0 { bottom: 0; }
.bottom50PX { bottom: 50px; }
.bottom55PX { bottom: 55px; }
.bottomAuto { bottom: auto; }
.left0 { left: 0px; }
@ -429,7 +430,8 @@ body {
.heightMin100VH { min-height: 100vh; }
.heightMin50VH { min-height: 50vh; }
.heightMin100PX { min-height: 100px; }
.heightMin80PX { min-height: 80px; }
.heightMin58PX { min-height: 58px; }
.heightMin50PX { min-height: 50px; }
.height100PC { height: 100%; }
@ -843,6 +845,11 @@ body {
-ms-overflow-style: none;
}
.footerChin {
padding-bottom: 0;
padding-bottom: env(safe-area-inset-bottom, 0);
}
/**
* Rich Text Editor
*/