Progress
This commit is contained in:
parent
8d452f0f6b
commit
59466ccc08
@ -79,10 +79,6 @@ export function importFetchedStatuses(statuses) {
|
||||
if (status.poll && status.poll.id) {
|
||||
pushUnique(polls, normalizePoll(status.poll));
|
||||
}
|
||||
|
||||
// if (status.replies_count > 0) {
|
||||
// dispatch(fetchComments(status.id));
|
||||
// }
|
||||
}
|
||||
|
||||
statuses.forEach(processStatus);
|
||||
|
@ -189,8 +189,13 @@ export function deleteStatusFail(id, error) {
|
||||
};
|
||||
};
|
||||
|
||||
export function fetchContext(id) {
|
||||
export function fetchContext(id, ensureIsReply) {
|
||||
return (dispatch, getState) => {
|
||||
if (ensureIsReply) {
|
||||
const isReply = !!getState().getIn(['statuses', id, 'in_reply_to_id'], null)
|
||||
if (!isReply) return;
|
||||
}
|
||||
|
||||
dispatch(fetchContextRequest(id));
|
||||
|
||||
api(getState).get(`/api/v1/statuses/${id}/context`).then(response => {
|
||||
|
@ -259,7 +259,7 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
|
||||
return (
|
||||
<Fragment>
|
||||
<div className={textareaContainerClasses}>
|
||||
{/*<Textarea
|
||||
<Textarea
|
||||
inputRef={this.setTextbox}
|
||||
className={textareaClasses}
|
||||
disabled={disabled}
|
||||
@ -273,9 +273,9 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
|
||||
// onBlur={this.onBlur}
|
||||
// onPaste={this.onPaste}
|
||||
aria-autocomplete='list'
|
||||
/>*/}
|
||||
/>
|
||||
|
||||
<Composer
|
||||
{/*<Composer
|
||||
inputRef={this.setTextbox}
|
||||
disabled={disabled}
|
||||
placeholder={placeholder}
|
||||
@ -288,7 +288,7 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
|
||||
onBlur={this.onBlur}
|
||||
onPaste={this.onPaste}
|
||||
small={small}
|
||||
/>
|
||||
/>*/}
|
||||
|
||||
{children}
|
||||
</div>
|
||||
|
@ -4,7 +4,8 @@ import {
|
||||
CompositeDecorator,
|
||||
RichUtils,
|
||||
convertToRaw,
|
||||
convertFromRaw
|
||||
convertFromRaw,
|
||||
ContentState,
|
||||
} from 'draft-js'
|
||||
import { draftToMarkdown } from 'markdown-draft-js'
|
||||
// import draftToMarkdown from 'draftjs-to-markdown'
|
||||
@ -115,6 +116,14 @@ class Composer extends PureComponent {
|
||||
return null
|
||||
}
|
||||
|
||||
componentDidUpdate (prevProps) {
|
||||
// console.log("this.props.value:", this.props.value)
|
||||
if (prevProps.value !== this.props.value) {
|
||||
// const editorState = EditorState.push(this.state.editorState, ContentState.createFromText(this.props.value));
|
||||
// this.setState({ editorState })
|
||||
}
|
||||
}
|
||||
|
||||
// EditorState.createWithContent(ContentState.createFromText('Hello'))
|
||||
|
||||
onChange = (editorState) => {
|
||||
@ -122,17 +131,17 @@ class Composer extends PureComponent {
|
||||
const content = this.state.editorState.getCurrentContent();
|
||||
const text = content.getPlainText('\u0001')
|
||||
|
||||
const selectionState = editorState.getSelection()
|
||||
const selectionStart = selectionState.getStartOffset()
|
||||
// const selectionState = editorState.getSelection()
|
||||
// const selectionStart = selectionState.getStartOffset()
|
||||
|
||||
const rawObject = convertToRaw(content);
|
||||
const markdownString = draftToMarkdown(rawObject);
|
||||
// const rawObject = convertToRaw(content);
|
||||
// const markdownString = draftToMarkdown(rawObject);
|
||||
// const markdownString = draftToMarkdown(rawObject, {
|
||||
// trigger: '#',
|
||||
// separator: ' ',
|
||||
// });
|
||||
|
||||
console.log("markdownString:", markdownString)
|
||||
// console.log("text:", text, this.props.value)
|
||||
|
||||
this.props.onChange(null, text, selectionStart, markdownString)
|
||||
}
|
||||
|
@ -21,6 +21,10 @@ const mapStateToProps = (state) => ({
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
onOpenSidebar() {
|
||||
dispatch(openSidebar())
|
||||
},
|
||||
|
||||
onOpenNavSettingsPopover() {
|
||||
dispatch(openPopover())
|
||||
}
|
||||
})
|
||||
|
||||
@ -35,6 +39,7 @@ class NavigationBar extends ImmutablePureComponent {
|
||||
title: PropTypes.string,
|
||||
showBackBtn: PropTypes.bool,
|
||||
onOpenSidebar: PropTypes.func.isRequired,
|
||||
onOpenNavSettingsPopover: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
handleProfileClick = () => {
|
||||
|
@ -191,7 +191,9 @@ class EmojiPickerMenu extends ImmutablePureComponent {
|
||||
include={categoriesSort}
|
||||
recent={frequentlyUsedEmojis}
|
||||
skin={skinTone}
|
||||
emojiSize={24}
|
||||
perLine={8}
|
||||
emojiSize={22}
|
||||
sheetSize={32}
|
||||
set='twitter'
|
||||
color='#30CE7D'
|
||||
emoji=''
|
||||
|
@ -0,0 +1,65 @@
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import { MODAL_DISPLAY_OPTIONS } from '../../constants'
|
||||
import { openModal } from '../../actions/modal'
|
||||
import { closePopover } from '../../actions/popover'
|
||||
import PopoverLayout from './popover_layout'
|
||||
import List from '../list'
|
||||
|
||||
const messages = defineMessages({
|
||||
display: { id: 'display_options', defaultMessage: 'Display Options' },
|
||||
help: { id: 'getting_started.help', defaultMessage: 'Help' },
|
||||
settings: { id: 'settings', defaultMessage: 'Settings' },
|
||||
logout: { 'id': 'confirmations.logout.confirm', 'defaultMessage': 'Log out' },
|
||||
})
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
onOpenDisplayModal: () => {
|
||||
dispatch(closePopover())
|
||||
dispatch(openModal(MODAL_DISPLAY_OPTIONS))
|
||||
},
|
||||
})
|
||||
|
||||
export default
|
||||
@injectIntl
|
||||
@connect(null, mapDispatchToProps)
|
||||
class NavSettingsPopover extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
onOpenDisplayModal: PropTypes.func.isRequired,
|
||||
isXS: PropTypes.bool,
|
||||
}
|
||||
|
||||
handleOnOpenDisplayModal = () => {
|
||||
this.props.onOpenDisplayModal()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl, isXS } = this.props
|
||||
|
||||
if (isXS) return null
|
||||
|
||||
return (
|
||||
<PopoverLayout width={240}>
|
||||
<List
|
||||
size='large'
|
||||
scrollKey='profile_options'
|
||||
items={[
|
||||
{
|
||||
title: intl.formatMessage(messages.help),
|
||||
href: 'https://help.gab.com',
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage(messages.settings),
|
||||
href: '/settings/preferences',
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage(messages.logout),
|
||||
href: '/auth/sign_out',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</PopoverLayout>
|
||||
)
|
||||
}
|
||||
}
|
@ -290,8 +290,6 @@ class ProfileOptionsPopover extends PureComponent {
|
||||
handleBlockDomain = () => {
|
||||
const domain = this.props.account.get('acct').split('@')[1]
|
||||
|
||||
console.log("handleBlockDomain:", domain)
|
||||
|
||||
// : todo : alert
|
||||
if (!domain) return
|
||||
|
||||
|
@ -38,6 +38,8 @@ const messages = defineMessages({
|
||||
search: { id: 'tabs_bar.search', defaultMessage: 'Search' },
|
||||
shop: { id: 'tabs_bar.shop', defaultMessage: 'Store - Buy Merch' },
|
||||
chat: { id: 'tabs_bar.chat', defaultMessage: 'Chat' },
|
||||
help: { id: 'getting_started.help', defaultMessage: 'Help' },
|
||||
display: { id: 'display_options', defaultMessage: 'Display Options' },
|
||||
})
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
@ -48,7 +50,8 @@ const mapStateToProps = (state) => ({
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
onCloseSidebar: () => dispatch(closeSidebar()),
|
||||
onOpenDisplayModel() {
|
||||
dispatch(openModal())
|
||||
dispatch(closeSidebar())
|
||||
dispatch(openModal('DISPLAY_OPTIONS'))
|
||||
}
|
||||
})
|
||||
|
||||
@ -61,6 +64,7 @@ class SidebarXS extends ImmutablePureComponent {
|
||||
account: ImmutablePropTypes.map,
|
||||
sidebarOpen: PropTypes.bool,
|
||||
onCloseSidebar: PropTypes.func.isRequired,
|
||||
onOpenDisplayModel: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
componentDidUpdate () {
|
||||
@ -87,13 +91,12 @@ class SidebarXS extends ImmutablePureComponent {
|
||||
|
||||
const mainItems = [
|
||||
{
|
||||
icon: 'user',
|
||||
to: `/${acct}`,
|
||||
onClick: this.handleSidebarClose,
|
||||
title: intl.formatMessage(messages.profile),
|
||||
},
|
||||
{
|
||||
icon: 'arrow-up',
|
||||
icon: 'pro',
|
||||
href: 'https://pro.gab.com',
|
||||
onClick: this.handleSidebarClose,
|
||||
title: intl.formatMessage(messages.pro),
|
||||
@ -135,50 +138,45 @@ class SidebarXS extends ImmutablePureComponent {
|
||||
title: intl.formatMessage(messages.lists),
|
||||
},
|
||||
{
|
||||
icon: 'user',
|
||||
icon: 'group',
|
||||
to: '/follow_requests',
|
||||
onClick: this.handleSidebarClose,
|
||||
title: intl.formatMessage(messages.follow_requests),
|
||||
},
|
||||
{
|
||||
icon: 'user',
|
||||
icon: 'block',
|
||||
to: '/blocks',
|
||||
onClick: this.handleSidebarClose,
|
||||
title: intl.formatMessage(messages.blocks),
|
||||
},
|
||||
{
|
||||
icon: 'user',
|
||||
icon: 'website',
|
||||
to: '/domain_blocks',
|
||||
onClick: this.handleSidebarClose,
|
||||
title: intl.formatMessage(messages.domain_blocks),
|
||||
},
|
||||
{
|
||||
icon: 'user',
|
||||
icon: 'audio-mute',
|
||||
to: '/mutes',
|
||||
onClick: this.handleSidebarClose,
|
||||
title: intl.formatMessage(messages.mutes),
|
||||
},
|
||||
{
|
||||
icon: 'user',
|
||||
icon: 'report',
|
||||
to: '/filters',
|
||||
onClick: this.handleSidebarClose,
|
||||
title: intl.formatMessage(messages.filters),
|
||||
},
|
||||
{
|
||||
// : todo :
|
||||
icon: 'user',
|
||||
onClick: this.handleSidebarClose, //on open display model
|
||||
title: intl.formatMessage(messages.filters),
|
||||
onClick: this.props.onOpenDisplayModel, //on open display model
|
||||
title: intl.formatMessage(messages.display),
|
||||
},
|
||||
{
|
||||
// : todo :
|
||||
icon: 'user',
|
||||
href: 'https://help.gab.com',
|
||||
onClick: this.handleSidebarClose,
|
||||
title: intl.formatMessage(messages.filters),
|
||||
title: intl.formatMessage(messages.help),
|
||||
},
|
||||
{
|
||||
icon: 'user',
|
||||
href: '/auth/sign_out',
|
||||
title: intl.formatMessage(messages.logout),
|
||||
},
|
||||
|
@ -136,7 +136,7 @@ class Status extends ImmutablePureComponent {
|
||||
|
||||
static getDerivedStateFromProps(nextProps, prevState) {
|
||||
if (nextProps.isChild) return null
|
||||
|
||||
|
||||
if (!nextProps.isHidden && (nextProps.isIntersecting || !nextProps.commentsLimited) && !prevState.loadedComments) {
|
||||
return {
|
||||
loadedComments: true
|
||||
@ -159,7 +159,7 @@ class Status extends ImmutablePureComponent {
|
||||
// timeline lazy loading comments
|
||||
if (!prevState.loadedComments && this.state.loadedComments && this.props.status && !this.props.isChild) {
|
||||
const commentCount = this.props.status.get('replies_count')
|
||||
if (this.props.isComment) {
|
||||
if (this.props.isComment && !this.props.ancestorStatus) {
|
||||
this.props.onFetchContext(this.props.status.get('id'))
|
||||
this._measureHeight(prevState.height !== this.state.height)
|
||||
} else {
|
||||
@ -381,7 +381,9 @@ class Status extends ImmutablePureComponent {
|
||||
if (!status) return null
|
||||
|
||||
if (isComment && !ancestorStatus && !isChild) {
|
||||
return <ColumnIndicator type='loading' />
|
||||
// Wait to load...
|
||||
// return <ColumnIndicator type='loading' />
|
||||
return null
|
||||
}
|
||||
|
||||
let reblogContent, rebloggedByText = null
|
||||
|
@ -4,6 +4,7 @@ import Button from './button'
|
||||
import Text from './text'
|
||||
|
||||
export default class StatusActionBarItem extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
altTitle: PropTypes.string,
|
||||
@ -80,4 +81,5 @@ export default class StatusActionBarItem extends PureComponent {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
@ -8,7 +8,10 @@ import debounce from 'lodash.debounce'
|
||||
import { me, promotions } from '../initial_state';
|
||||
import { dequeueTimeline } from '../actions/timelines';
|
||||
import { scrollTopTimeline } from '../actions/timelines';
|
||||
import { fetchStatus } from '../actions/statuses';
|
||||
import {
|
||||
fetchStatus,
|
||||
fetchContext,
|
||||
} from '../actions/statuses';
|
||||
import StatusContainer from '../containers/status_container';
|
||||
import ScrollableList from './scrollable_list';
|
||||
import TimelineQueueButtonHeader from './timeline_queue_button_header';
|
||||
@ -71,7 +74,10 @@ const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
}, 100),
|
||||
fetchStatus(id) {
|
||||
dispatch(fetchStatus(id));
|
||||
}
|
||||
},
|
||||
onFetchContext(statusId) {
|
||||
dispatch(fetchContext(statusId, true))
|
||||
},
|
||||
});
|
||||
|
||||
export default
|
||||
@ -96,7 +102,12 @@ class StatusList extends ImmutablePureComponent {
|
||||
promotion: PropTypes.object, // : todo :
|
||||
promotedStatus: ImmutablePropTypes.map,
|
||||
fetchStatus: PropTypes.func,
|
||||
};
|
||||
onFetchContext: PropTypes.func,
|
||||
}
|
||||
|
||||
state = {
|
||||
fetchedContext: false,
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.handleDequeueTimeline();
|
||||
@ -111,6 +122,15 @@ class StatusList extends ImmutablePureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
fetchContextsForInitialStatuses = (statusIds) => {
|
||||
console.log("fetchContextsForInitialStatuses:", statusIds)
|
||||
for (let i = 0; i < statusIds.length; i++) {
|
||||
const statusId = statusIds[i];
|
||||
this.props.onFetchContext(statusId)
|
||||
}
|
||||
this.setState({ fetchedContext: true })
|
||||
}
|
||||
|
||||
getFeaturedStatusCount = () => {
|
||||
return this.props.featuredStatusIds ? this.props.featuredStatusIds.size : 0;
|
||||
}
|
||||
@ -180,11 +200,24 @@ class StatusList extends ImmutablePureComponent {
|
||||
promotedStatus,
|
||||
...other
|
||||
} = this.props
|
||||
const { fetchedContext } = this.state
|
||||
|
||||
if (isPartial) {
|
||||
return <ColumnIndicator type='loading' />
|
||||
}
|
||||
|
||||
// : hack :
|
||||
// if index is 0 or 1 and is comment, preload context
|
||||
if (statusIds && !fetchedContext) {
|
||||
const firstStatusId = statusIds.get(0)
|
||||
const secondStatusId = statusIds.get(1)
|
||||
let arr = []
|
||||
|
||||
if (!!firstStatusId) arr.push(firstStatusId)
|
||||
if (!!secondStatusId) arr.push(secondStatusId)
|
||||
if (arr.length > 0) this.fetchContextsForInitialStatuses(arr)
|
||||
}
|
||||
|
||||
let scrollableContent = (isLoading || statusIds.size > 0) ? (
|
||||
statusIds.map((statusId, index) => statusId === null ? (
|
||||
<div
|
||||
|
@ -320,9 +320,9 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
<div className={actionsContainerClasses}>
|
||||
<div className={[_s.default, _s.flexRow, _s.mrAuto].join(' ')}>
|
||||
|
||||
<EmojiPickerButton small={shouldCondense} isMatch={isMatch} />
|
||||
{ /* <EmojiPickerButton small={shouldCondense} isMatch={isMatch} /> */ }
|
||||
|
||||
<UploadButton small={shouldCondense} />
|
||||
{ /* <UploadButton small={shouldCondense} /> */ }
|
||||
|
||||
<div className={commentPublishBtnClasses}>
|
||||
<Button
|
||||
@ -452,7 +452,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
<div className={actionsContainerClasses}>
|
||||
<div className={[_s.default, _s.flexRow, _s.mrAuto].join(' ')}>
|
||||
|
||||
<EmojiPickerButton small={shouldCondense} isMatch={isMatch} />
|
||||
{ /* <EmojiPickerButton small={shouldCondense} isMatch={isMatch} /> */ }
|
||||
|
||||
<UploadButton small={shouldCondense} />
|
||||
{ /* <GifSelectorButton small={shouldCondense} /> */}
|
||||
|
@ -1,91 +1,13 @@
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { injectIntl, defineMessages } from 'react-intl';
|
||||
import spring from 'react-motion/lib/spring';
|
||||
import {
|
||||
changeComposing,
|
||||
mountCompose,
|
||||
unmountCompose,
|
||||
} from '../../actions/compose';
|
||||
import Motion from '../ui/util/optional_motion';
|
||||
import ComposeFormContainer from './containers/compose_form_container';
|
||||
import NavigationBar from './components/navigation_bar';
|
||||
import elephantUIPlane from '../../../images/logo_ui_column_footer.png';
|
||||
import ComposeFormContainer from './containers/compose_form_container'
|
||||
|
||||
const messages = defineMessages({
|
||||
start: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
|
||||
home_timeline: { id: 'tabs_bar.home', defaultMessage: 'Home' },
|
||||
notifications: { id: 'tabs_bar.notifications', defaultMessage: 'Notifications' },
|
||||
public: { id: 'navigation_bar.public_timeline', defaultMessage: 'Federated timeline' },
|
||||
community: { id: 'navigation_bar.community_timeline', defaultMessage: 'Community feed' },
|
||||
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
||||
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
|
||||
compose: { id: 'navigation_bar.compose', defaultMessage: 'Compose new gab' },
|
||||
});
|
||||
|
||||
const mapStateToProps = (state, ownProps) => ({
|
||||
columns: state.getIn(['settings', 'columns']),
|
||||
showSearch: ownProps.isSearchPage,
|
||||
});
|
||||
|
||||
export default
|
||||
@connect(mapStateToProps)
|
||||
@injectIntl
|
||||
class Compose extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
columns: ImmutablePropTypes.list.isRequired,
|
||||
showSearch: PropTypes.bool,
|
||||
isSearchPage: PropTypes.bool,
|
||||
intl: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
componentDidMount () {
|
||||
const { isSearchPage } = this.props;
|
||||
|
||||
if (!isSearchPage) {
|
||||
this.props.dispatch(mountCompose());
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
const { isSearchPage } = this.props;
|
||||
|
||||
if (!isSearchPage) {
|
||||
this.props.dispatch(unmountCompose());
|
||||
}
|
||||
}
|
||||
|
||||
onFocus = () => {
|
||||
this.props.dispatch(changeComposing(true));
|
||||
}
|
||||
|
||||
onBlur = () => {
|
||||
this.props.dispatch(changeComposing(false));
|
||||
}
|
||||
export default class Compose extends PureComponent {
|
||||
|
||||
render () {
|
||||
const { showSearch, isSearchPage, intl } = this.props;
|
||||
|
||||
const header = '';
|
||||
|
||||
return (
|
||||
<div className='drawer' role='region' aria-label={intl.formatMessage(messages.compose)}>
|
||||
{header}
|
||||
|
||||
{ /* isSearchPage && <SearchContainer /> */ }
|
||||
|
||||
<div className='drawer__pager'>
|
||||
{!isSearchPage && <div className='drawer__inner' onFocus={this.onFocus}>
|
||||
<NavigationBar onClose={this.onBlur} />
|
||||
|
||||
<ComposeFormContainer />
|
||||
|
||||
</div>}
|
||||
</div>
|
||||
<div className={[_s.default, _s.bgPrimary, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
|
||||
<ComposeFormContainer />
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ import {
|
||||
BlockedAccounts,
|
||||
BlockedDomains,
|
||||
CommunityTimeline,
|
||||
Compose,
|
||||
// Filters,
|
||||
Followers,
|
||||
Following,
|
||||
@ -145,7 +146,7 @@ class SwitchingArea extends PureComponent {
|
||||
<Redirect from='/' to='/home' exact />
|
||||
<WrappedRoute path='/home' exact page={HomePage} component={HomeTimeline} content={children} />
|
||||
|
||||
<WrappedRoute path='/compose' exact page={CommunityPage} component={CommunityTimeline} content={children} />
|
||||
<WrappedRoute path='/compose' exact page={BasicPage} component={Compose} content={children} componentParams={{ title: 'Gab' }} />
|
||||
|
||||
<WrappedRoute path='/timeline/all' exact page={CommunityPage} component={CommunityTimeline} content={children} componentParams={{ title: 'Community Feed' }} />
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user