This commit is contained in:
mgabdev
2020-04-07 21:06:59 -04:00
parent b5e3c2a94f
commit bb4fcdf32d
101 changed files with 1069 additions and 1886 deletions

View File

@@ -84,7 +84,7 @@ class AccountGallery extends ImmutablePureComponent {
isLoading,
hasMore,
intl,
account
account,
} = this.props
if (!account) return null
@@ -109,7 +109,7 @@ class AccountGallery extends ImmutablePureComponent {
}
{ /*
attachments.size == 0 &&
attachments.size === 0 &&
<ColumnIndicator type='empty' message={intl.formatMessage(messages.none)} />
*/ }

View File

@@ -1,7 +1,7 @@
import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
import { debounce } from 'lodash'
import debounce from 'lodash.debounce'
import { fetchBlocks, expandBlocks } from '../actions/blocks'
import AccountContainer from '../containers/account_container'
import ColumnIndicator from '../components/column_indicator'

View File

@@ -1,7 +1,7 @@
import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
import { debounce } from 'lodash'
import debounce from 'lodash.debounce'
import { unblockDomain, fetchDomainBlocks, expandDomainBlocks } from '../actions/domain_blocks'
import ColumnIndicator from '../components/column_indicator'
import List from '../components/list'

View File

@@ -1,8 +1,8 @@
import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import { length } from 'stringz'
import ImmutablePropTypes from 'react-immutable-proptypes'
import classNames from 'classnames/bind'
import { length } from 'stringz'
import CharacterCounter from '../../../../components/character_counter'
import UploadForm from '../upload_form'
import AutosuggestTextbox from '../../../../components/autosuggest_textbox'
@@ -15,7 +15,7 @@ import StatusVisibilityButton from '../../components/status_visibility_button'
import EmojiPickerButton from '../../components/emoji_picker_button'
import PollFormContainer from '../../containers/poll_form_container'
import SchedulePostButton from '../schedule_post_button'
import QuotedStatusPreviewContainer from '../../containers/quoted_status_preview_container'
import StatusContainer from '../../../../containers/status_container'
import Button from '../../../../components/button'
import Avatar from '../../../../components/avatar'
import { isMobile } from '../../../../utils/is_mobile'
@@ -29,7 +29,7 @@ const messages = defineMessages({
spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Write your warning here' },
publish: { id: 'compose_form.publish', defaultMessage: 'Gab' },
publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}' },
schedulePost: { id: 'compose_form.schedule_post', defaultMessage: 'Schedule Post' }
schedulePost: { id: 'compose_form.schedule_post', defaultMessage: 'Schedule Post' },
});
const cx = classNames.bind(_s)
@@ -79,6 +79,7 @@ class ComposeForm extends ImmutablePureComponent {
scheduledAt: PropTypes.instanceOf(Date),
setScheduledAt: PropTypes.func.isRequired,
replyToId: PropTypes.string,
hasPoll: PropTypes.bool,
};
static defaultProps = {
@@ -104,7 +105,7 @@ class ComposeForm extends ImmutablePureComponent {
handleClick = (e) => {
if (!this.form) return false;
if (e.target) {
if (e.target.classList.contains('react-datepicker__time-list-item')) return;
if (e.target.classList.contains('react-datepicker__time-list-item')) return false
}
if (!this.form.contains(e.target)) {
this.handleClickOutside();
@@ -162,11 +163,11 @@ class ComposeForm extends ImmutablePureComponent {
}
componentDidMount() {
document.addEventListener("click", this.handleClick, false);
document.addEventListener('click', this.handleClick, false);
}
componentWillUnmount() {
document.removeEventListener("click", this.handleClick, false);
document.removeEventListener('click', this.handleClick, false);
}
componentDidUpdate(prevProps) {
@@ -201,19 +202,19 @@ class ComposeForm extends ImmutablePureComponent {
}
setForm = (c) => {
this.form = c;
this.form = c
}
setSpoilerText = (c) => {
this.spoilerText = c;
this.spoilerText = c
}
handleEmojiPick = (data) => {
const { text } = this.props;
const position = this.autosuggestTextarea.textbox.selectionStart;
const needsSpace = data.custom && position > 0 && !allowedAroundShortCode.includes(text[position - 1]);
const { text } = this.props
const position = this.autosuggestTextarea.textbox.selectionStart
const needsSpace = data.custom && position > 0 && !allowedAroundShortCode.includes(text[position - 1])
this.props.onPickEmoji(position, data, needsSpace);
this.props.onPickEmoji(position, data, needsSpace)
}
render() {
@@ -230,11 +231,13 @@ class ComposeForm extends ImmutablePureComponent {
edit,
scheduledAt,
spoiler,
replyToId
replyToId,
hasPoll,
isUploading,
} = this.props
const disabled = this.props.isSubmitting;
const text = [this.props.spoilerText, countableText(this.props.text)].join('');
const disabledButton = disabled || this.props.isUploading || this.props.isChangingUpload || length(text) > maxPostCharacterCount || (text.length !== 0 && text.trim().length === 0 && !anyMedia);
const disabledButton = disabled || isUploading || this.props.isChangingUpload || length(text) > maxPostCharacterCount || (text.length !== 0 && text.trim().length === 0 && !anyMedia);
const shouldAutoFocus = autoFocus && !showSearch && !isMobile(window.innerWidth)
const parentContainerClasses = cx({
@@ -255,7 +258,8 @@ class ComposeForm extends ImmutablePureComponent {
const actionsContainerClasses = cx({
default: 1,
flexRow: 1,
alignItemsCenter: 1,
alignItemsCenter: !shouldCondense,
alignItemsStart: shouldCondense,
mt10: !shouldCondense,
px15: !shouldCondense,
})
@@ -313,19 +317,25 @@ class ComposeForm extends ImmutablePureComponent {
autoFocus={shouldAutoFocus}
small={shouldCondense}
textarea
>
/>
{
(isUploading || anyMedia) &&
<div className={[_s.default, _s.px15].join(' ')}>
<UploadForm replyToId={replyToId} />
{
!edit &&
<PollFormContainer replyToId={replyToId} />
}
</div>
}
</AutosuggestTextbox>
{
!edit && hasPoll &&
<div className={[_s.default, _s.px15].join(' ')}>
<PollFormContainer replyToId={replyToId} />
</div>
}
{ /* quoteOfId && <QuotedStatusPreviewContainer id={quoteOfId} /> */}
{
/* : todo : quoteOfId && <StatusContainer id={quoteOfId} /> */
}
<div className={actionsContainerClasses}>
<div className={[_s.default, _s.flexRow, _s.marginRightAuto].join(' ')}>
@@ -358,8 +368,8 @@ class ComposeForm extends ImmutablePureComponent {
!shouldCondense &&
<CharacterCounter max={maxPostCharacterCount} text={text} />
}
{
{ /* : todo : show send on shouldCondense if any text */
!shouldCondense &&
<Button
className={[_s.fontSize15PX, _s.px15].join(' ')}

View File

@@ -7,7 +7,7 @@ const messages = defineMessages({
})
const mapStateToProps = state => ({
active: state.get('popover').popoverType === 'EMOJI_PICKER',
active: state.getIn(['popover', 'popoverType']) === 'EMOJI_PICKER',
})
const mapDispatchToProps = dispatch => ({

View File

@@ -9,7 +9,7 @@ const messages = defineMessages({
})
const mapStateToProps = (state) => ({
active: !!state.getIn(['compose', 'gif']) || state.get('modal').modalType === 'GIF_PICKER',
active: !!state.getIn(['compose', 'gif']) || state.getIn(['modal', 'modalType']) === 'GIF_PICKER',
})
const mapDispatchToProps = (dispatch) => ({

View File

@@ -1,23 +0,0 @@
import ImmutablePropTypes from 'react-immutable-proptypes';
import DisplayName from '../../../components/display_name';
import StatusContent from '../../../components/status_content';
// : todo : do we need this? make work inside of status/status content
export default class QuotedStatusPreview extends PureComponent {
static propTypes = {
status: ImmutablePropTypes.map,
account: ImmutablePropTypes.map,
}
render() {
const { status, account } = this.props;
return (
<div className='compose-form__quote-preview'>
<DisplayName account={account} />
<StatusContent status={status} expanded={false} />
</div>
);
}
}

View File

@@ -28,6 +28,11 @@ class StatusVisibilityButton extends PureComponent {
intl: PropTypes.object.isRequired,
small: PropTypes.bool,
onOpenPopover: PropTypes.func.isRequired,
value: PropTypes.oneOf([
'private',
'unlisted',
'public',
]),
}
handleOnClick = () => {
@@ -42,20 +47,20 @@ class StatusVisibilityButton extends PureComponent {
const {
intl,
small,
value
value,
} = this.props
let icon;
switch (value) {
case 'unlisted':
icon = 'unlock-filled'
break;
case 'private':
icon = 'lock-filled'
break;
default:
icon = 'globe'
break;
case 'unlisted':
icon = 'unlock-filled'
break;
case 'private':
icon = 'lock-filled'
break;
default:
icon = 'globe'
break;
}
return (

View File

@@ -24,7 +24,7 @@ class UploadForm extends ImmutablePureComponent {
const {
mediaIds,
isUploading,
uploadProgress
uploadProgress,
} = this.props
return (

View File

@@ -71,7 +71,7 @@ class Compose extends ImmutablePureComponent {
render () {
const { showSearch, isSearchPage, intl } = this.props;
let header = '';
const header = '';
return (
<div className='drawer' role='region' aria-label={intl.formatMessage(messages.compose)}>

View File

@@ -35,10 +35,11 @@ const mapStateToProps = (state, { replyToId }) => {
isUploading: !isMatch ? false : state.getIn(['compose', 'is_uploading']),
showSearch: !isMatch ? false : state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']),
anyMedia: !isMatch ? false : state.getIn(['compose', 'media_attachments']).size > 0,
isModalOpen: !isMatch ? false : state.get('modal').modalType === 'COMPOSE',
isModalOpen: !isMatch ? false : state.getIn(['modal', 'modalType']) === 'COMPOSE',
quoteOfId: !isMatch ? null : state.getIn(['compose', 'quote_of_id']),
scheduledAt: !isMatch ? null : state.getIn(['compose', 'scheduled_at']),
account: state.getIn(['accounts', me]),
hasPoll: !isMatch ? false : state.getIn(['compose', 'poll']),
}
}
@@ -84,7 +85,7 @@ const mapDispatchToProps = (dispatch) => ({
function mergeProps(stateProps, dispatchProps, ownProps) {
return Object.assign({}, ownProps, {
...stateProps,
...dispatchProps
...dispatchProps,
})
}

View File

@@ -1,8 +0,0 @@
import QuotedStatusPreview from '../components/quoted_status_preview';
const mapStateToProps = (state, { id }) => ({
status: state.getIn(['statuses', id]),
account: state.getIn(['accounts', state.getIn(['statuses', id, 'account'])]),
});
export default connect(mapStateToProps)(QuotedStatusPreview);

View File

@@ -1,9 +1,9 @@
import { urlRegex } from './url_regex';
import { urlRegex } from './url_regex'
const urlPlaceholder = 'xxxxxxxxxxxxxxxxxxxxxxx';
const urlPlaceholder = 'xxxxxxxxxxxxxxxxxxxxxxx'
export function countableText(inputText) {
return inputText
.replace(urlRegex, urlPlaceholder)
.replace(/(^|[^\/\w])@(([a-z0-9_]+)@[a-z0-9\.\-]+[a-z0-9]+)/ig, '$1@$3');
};
}

View File

@@ -1,7 +1,7 @@
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { debounce } from 'lodash';
import debounce from 'lodash.debounce'
import { fetchFollowRequests, expandFollowRequests } from '../../actions/accounts';
import ColumnIndicator from '../../components/column_indicator';
import AccountAuthorize from './components/account_authorize';

View File

@@ -1,6 +1,6 @@
import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
import { debounce } from 'lodash'
import debounce from 'lodash.debounce'
import { defineMessages, injectIntl } from 'react-intl'
import {
fetchFollowers,

View File

@@ -1,6 +1,6 @@
import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
import { debounce } from 'lodash'
import debounce from 'lodash.debounce'
import { defineMessages, injectIntl } from 'react-intl'
import {
fetchFollowing,

View File

@@ -1,6 +1,6 @@
import ImmutablePureComponent from 'react-immutable-pure-component';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { debounce } from 'lodash';
import debounce from 'lodash.debounce'
import {
fetchMembers,
expandMembers,

View File

@@ -1,6 +1,6 @@
import ImmutablePureComponent from 'react-immutable-pure-component';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { debounce } from 'lodash';
import debounce from 'lodash.debounce'
import ColumnIndicator from '../components/column_indicator';
import {
fetchRemovedAccounts,

View File

@@ -12,6 +12,7 @@ const mapStateToProps = (state, { activeTab }) => ({
export default
@connect(mapStateToProps)
class GroupsCollection extends ImmutablePureComponent {
static propTypes = {
activeTab: PropTypes.string.isRequired,
dispatch: PropTypes.func.isRequired,
@@ -35,14 +36,32 @@ class GroupsCollection extends ImmutablePureComponent {
return <ColumnIndicator type='loading' />
}
const halfCount = parseInt(groupIds.size / 2)
console.log("halfCount", halfCount)
return (
<div className={[_s.default, _s.flexRow, _s.flexWrap].join(' ')}>
{
groupIds.map((groupId, i) => (
<GroupCollectionItem key={`group-collection-item-${i}`} id={groupId} />
))
}
<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>
</div>
)
}
}

View File

@@ -1,5 +1,5 @@
import { FormattedMessage } from 'react-intl'
import { isEqual } from 'lodash'
import isEqual from 'lodash.isequal'
import { expandHashtagTimeline, clearTimeline } from '../actions/timelines'
import { connectHashtagStream } from '../actions/streaming'
import StatusListContainer from '../containers/status_list_container'
@@ -21,7 +21,7 @@ class HashtagTimeline extends PureComponent {
}
title = () => {
let title = [this.props.params.id]
const title = [this.props.params.id]
if (this.additionalFor('any')) {
title.push(' ',
@@ -29,7 +29,7 @@ class HashtagTimeline extends PureComponent {
key='any'
id='hashtag.column_header.tag_mode.any'
values={{
additional: this.additionalFor('any')
additional: this.additionalFor('any'),
}}
defaultMessage='or {additional}'
/>
@@ -42,7 +42,7 @@ class HashtagTimeline extends PureComponent {
key='all'
id='hashtag.column_header.tag_mode.all'
values={{
additional: this.additionalFor('all')
additional: this.additionalFor('all'),
}}
defaultMessage='and {additional}'
/>
@@ -55,7 +55,7 @@ class HashtagTimeline extends PureComponent {
key='none'
id='hashtag.column_header.tag_mode.none'
values={{
additional: this.additionalFor('none')
additional: this.additionalFor('none'),
}}
defaultMessage='without {additional}'
/>
@@ -76,13 +76,13 @@ class HashtagTimeline extends PureComponent {
}
_subscribe (dispatch, id, tags = {}) {
let any = (tags.any || []).map(tag => tag.value)
let all = (tags.all || []).map(tag => tag.value)
let none = (tags.none || []).map(tag => tag.value);
const any = (tags.any || []).map(tag => tag.value)
const all = (tags.all || []).map(tag => tag.value)
const none = (tags.none || []).map(tag => tag.value);
[id, ...any].map(tag => {
this.disconnects.push(dispatch(connectHashtagStream(id, tag, status => {
let tags = status.tags.map(tag => tag.name)
const tags = status.tags.map(tag => tag.name)
return all.filter(tag => tags.includes(tag)).length === all.length &&
none.filter(tag => tags.includes(tag)).length === 0

View File

@@ -5,7 +5,7 @@ import { closeOnboarding } from '../actions/onboarding';
// : todo :
class FrameWelcome extends Component {
class FrameWelcome extends React.Component {
static propTypes = {
domain: PropTypes.string.isRequired,
onNext: PropTypes.func.isRequired,
@@ -45,7 +45,7 @@ class FrameWelcome extends Component {
}
}
class FrameFederation extends Component {
class FrameFederation extends React.Component {
static propTypes = {
onNext: PropTypes.func.isRequired,
}
@@ -81,7 +81,7 @@ class FrameFederation extends Component {
}
};
class FrameInteractions extends Component {
class FrameInteractions extends React.Component {
static propTypes = {
onNext: PropTypes.func.isRequired,
};

View File

@@ -1,7 +1,7 @@
import ImmutablePropTypes from 'react-immutable-proptypes'
import { FormattedMessage } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import { debounce } from 'lodash'
import debounce from 'lodash.debounce'
import { fetchFavoritedStatuses, expandFavoritedStatuses } from '../actions/favorites'
import { meUsername } from '../initial_state'
import StatusList from '../components/status_list'

View File

@@ -1,7 +1,7 @@
import { injectIntl, FormattedMessage } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
import { debounce } from 'lodash'
import debounce from 'lodash.debounce'
import { fetchMutes, expandMutes } from '../actions/mutes'
import AccountContainer from '../containers/account_container'
import ColumnIndicator from '../components/column_indicator'

View File

@@ -3,7 +3,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component'
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'
import { createSelector } from 'reselect'
import { List as ImmutableList } from 'immutable'
import { debounce } from 'lodash'
import debounce from 'lodash.debounce'
import {
expandNotifications,
scrollTopNotifications,

View File

@@ -50,7 +50,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
onReply (status, router) {
dispatch((_, getState) => {
let state = getState();
const state = getState();
if (state.getIn(['compose', 'text']).trim().length !== 0) {
dispatch(openModal('CONFIRM', {
message: intl.formatMessage(messages.replyMessage),

View File

@@ -33,7 +33,7 @@ import StatusContainer from '../../containers/status_container'
import { textForScreenReader, defaultMediaVisibility } from '../../components/status/status'
import ColumnIndicator from '../../components/column_indicator'
import Block from '../../components/block'
import Comment from '../../components/comment'
import CommentList from '../../components/comment_list'
const messages = defineMessages({
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
@@ -57,23 +57,52 @@ const makeMapStateToProps = () => {
username: props.params.username,
})
// : todo : if is comment (i.e. if any ancestorsIds) use comment not status
let ancestorsIds = Immutable.List()
let descendantsIds = Immutable.List();
let descendantsIds = Immutable.List()
if (status) {
ancestorsIds = ancestorsIds.withMutations(mutable => {
let id = status.get('in_reply_to_id');
// ancestorsIds = ancestorsIds.withMutations(mutable => {
// let id = status.get('in_reply_to_id');
while (id) {
mutable.unshift(id);
id = state.getIn(['contexts', 'inReplyTos', id]);
// while (id) {
// mutable.unshift(id);
// id = state.getIn(['contexts', 'inReplyTos', id]);
// }
// });
// // ONLY Direct descendants
// descendantsIds = state.getIn(['contexts', 'replies', status.get('id')])
let indent = -1
descendantsIds = descendantsIds.withMutations(mutable => {
const ids = [status.get('id')]
while (ids.length > 0) {
let id = ids.shift();
const replies = state.getIn(['contexts', 'replies', id])
if (status.get('id') !== id) {
mutable.push(Immutable.Map({
statusId: id,
indent: indent,
}))
}
if (replies) {
replies.reverse().forEach(reply => {
ids.unshift(reply)
});
indent++
indent = Math.min(2, indent)
}
}
});
// ONLY Direct descendants
descendantsIds = state.getIn(['contexts', 'replies', status.get('id')])
})
}
console.log("descendantsIds:", descendantsIds)
return {
status,
ancestorsIds,
@@ -338,6 +367,7 @@ class Status extends ImmutablePureComponent {
renderChildren(list) {
console.log("list:", list)
return null
// : todo : comments
return list.map(id => (
<Comment
@@ -383,9 +413,9 @@ class Status extends ImmutablePureComponent {
return <ColumnIndicator type='loading' />
}
if (ancestorsIds && ancestorsIds.size > 0) {
ancestors = this.renderChildren(ancestorsIds)
}
// if (ancestorsIds && ancestorsIds.size > 0) {
// ancestors = this.renderChildren(ancestorsIds)
// }
if (descendantsIds && descendantsIds.size > 0) {
descendants = this.renderChildren(descendantsIds)
@@ -434,7 +464,7 @@ class Status extends ImmutablePureComponent {
<div className={[_s.default, _s.mr10, _s.ml10, _s.mb10, _s.borderColorSecondary, _s.borderBottom1PX].join(' ')}/>
}
{descendants}
<CommentList descendants={descendantsIds} />
</Block>
</div>
)

View File

@@ -3,7 +3,7 @@ import BundleColumnError from '../../../components/bundle_column_error'
import Bundle from './bundle'
import { me } from '../../../initial_state'
export default class WrappedRoute extends Component {
export default class WrappedRoute extends PureComponent {
static propTypes = {
component: PropTypes.func.isRequired,
page: PropTypes.func.isRequired,