[Glitch] Use a modern React context for identity in the app
Port a178ba7cd5
to glitch-soc
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
parent
e46321e63d
commit
ca5955ed76
27 changed files with 215 additions and 230 deletions
|
@ -14,8 +14,10 @@ import CloseIcon from '@/material-icons/400-24px/close.svg?react';
|
||||||
import SettingsIcon from '@/material-icons/400-24px/settings.svg?react';
|
import SettingsIcon from '@/material-icons/400-24px/settings.svg?react';
|
||||||
import { Icon } from 'flavours/glitch/components/icon';
|
import { Icon } from 'flavours/glitch/components/icon';
|
||||||
import { ButtonInTabsBar } from 'flavours/glitch/features/ui/util/columns_context';
|
import { ButtonInTabsBar } from 'flavours/glitch/features/ui/util/columns_context';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
||||||
|
|
||||||
|
|
||||||
import { useAppHistory } from './router';
|
import { useAppHistory } from './router';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
@ -51,12 +53,8 @@ BackButton.propTypes = {
|
||||||
};
|
};
|
||||||
|
|
||||||
class ColumnHeader extends PureComponent {
|
class ColumnHeader extends PureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
title: PropTypes.node,
|
title: PropTypes.node,
|
||||||
icon: PropTypes.string,
|
icon: PropTypes.string,
|
||||||
|
@ -171,7 +169,7 @@ class ColumnHeader extends PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.context.identity.signedIn && (children || (multiColumn && this.props.onPin))) {
|
if (this.props.identity.signedIn && (children || (multiColumn && this.props.onPin))) {
|
||||||
collapseButton = (
|
collapseButton = (
|
||||||
<button
|
<button
|
||||||
className={collapsibleButtonClassName}
|
className={collapsibleButtonClassName}
|
||||||
|
@ -232,4 +230,4 @@ class ColumnHeader extends PureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default injectIntl(withRouter(ColumnHeader));
|
export default injectIntl(withIdentity(withRouter(ColumnHeader)));
|
||||||
|
|
|
@ -14,6 +14,7 @@ import CheckIcon from '@/material-icons/400-24px/check.svg?react';
|
||||||
import { Icon } from 'flavours/glitch/components/icon';
|
import { Icon } from 'flavours/glitch/components/icon';
|
||||||
import emojify from 'flavours/glitch/features/emoji/emoji';
|
import emojify from 'flavours/glitch/features/emoji/emoji';
|
||||||
import Motion from 'flavours/glitch/features/ui/util/optional_motion';
|
import Motion from 'flavours/glitch/features/ui/util/optional_motion';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
|
|
||||||
import { RelativeTimestamp } from './relative_timestamp';
|
import { RelativeTimestamp } from './relative_timestamp';
|
||||||
|
|
||||||
|
@ -38,12 +39,8 @@ const makeEmojiMap = record => record.get('emojis').reduce((obj, emoji) => {
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
class Poll extends ImmutablePureComponent {
|
class Poll extends ImmutablePureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
poll: ImmutablePropTypes.map,
|
poll: ImmutablePropTypes.map,
|
||||||
lang: PropTypes.string,
|
lang: PropTypes.string,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
|
@ -235,7 +232,7 @@ class Poll extends ImmutablePureComponent {
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div className='poll__footer'>
|
<div className='poll__footer'>
|
||||||
{!showResults && <button className='button button-secondary' disabled={disabled || !this.context.identity.signedIn} onClick={this.handleVote}><FormattedMessage id='poll.vote' defaultMessage='Vote' /></button>}
|
{!showResults && <button className='button button-secondary' disabled={disabled || !this.props.identity.signedIn} onClick={this.handleVote}><FormattedMessage id='poll.vote' defaultMessage='Vote' /></button>}
|
||||||
{!showResults && <><button className='poll__link' onClick={this.handleReveal}><FormattedMessage id='poll.reveal' defaultMessage='See results' /></button> · </>}
|
{!showResults && <><button className='poll__link' onClick={this.handleReveal}><FormattedMessage id='poll.reveal' defaultMessage='See results' /></button> · </>}
|
||||||
{showResults && !this.props.disabled && <><button className='poll__link' onClick={this.handleRefresh}><FormattedMessage id='poll.refresh' defaultMessage='Refresh' /></button> · </>}
|
{showResults && !this.props.disabled && <><button className='poll__link' onClick={this.handleRefresh}><FormattedMessage id='poll.refresh' defaultMessage='Refresh' /></button> · </>}
|
||||||
{votesCount}
|
{votesCount}
|
||||||
|
@ -247,4 +244,4 @@ class Poll extends ImmutablePureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default injectIntl(Poll);
|
export default injectIntl(withIdentity(Poll));
|
||||||
|
|
|
@ -21,6 +21,7 @@ import RepeatActiveIcon from '@/svg-icons/repeat_active.svg?react';
|
||||||
import RepeatDisabledIcon from '@/svg-icons/repeat_disabled.svg';
|
import RepeatDisabledIcon from '@/svg-icons/repeat_disabled.svg';
|
||||||
import RepeatPrivateIcon from '@/svg-icons/repeat_private.svg';
|
import RepeatPrivateIcon from '@/svg-icons/repeat_private.svg';
|
||||||
import RepeatPrivateActiveIcon from '@/svg-icons/repeat_private_active.svg?react';
|
import RepeatPrivateActiveIcon from '@/svg-icons/repeat_private_active.svg?react';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'flavours/glitch/permissions';
|
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'flavours/glitch/permissions';
|
||||||
import { accountAdminLink, statusAdminLink } from 'flavours/glitch/utils/backend_links';
|
import { accountAdminLink, statusAdminLink } from 'flavours/glitch/utils/backend_links';
|
||||||
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
||||||
|
@ -67,12 +68,8 @@ const messages = defineMessages({
|
||||||
});
|
});
|
||||||
|
|
||||||
class StatusActionBar extends ImmutablePureComponent {
|
class StatusActionBar extends ImmutablePureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
status: ImmutablePropTypes.map.isRequired,
|
status: ImmutablePropTypes.map.isRequired,
|
||||||
onReply: PropTypes.func,
|
onReply: PropTypes.func,
|
||||||
onFavourite: PropTypes.func,
|
onFavourite: PropTypes.func,
|
||||||
|
@ -108,7 +105,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
];
|
];
|
||||||
|
|
||||||
handleReplyClick = () => {
|
handleReplyClick = () => {
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
if (signedIn) {
|
if (signedIn) {
|
||||||
this.props.onReply(this.props.status, this.props.history);
|
this.props.onReply(this.props.status, this.props.history);
|
||||||
|
@ -124,7 +121,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
handleFavouriteClick = (e) => {
|
handleFavouriteClick = (e) => {
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
if (signedIn) {
|
if (signedIn) {
|
||||||
this.props.onFavourite(this.props.status, e);
|
this.props.onFavourite(this.props.status, e);
|
||||||
|
@ -134,7 +131,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
handleReblogClick = e => {
|
handleReblogClick = e => {
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
if (signedIn) {
|
if (signedIn) {
|
||||||
this.props.onReblog(this.props.status, e);
|
this.props.onReblog(this.props.status, e);
|
||||||
|
@ -210,7 +207,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { status, intl, withDismiss, withCounters, showReplyCount, scrollKey } = this.props;
|
const { status, intl, withDismiss, withCounters, showReplyCount, scrollKey } = this.props;
|
||||||
const { permissions, signedIn } = this.context.identity;
|
const { permissions, signedIn } = this.props.identity;
|
||||||
|
|
||||||
const mutingConversation = status.get('muted');
|
const mutingConversation = status.get('muted');
|
||||||
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'));
|
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'));
|
||||||
|
@ -359,4 +356,4 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withRouter(injectIntl(StatusActionBar));
|
export default withRouter(withIdentity(injectIntl(StatusActionBar)));
|
||||||
|
|
|
@ -15,6 +15,7 @@ import LinkIcon from '@/material-icons/400-24px/link.svg?react';
|
||||||
import MovieIcon from '@/material-icons/400-24px/movie.svg?react';
|
import MovieIcon from '@/material-icons/400-24px/movie.svg?react';
|
||||||
import MusicNoteIcon from '@/material-icons/400-24px/music_note.svg?react';
|
import MusicNoteIcon from '@/material-icons/400-24px/music_note.svg?react';
|
||||||
import { Icon } from 'flavours/glitch/components/icon';
|
import { Icon } from 'flavours/glitch/components/icon';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { autoPlayGif, languages as preloadedLanguages } from 'flavours/glitch/initial_state';
|
import { autoPlayGif, languages as preloadedLanguages } from 'flavours/glitch/initial_state';
|
||||||
import { decode as decodeIDNA } from 'flavours/glitch/utils/idna';
|
import { decode as decodeIDNA } from 'flavours/glitch/utils/idna';
|
||||||
|
|
||||||
|
@ -126,12 +127,8 @@ const mapStateToProps = state => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
class StatusContent extends PureComponent {
|
class StatusContent extends PureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
status: ImmutablePropTypes.map.isRequired,
|
status: ImmutablePropTypes.map.isRequired,
|
||||||
statusContent: PropTypes.string,
|
statusContent: PropTypes.string,
|
||||||
expanded: PropTypes.bool,
|
expanded: PropTypes.bool,
|
||||||
|
@ -349,7 +346,7 @@ class StatusContent extends PureComponent {
|
||||||
const hidden = this.props.onExpandedToggle ? !this.props.expanded : this.state.hidden;
|
const hidden = this.props.onExpandedToggle ? !this.props.expanded : this.state.hidden;
|
||||||
const contentLocale = intl.locale.replace(/[_-].*/, '');
|
const contentLocale = intl.locale.replace(/[_-].*/, '');
|
||||||
const targetLanguages = this.props.languages?.get(status.get('language') || 'und');
|
const targetLanguages = this.props.languages?.get(status.get('language') || 'und');
|
||||||
const renderTranslate = this.props.onTranslate && this.context.identity.signedIn && ['public', 'unlisted'].includes(status.get('visibility')) && status.get('search_index').trim().length > 0 && targetLanguages?.includes(contentLocale);
|
const renderTranslate = this.props.onTranslate && this.props.identity.signedIn && ['public', 'unlisted'].includes(status.get('visibility')) && status.get('search_index').trim().length > 0 && targetLanguages?.includes(contentLocale);
|
||||||
|
|
||||||
const content = { __html: statusContent ?? getStatusContent(status) };
|
const content = { __html: statusContent ?? getStatusContent(status) };
|
||||||
const spoilerContent = { __html: status.getIn(['translation', 'spoilerHtml']) || status.get('spoilerHtml') };
|
const spoilerContent = { __html: status.getIn(['translation', 'spoilerHtml']) || status.get('spoilerHtml') };
|
||||||
|
@ -503,4 +500,4 @@ class StatusContent extends PureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withRouter(connect(mapStateToProps)(injectIntl(StatusContent)));
|
export default withRouter(withIdentity(connect(mapStateToProps)(injectIntl(StatusContent))));
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { PureComponent } from 'react';
|
import { PureComponent } from 'react';
|
||||||
|
|
||||||
import { Helmet } from 'react-helmet';
|
import { Helmet } from 'react-helmet';
|
||||||
|
@ -15,6 +14,7 @@ import { connectUserStream } from 'flavours/glitch/actions/streaming';
|
||||||
import ErrorBoundary from 'flavours/glitch/components/error_boundary';
|
import ErrorBoundary from 'flavours/glitch/components/error_boundary';
|
||||||
import { Router } from 'flavours/glitch/components/router';
|
import { Router } from 'flavours/glitch/components/router';
|
||||||
import UI from 'flavours/glitch/features/ui';
|
import UI from 'flavours/glitch/features/ui';
|
||||||
|
import { IdentityContext, createIdentityContext } from 'flavours/glitch/identity_context';
|
||||||
import initialState, { title as siteTitle } from 'flavours/glitch/initial_state';
|
import initialState, { title as siteTitle } from 'flavours/glitch/initial_state';
|
||||||
import { IntlProvider } from 'flavours/glitch/locales';
|
import { IntlProvider } from 'flavours/glitch/locales';
|
||||||
import { store } from 'flavours/glitch/store';
|
import { store } from 'flavours/glitch/store';
|
||||||
|
@ -33,33 +33,9 @@ if (initialState.meta.me) {
|
||||||
store.dispatch(fetchCustomEmojis());
|
store.dispatch(fetchCustomEmojis());
|
||||||
}
|
}
|
||||||
|
|
||||||
const createIdentityContext = state => ({
|
|
||||||
signedIn: !!state.meta.me,
|
|
||||||
accountId: state.meta.me,
|
|
||||||
disabledAccountId: state.meta.disabled_account_id,
|
|
||||||
accessToken: state.meta.access_token,
|
|
||||||
permissions: state.role ? state.role.permissions : 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default class Mastodon extends PureComponent {
|
export default class Mastodon extends PureComponent {
|
||||||
|
|
||||||
static childContextTypes = {
|
|
||||||
identity: PropTypes.shape({
|
|
||||||
signedIn: PropTypes.bool.isRequired,
|
|
||||||
accountId: PropTypes.string,
|
|
||||||
disabledAccountId: PropTypes.string,
|
|
||||||
accessToken: PropTypes.string,
|
|
||||||
}).isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
identity = createIdentityContext(initialState);
|
identity = createIdentityContext(initialState);
|
||||||
|
|
||||||
getChildContext() {
|
|
||||||
return {
|
|
||||||
identity: this.identity,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (this.identity.signedIn) {
|
if (this.identity.signedIn) {
|
||||||
this.disconnect = store.dispatch(connectUserStream());
|
this.disconnect = store.dispatch(connectUserStream());
|
||||||
|
@ -79,6 +55,7 @@ export default class Mastodon extends PureComponent {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
|
<IdentityContext.Provider value={this.identity}>
|
||||||
<IntlProvider>
|
<IntlProvider>
|
||||||
<ReduxProvider store={store}>
|
<ReduxProvider store={store}>
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
|
@ -92,6 +69,7 @@ export default class Mastodon extends PureComponent {
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
</ReduxProvider>
|
</ReduxProvider>
|
||||||
</IntlProvider>
|
</IntlProvider>
|
||||||
|
</IdentityContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import { Icon } from 'flavours/glitch/components/icon';
|
||||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||||
import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator';
|
import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator';
|
||||||
import DropdownMenuContainer from 'flavours/glitch/containers/dropdown_menu_container';
|
import DropdownMenuContainer from 'flavours/glitch/containers/dropdown_menu_container';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { autoPlayGif, me, domain as localDomain } from 'flavours/glitch/initial_state';
|
import { autoPlayGif, me, domain as localDomain } from 'flavours/glitch/initial_state';
|
||||||
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'flavours/glitch/permissions';
|
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'flavours/glitch/permissions';
|
||||||
import { preferencesLink, profileLink, accountAdminLink } from 'flavours/glitch/utils/backend_links';
|
import { preferencesLink, profileLink, accountAdminLink } from 'flavours/glitch/utils/backend_links';
|
||||||
|
@ -94,6 +95,7 @@ const dateFormatOptions = {
|
||||||
class Header extends ImmutablePureComponent {
|
class Header extends ImmutablePureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
account: ImmutablePropTypes.record,
|
account: ImmutablePropTypes.record,
|
||||||
identity_props: ImmutablePropTypes.list,
|
identity_props: ImmutablePropTypes.list,
|
||||||
onFollow: PropTypes.func.isRequired,
|
onFollow: PropTypes.func.isRequired,
|
||||||
|
@ -117,10 +119,6 @@ class Header extends ImmutablePureComponent {
|
||||||
...WithRouterPropTypes,
|
...WithRouterPropTypes,
|
||||||
};
|
};
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
openEditProfile = () => {
|
openEditProfile = () => {
|
||||||
window.open(profileLink, '_blank');
|
window.open(profileLink, '_blank');
|
||||||
};
|
};
|
||||||
|
@ -170,7 +168,7 @@ class Header extends ImmutablePureComponent {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { account, hidden, intl } = this.props;
|
const { account, hidden, intl } = this.props;
|
||||||
const { signedIn, permissions } = this.context.identity;
|
const { signedIn, permissions } = this.props.identity;
|
||||||
|
|
||||||
if (!account) {
|
if (!account) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -414,4 +412,4 @@ class Header extends ImmutablePureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withRouter(injectIntl(Header));
|
export default withRouter(withIdentity(injectIntl(Header)));
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { connect } from 'react-redux';
|
||||||
|
|
||||||
import PeopleIcon from '@/material-icons/400-24px/group.svg?react';
|
import PeopleIcon from '@/material-icons/400-24px/group.svg?react';
|
||||||
import { DismissableBanner } from 'flavours/glitch/components/dismissable_banner';
|
import { DismissableBanner } from 'flavours/glitch/components/dismissable_banner';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { domain } from 'flavours/glitch/initial_state';
|
import { domain } from 'flavours/glitch/initial_state';
|
||||||
|
|
||||||
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
||||||
|
@ -40,16 +41,12 @@ const mapStateToProps = (state, { columnId }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
class CommunityTimeline extends PureComponent {
|
class CommunityTimeline extends PureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
onlyMedia: false,
|
onlyMedia: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
columnId: PropTypes.string,
|
columnId: PropTypes.string,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
|
@ -80,7 +77,7 @@ class CommunityTimeline extends PureComponent {
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
const { dispatch, onlyMedia } = this.props;
|
const { dispatch, onlyMedia } = this.props;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
dispatch(expandCommunityTimeline({ onlyMedia }));
|
dispatch(expandCommunityTimeline({ onlyMedia }));
|
||||||
|
|
||||||
|
@ -90,7 +87,7 @@ class CommunityTimeline extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate (prevProps) {
|
componentDidUpdate (prevProps) {
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
if (prevProps.onlyMedia !== this.props.onlyMedia) {
|
if (prevProps.onlyMedia !== this.props.onlyMedia) {
|
||||||
const { dispatch, onlyMedia } = this.props;
|
const { dispatch, onlyMedia } = this.props;
|
||||||
|
@ -165,4 +162,4 @@ class CommunityTimeline extends PureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps)(injectIntl(CommunityTimeline));
|
export default withIdentity(connect(mapStateToProps)(injectIntl(CommunityTimeline)));
|
||||||
|
|
|
@ -12,6 +12,7 @@ import CancelIcon from '@/material-icons/400-24px/cancel-fill.svg?react';
|
||||||
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
|
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
|
||||||
import SearchIcon from '@/material-icons/400-24px/search.svg?react';
|
import SearchIcon from '@/material-icons/400-24px/search.svg?react';
|
||||||
import { Icon } from 'flavours/glitch/components/icon';
|
import { Icon } from 'flavours/glitch/components/icon';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { domain, searchEnabled } from 'flavours/glitch/initial_state';
|
import { domain, searchEnabled } from 'flavours/glitch/initial_state';
|
||||||
import { HASHTAG_REGEX } from 'flavours/glitch/utils/hashtags';
|
import { HASHTAG_REGEX } from 'flavours/glitch/utils/hashtags';
|
||||||
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
||||||
|
@ -33,12 +34,8 @@ const labelForRecentSearch = search => {
|
||||||
};
|
};
|
||||||
|
|
||||||
class Search extends PureComponent {
|
class Search extends PureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
value: PropTypes.string.isRequired,
|
value: PropTypes.string.isRequired,
|
||||||
recent: ImmutablePropTypes.orderedSet,
|
recent: ImmutablePropTypes.orderedSet,
|
||||||
submitted: PropTypes.bool,
|
submitted: PropTypes.bool,
|
||||||
|
@ -276,7 +273,7 @@ class Search extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
_calculateOptions (value) {
|
_calculateOptions (value) {
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
const trimmedValue = value.trim();
|
const trimmedValue = value.trim();
|
||||||
const options = [];
|
const options = [];
|
||||||
|
|
||||||
|
@ -318,7 +315,7 @@ class Search extends PureComponent {
|
||||||
render () {
|
render () {
|
||||||
const { intl, value, submitted, recent } = this.props;
|
const { intl, value, submitted, recent } = this.props;
|
||||||
const { expanded, options, selectedOption } = this.state;
|
const { expanded, options, selectedOption } = this.state;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
const hasValue = value.length > 0 || submitted;
|
const hasValue = value.length > 0 || submitted;
|
||||||
|
|
||||||
|
@ -402,4 +399,4 @@ class Search extends PureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withRouter(injectIntl(Search));
|
export default withRouter(withIdentity(injectIntl(Search)));
|
||||||
|
|
|
@ -13,6 +13,7 @@ import SearchIcon from '@/material-icons/400-24px/search.svg?react';
|
||||||
import Column from 'flavours/glitch/components/column';
|
import Column from 'flavours/glitch/components/column';
|
||||||
import ColumnHeader from 'flavours/glitch/components/column_header';
|
import ColumnHeader from 'flavours/glitch/components/column_header';
|
||||||
import Search from 'flavours/glitch/features/compose/containers/search_container';
|
import Search from 'flavours/glitch/features/compose/containers/search_container';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { trendsEnabled } from 'flavours/glitch/initial_state';
|
import { trendsEnabled } from 'flavours/glitch/initial_state';
|
||||||
|
|
||||||
import Links from './links';
|
import Links from './links';
|
||||||
|
@ -32,12 +33,8 @@ const mapStateToProps = state => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
class Explore extends PureComponent {
|
class Explore extends PureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
multiColumn: PropTypes.bool,
|
multiColumn: PropTypes.bool,
|
||||||
isSearching: PropTypes.bool,
|
isSearching: PropTypes.bool,
|
||||||
|
@ -53,7 +50,7 @@ class Explore extends PureComponent {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { intl, multiColumn, isSearching } = this.props;
|
const { intl, multiColumn, isSearching } = this.props;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column bindToDocument={!multiColumn} ref={this.setRef} label={intl.formatMessage(messages.title)}>
|
<Column bindToDocument={!multiColumn} ref={this.setRef} label={intl.formatMessage(messages.title)}>
|
||||||
|
@ -114,4 +111,4 @@ class Explore extends PureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps)(injectIntl(Explore));
|
export default withIdentity(connect(mapStateToProps)(injectIntl(Explore)));
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { useIntl, defineMessages, FormattedMessage } from 'react-intl';
|
||||||
import { Helmet } from 'react-helmet';
|
import { Helmet } from 'react-helmet';
|
||||||
import { NavLink } from 'react-router-dom';
|
import { NavLink } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { useIdentity } from '@/flavours/glitch/identity_context';
|
||||||
import PublicIcon from '@/material-icons/400-24px/public.svg?react';
|
import PublicIcon from '@/material-icons/400-24px/public.svg?react';
|
||||||
import { addColumn } from 'flavours/glitch/actions/columns';
|
import { addColumn } from 'flavours/glitch/actions/columns';
|
||||||
import { changeSetting } from 'flavours/glitch/actions/settings';
|
import { changeSetting } from 'flavours/glitch/actions/settings';
|
||||||
|
@ -13,7 +14,7 @@ import { connectPublicStream, connectCommunityStream } from 'flavours/glitch/act
|
||||||
import { expandPublicTimeline, expandCommunityTimeline } from 'flavours/glitch/actions/timelines';
|
import { expandPublicTimeline, expandCommunityTimeline } from 'flavours/glitch/actions/timelines';
|
||||||
import { DismissableBanner } from 'flavours/glitch/components/dismissable_banner';
|
import { DismissableBanner } from 'flavours/glitch/components/dismissable_banner';
|
||||||
import SettingText from 'flavours/glitch/components/setting_text';
|
import SettingText from 'flavours/glitch/components/setting_text';
|
||||||
import initialState, { domain } from 'flavours/glitch/initial_state';
|
import { domain } from 'flavours/glitch/initial_state';
|
||||||
import { useAppDispatch, useAppSelector } from 'flavours/glitch/store';
|
import { useAppDispatch, useAppSelector } from 'flavours/glitch/store';
|
||||||
|
|
||||||
import Column from '../../components/column';
|
import Column from '../../components/column';
|
||||||
|
@ -26,15 +27,6 @@ const messages = defineMessages({
|
||||||
filter_regex: { id: 'home.column_settings.filter_regex', defaultMessage: 'Filter out by regular expressions' },
|
filter_regex: { id: 'home.column_settings.filter_regex', defaultMessage: 'Filter out by regular expressions' },
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: use a proper React context later on
|
|
||||||
const useIdentity = () => ({
|
|
||||||
signedIn: !!initialState.meta.me,
|
|
||||||
accountId: initialState.meta.me,
|
|
||||||
disabledAccountId: initialState.meta.disabled_account_id,
|
|
||||||
accessToken: initialState.meta.access_token,
|
|
||||||
permissions: initialState.role ? initialState.role.permissions : 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
const ColumnSettings = () => {
|
const ColumnSettings = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
|
@ -28,6 +28,7 @@ import { fetchLists } from 'flavours/glitch/actions/lists';
|
||||||
import { openModal } from 'flavours/glitch/actions/modal';
|
import { openModal } from 'flavours/glitch/actions/modal';
|
||||||
import Column from 'flavours/glitch/features/ui/components/column';
|
import Column from 'flavours/glitch/features/ui/components/column';
|
||||||
import LinkFooter from 'flavours/glitch/features/ui/components/link_footer';
|
import LinkFooter from 'flavours/glitch/features/ui/components/link_footer';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { preferencesLink } from 'flavours/glitch/utils/backend_links';
|
import { preferencesLink } from 'flavours/glitch/utils/backend_links';
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,12 +100,8 @@ const badgeDisplay = (number, limit) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
class GettingStarted extends ImmutablePureComponent {
|
class GettingStarted extends ImmutablePureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
myAccount: ImmutablePropTypes.record,
|
myAccount: ImmutablePropTypes.record,
|
||||||
columns: ImmutablePropTypes.list,
|
columns: ImmutablePropTypes.list,
|
||||||
|
@ -123,7 +120,7 @@ class GettingStarted extends ImmutablePureComponent {
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
const { fetchFollowRequests } = this.props;
|
const { fetchFollowRequests } = this.props;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
if (!signedIn) {
|
if (!signedIn) {
|
||||||
return;
|
return;
|
||||||
|
@ -134,7 +131,7 @@ class GettingStarted extends ImmutablePureComponent {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, myAccount, columns, multiColumn, unreadFollowRequests, unreadNotifications, lists, openSettings } = this.props;
|
const { intl, myAccount, columns, multiColumn, unreadFollowRequests, unreadNotifications, lists, openSettings } = this.props;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
const navItems = [];
|
const navItems = [];
|
||||||
let listItems = [];
|
let listItems = [];
|
||||||
|
@ -219,4 +216,4 @@ class GettingStarted extends ImmutablePureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(makeMapStateToProps, mapDispatchToProps)(injectIntl(GettingStarted));
|
export default withIdentity(connect(makeMapStateToProps, mapDispatchToProps)(injectIntl(GettingStarted)));
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { openModal } from 'flavours/glitch/actions/modal';
|
||||||
import Column from 'flavours/glitch/features/ui/components/column';
|
import Column from 'flavours/glitch/features/ui/components/column';
|
||||||
import ColumnLink from 'flavours/glitch/features/ui/components/column_link';
|
import ColumnLink from 'flavours/glitch/features/ui/components/column_link';
|
||||||
import ColumnSubheading from 'flavours/glitch/features/ui/components/column_subheading';
|
import ColumnSubheading from 'flavours/glitch/features/ui/components/column_subheading';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
heading: { id: 'column.heading', defaultMessage: 'Misc' },
|
heading: { id: 'column.heading', defaultMessage: 'Misc' },
|
||||||
|
@ -32,11 +32,8 @@ const messages = defineMessages({
|
||||||
|
|
||||||
class GettingStartedMisc extends ImmutablePureComponent {
|
class GettingStartedMisc extends ImmutablePureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
@ -49,7 +46,7 @@ class GettingStartedMisc extends ImmutablePureComponent {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl } = this.props;
|
const { intl } = this.props;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column icon='ellipsis-h' iconComponent={MoreHorizIcon} heading={intl.formatMessage(messages.heading)} alwaysShowBackButton>
|
<Column icon='ellipsis-h' iconComponent={MoreHorizIcon} heading={intl.formatMessage(messages.heading)} alwaysShowBackButton>
|
||||||
|
@ -69,4 +66,4 @@ class GettingStartedMisc extends ImmutablePureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect()(injectIntl(GettingStartedMisc));
|
export default connect()(withIdentity(injectIntl(GettingStartedMisc)));
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { fetchHashtag, followHashtag, unfollowHashtag } from 'flavours/glitch/ac
|
||||||
import { expandHashtagTimeline, clearTimeline } from 'flavours/glitch/actions/timelines';
|
import { expandHashtagTimeline, clearTimeline } from 'flavours/glitch/actions/timelines';
|
||||||
import Column from 'flavours/glitch/components/column';
|
import Column from 'flavours/glitch/components/column';
|
||||||
import ColumnHeader from 'flavours/glitch/components/column_header';
|
import ColumnHeader from 'flavours/glitch/components/column_header';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
|
|
||||||
import StatusListContainer from '../ui/containers/status_list_container';
|
import StatusListContainer from '../ui/containers/status_list_container';
|
||||||
|
|
||||||
|
@ -29,14 +30,10 @@ const mapStateToProps = (state, props) => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
class HashtagTimeline extends PureComponent {
|
class HashtagTimeline extends PureComponent {
|
||||||
|
|
||||||
disconnects = [];
|
disconnects = [];
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
params: PropTypes.object.isRequired,
|
params: PropTypes.object.isRequired,
|
||||||
columnId: PropTypes.string,
|
columnId: PropTypes.string,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
@ -94,7 +91,7 @@ class HashtagTimeline extends PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
_subscribe (dispatch, id, tags = {}, local) {
|
_subscribe (dispatch, id, tags = {}, local) {
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
if (!signedIn) {
|
if (!signedIn) {
|
||||||
return;
|
return;
|
||||||
|
@ -168,7 +165,7 @@ class HashtagTimeline extends PureComponent {
|
||||||
handleFollow = () => {
|
handleFollow = () => {
|
||||||
const { dispatch, params, tag } = this.props;
|
const { dispatch, params, tag } = this.props;
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
if (!signedIn) {
|
if (!signedIn) {
|
||||||
return;
|
return;
|
||||||
|
@ -185,7 +182,7 @@ class HashtagTimeline extends PureComponent {
|
||||||
const { hasUnread, columnId, multiColumn, tag } = this.props;
|
const { hasUnread, columnId, multiColumn, tag } = this.props;
|
||||||
const { id, local } = this.props.params;
|
const { id, local } = this.props.params;
|
||||||
const pinned = !!columnId;
|
const pinned = !!columnId;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column bindToDocument={!multiColumn} ref={this.setRef} label={`#${id}`}>
|
<Column bindToDocument={!multiColumn} ref={this.setRef} label={`#${id}`}>
|
||||||
|
@ -225,4 +222,4 @@ class HashtagTimeline extends PureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps)(HashtagTimeline);
|
export default connect(mapStateToProps)(withIdentity(HashtagTimeline));
|
||||||
|
|
|
@ -14,6 +14,7 @@ import { fetchAnnouncements, toggleShowAnnouncements } from 'flavours/glitch/act
|
||||||
import { IconWithBadge } from 'flavours/glitch/components/icon_with_badge';
|
import { IconWithBadge } from 'flavours/glitch/components/icon_with_badge';
|
||||||
import { NotSignedInIndicator } from 'flavours/glitch/components/not_signed_in_indicator';
|
import { NotSignedInIndicator } from 'flavours/glitch/components/not_signed_in_indicator';
|
||||||
import AnnouncementsContainer from 'flavours/glitch/features/getting_started/containers/announcements_container';
|
import AnnouncementsContainer from 'flavours/glitch/features/getting_started/containers/announcements_container';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { criticalUpdatesPending } from 'flavours/glitch/initial_state';
|
import { criticalUpdatesPending } from 'flavours/glitch/initial_state';
|
||||||
|
|
||||||
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
||||||
|
@ -41,12 +42,8 @@ const mapStateToProps = state => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
class HomeTimeline extends PureComponent {
|
class HomeTimeline extends PureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
hasUnread: PropTypes.bool,
|
hasUnread: PropTypes.bool,
|
||||||
|
@ -128,7 +125,7 @@ class HomeTimeline extends PureComponent {
|
||||||
render () {
|
render () {
|
||||||
const { intl, hasUnread, columnId, multiColumn, hasAnnouncements, unreadAnnouncements, showAnnouncements } = this.props;
|
const { intl, hasUnread, columnId, multiColumn, hasAnnouncements, unreadAnnouncements, showAnnouncements } = this.props;
|
||||||
const pinned = !!columnId;
|
const pinned = !!columnId;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
const banners = [];
|
const banners = [];
|
||||||
|
|
||||||
let announcementsButton;
|
let announcementsButton;
|
||||||
|
@ -192,4 +189,4 @@ class HomeTimeline extends PureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps)(injectIntl(HomeTimeline));
|
export default connect(mapStateToProps)(withIdentity(injectIntl(HomeTimeline)));
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
|
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_REPORTS } from 'flavours/glitch/permissions';
|
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_REPORTS } from 'flavours/glitch/permissions';
|
||||||
|
|
||||||
import { CheckboxWithLabel } from './checkbox_with_label';
|
import { CheckboxWithLabel } from './checkbox_with_label';
|
||||||
|
@ -13,13 +14,9 @@ import GrantPermissionButton from './grant_permission_button';
|
||||||
import PillBarButton from './pill_bar_button';
|
import PillBarButton from './pill_bar_button';
|
||||||
import SettingToggle from './setting_toggle';
|
import SettingToggle from './setting_toggle';
|
||||||
|
|
||||||
export default class ColumnSettings extends PureComponent {
|
class ColumnSettings extends PureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
settings: ImmutablePropTypes.map.isRequired,
|
settings: ImmutablePropTypes.map.isRequired,
|
||||||
pushSettings: ImmutablePropTypes.map.isRequired,
|
pushSettings: ImmutablePropTypes.map.isRequired,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
|
@ -216,7 +213,7 @@ export default class ColumnSettings extends PureComponent {
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{((this.context.identity.permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) && (
|
{((this.props.identity.permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) && (
|
||||||
<section role='group' aria-labelledby='notifications-admin-sign-up'>
|
<section role='group' aria-labelledby='notifications-admin-sign-up'>
|
||||||
<h3 id='notifications-status'><FormattedMessage id='notifications.column_settings.admin.sign_up' defaultMessage='New sign-ups:' /></h3>
|
<h3 id='notifications-status'><FormattedMessage id='notifications.column_settings.admin.sign_up' defaultMessage='New sign-ups:' /></h3>
|
||||||
|
|
||||||
|
@ -229,7 +226,7 @@ export default class ColumnSettings extends PureComponent {
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{((this.context.identity.permissions & PERMISSION_MANAGE_REPORTS) === PERMISSION_MANAGE_REPORTS) && (
|
{((this.props.identity.permissions & PERMISSION_MANAGE_REPORTS) === PERMISSION_MANAGE_REPORTS) && (
|
||||||
<section role='group' aria-labelledby='notifications-admin-report'>
|
<section role='group' aria-labelledby='notifications-admin-report'>
|
||||||
<h3 id='notifications-status'><FormattedMessage id='notifications.column_settings.admin.report' defaultMessage='New reports:' /></h3>
|
<h3 id='notifications-status'><FormattedMessage id='notifications.column_settings.admin.report' defaultMessage='New reports:' /></h3>
|
||||||
|
|
||||||
|
@ -246,3 +243,5 @@ export default class ColumnSettings extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default withIdentity(ColumnSettings);
|
||||||
|
|
|
@ -19,6 +19,7 @@ import NotificationsIcon from '@/material-icons/400-24px/notifications-fill.svg?
|
||||||
import { compareId } from 'flavours/glitch/compare_id';
|
import { compareId } from 'flavours/glitch/compare_id';
|
||||||
import { Icon } from 'flavours/glitch/components/icon';
|
import { Icon } from 'flavours/glitch/components/icon';
|
||||||
import { NotSignedInIndicator } from 'flavours/glitch/components/not_signed_in_indicator';
|
import { NotSignedInIndicator } from 'flavours/glitch/components/not_signed_in_indicator';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
|
|
||||||
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
||||||
import { submitMarkers } from '../../actions/markers';
|
import { submitMarkers } from '../../actions/markers';
|
||||||
|
@ -93,12 +94,8 @@ const mapDispatchToProps = dispatch => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
class Notifications extends PureComponent {
|
class Notifications extends PureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
columnId: PropTypes.string,
|
columnId: PropTypes.string,
|
||||||
notifications: ImmutablePropTypes.list.isRequired,
|
notifications: ImmutablePropTypes.list.isRequired,
|
||||||
showFilterBar: PropTypes.bool.isRequired,
|
showFilterBar: PropTypes.bool.isRequired,
|
||||||
|
@ -225,7 +222,7 @@ class Notifications extends PureComponent {
|
||||||
const { animatingNCD } = this.state;
|
const { animatingNCD } = this.state;
|
||||||
const pinned = !!columnId;
|
const pinned = !!columnId;
|
||||||
const emptyMessage = <FormattedMessage id='empty_column.notifications' defaultMessage="You don't have any notifications yet. When other people interact with you, you will see it here." />;
|
const emptyMessage = <FormattedMessage id='empty_column.notifications' defaultMessage="You don't have any notifications yet. When other people interact with you, you will see it here." />;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
let scrollableContent = null;
|
let scrollableContent = null;
|
||||||
|
|
||||||
|
@ -373,4 +370,4 @@ class Notifications extends PureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(Notifications));
|
export default connect(mapStateToProps, mapDispatchToProps)(withIdentity(injectIntl(Notifications)));
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { replyCompose } from 'flavours/glitch/actions/compose';
|
||||||
import { reblog, favourite, unreblog, unfavourite } from 'flavours/glitch/actions/interactions';
|
import { reblog, favourite, unreblog, unfavourite } from 'flavours/glitch/actions/interactions';
|
||||||
import { openModal } from 'flavours/glitch/actions/modal';
|
import { openModal } from 'flavours/glitch/actions/modal';
|
||||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { me, boostModal } from 'flavours/glitch/initial_state';
|
import { me, boostModal } from 'flavours/glitch/initial_state';
|
||||||
import { makeGetStatus } from 'flavours/glitch/selectors';
|
import { makeGetStatus } from 'flavours/glitch/selectors';
|
||||||
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
||||||
|
@ -48,12 +49,8 @@ const makeMapStateToProps = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
class Footer extends ImmutablePureComponent {
|
class Footer extends ImmutablePureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
statusId: PropTypes.string.isRequired,
|
statusId: PropTypes.string.isRequired,
|
||||||
status: ImmutablePropTypes.map.isRequired,
|
status: ImmutablePropTypes.map.isRequired,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
|
@ -77,7 +74,7 @@ class Footer extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleReplyClick = () => {
|
handleReplyClick = () => {
|
||||||
const { dispatch, askReplyConfirmation, status, intl } = this.props;
|
const { dispatch, askReplyConfirmation, status, intl } = this.props;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
if (signedIn) {
|
if (signedIn) {
|
||||||
if (askReplyConfirmation) {
|
if (askReplyConfirmation) {
|
||||||
|
@ -106,7 +103,7 @@ class Footer extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleFavouriteClick = () => {
|
handleFavouriteClick = () => {
|
||||||
const { dispatch, status } = this.props;
|
const { dispatch, status } = this.props;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
if (signedIn) {
|
if (signedIn) {
|
||||||
if (status.get('favourited')) {
|
if (status.get('favourited')) {
|
||||||
|
@ -133,7 +130,7 @@ class Footer extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleReblogClick = e => {
|
handleReblogClick = e => {
|
||||||
const { dispatch, status } = this.props;
|
const { dispatch, status } = this.props;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
if (signedIn) {
|
if (signedIn) {
|
||||||
if (status.get('reblogged')) {
|
if (status.get('reblogged')) {
|
||||||
|
@ -236,4 +233,4 @@ class Footer extends ImmutablePureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(makeMapStateToProps)(withRouter(injectIntl(Footer)));
|
export default connect(makeMapStateToProps)(withIdentity(withRouter(injectIntl(Footer))));
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { connect } from 'react-redux';
|
||||||
|
|
||||||
import PublicIcon from '@/material-icons/400-24px/public.svg?react';
|
import PublicIcon from '@/material-icons/400-24px/public.svg?react';
|
||||||
import { DismissableBanner } from 'flavours/glitch/components/dismissable_banner';
|
import { DismissableBanner } from 'flavours/glitch/components/dismissable_banner';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { domain } from 'flavours/glitch/initial_state';
|
import { domain } from 'flavours/glitch/initial_state';
|
||||||
|
|
||||||
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
||||||
|
@ -44,16 +45,12 @@ const mapStateToProps = (state, { columnId }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
class PublicTimeline extends PureComponent {
|
class PublicTimeline extends PureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
onlyMedia: false,
|
onlyMedia: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
columnId: PropTypes.string,
|
columnId: PropTypes.string,
|
||||||
|
@ -86,7 +83,7 @@ class PublicTimeline extends PureComponent {
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
const { dispatch, onlyMedia, onlyRemote, allowLocalOnly } = this.props;
|
const { dispatch, onlyMedia, onlyRemote, allowLocalOnly } = this.props;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
dispatch(expandPublicTimeline({ onlyMedia, onlyRemote, allowLocalOnly }));
|
dispatch(expandPublicTimeline({ onlyMedia, onlyRemote, allowLocalOnly }));
|
||||||
if (signedIn) {
|
if (signedIn) {
|
||||||
|
@ -95,7 +92,7 @@ class PublicTimeline extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate (prevProps) {
|
componentDidUpdate (prevProps) {
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
if (prevProps.onlyMedia !== this.props.onlyMedia || prevProps.onlyRemote !== this.props.onlyRemote || prevProps.allowLocalOnly !== this.props.allowLocalOnly) {
|
if (prevProps.onlyMedia !== this.props.onlyMedia || prevProps.onlyRemote !== this.props.onlyRemote || prevProps.allowLocalOnly !== this.props.allowLocalOnly) {
|
||||||
const { dispatch, onlyMedia, onlyRemote, allowLocalOnly } = this.props;
|
const { dispatch, onlyMedia, onlyRemote, allowLocalOnly } = this.props;
|
||||||
|
@ -170,4 +167,4 @@ class PublicTimeline extends PureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps)(injectIntl(PublicTimeline));
|
export default connect(mapStateToProps)(withIdentity(injectIntl(PublicTimeline)));
|
||||||
|
|
|
@ -20,6 +20,7 @@ import RepeatActiveIcon from '@/svg-icons/repeat_active.svg?react';
|
||||||
import RepeatDisabledIcon from '@/svg-icons/repeat_disabled.svg?react';
|
import RepeatDisabledIcon from '@/svg-icons/repeat_disabled.svg?react';
|
||||||
import RepeatPrivateIcon from '@/svg-icons/repeat_private.svg?react';
|
import RepeatPrivateIcon from '@/svg-icons/repeat_private.svg?react';
|
||||||
import RepeatPrivateActiveIcon from '@/svg-icons/repeat_private_active.svg?react';
|
import RepeatPrivateActiveIcon from '@/svg-icons/repeat_private_active.svg?react';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'flavours/glitch/permissions';
|
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'flavours/glitch/permissions';
|
||||||
import { accountAdminLink, statusAdminLink } from 'flavours/glitch/utils/backend_links';
|
import { accountAdminLink, statusAdminLink } from 'flavours/glitch/utils/backend_links';
|
||||||
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
||||||
|
@ -59,12 +60,8 @@ const messages = defineMessages({
|
||||||
});
|
});
|
||||||
|
|
||||||
class ActionBar extends PureComponent {
|
class ActionBar extends PureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
status: ImmutablePropTypes.map.isRequired,
|
status: ImmutablePropTypes.map.isRequired,
|
||||||
onReply: PropTypes.func.isRequired,
|
onReply: PropTypes.func.isRequired,
|
||||||
onReblog: PropTypes.func.isRequired,
|
onReblog: PropTypes.func.isRequired,
|
||||||
|
@ -157,7 +154,7 @@ class ActionBar extends PureComponent {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { status, intl } = this.props;
|
const { status, intl } = this.props;
|
||||||
const { signedIn, permissions } = this.context.identity;
|
const { signedIn, permissions } = this.props.identity;
|
||||||
|
|
||||||
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'));
|
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'));
|
||||||
const pinnableStatus = ['public', 'unlisted', 'private'].includes(status.get('visibility'));
|
const pinnableStatus = ['public', 'unlisted', 'private'].includes(status.get('visibility'));
|
||||||
|
@ -265,4 +262,4 @@ class ActionBar extends PureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withRouter(injectIntl(ActionBar));
|
export default withRouter(withIdentity(injectIntl(ActionBar)));
|
||||||
|
|
|
@ -21,6 +21,7 @@ import { Icon } from 'flavours/glitch/components/icon';
|
||||||
import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator';
|
import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator';
|
||||||
import ScrollContainer from 'flavours/glitch/containers/scroll_container';
|
import ScrollContainer from 'flavours/glitch/containers/scroll_container';
|
||||||
import BundleColumnError from 'flavours/glitch/features/ui/components/bundle_column_error';
|
import BundleColumnError from 'flavours/glitch/features/ui/components/bundle_column_error';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { autoUnfoldCW } from 'flavours/glitch/utils/content_warning';
|
import { autoUnfoldCW } from 'flavours/glitch/utils/content_warning';
|
||||||
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
||||||
|
|
||||||
|
@ -185,12 +186,8 @@ const titleFromStatus = (intl, status) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
class Status extends ImmutablePureComponent {
|
class Status extends ImmutablePureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
params: PropTypes.object.isRequired,
|
params: PropTypes.object.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
status: ImmutablePropTypes.map,
|
status: ImmutablePropTypes.map,
|
||||||
|
@ -277,7 +274,7 @@ class Status extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleFavouriteClick = (status, e) => {
|
handleFavouriteClick = (status, e) => {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
if (signedIn) {
|
if (signedIn) {
|
||||||
if (status.get('favourited')) {
|
if (status.get('favourited')) {
|
||||||
|
@ -317,7 +314,7 @@ class Status extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleReplyClick = (status) => {
|
handleReplyClick = (status) => {
|
||||||
const { askReplyConfirmation, dispatch, intl } = this.props;
|
const { askReplyConfirmation, dispatch, intl } = this.props;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
if (signedIn) {
|
if (signedIn) {
|
||||||
if (askReplyConfirmation) {
|
if (askReplyConfirmation) {
|
||||||
|
@ -357,7 +354,7 @@ class Status extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleReblogClick = (status, e) => {
|
handleReblogClick = (status, e) => {
|
||||||
const { settings, dispatch } = this.props;
|
const { settings, dispatch } = this.props;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
if (signedIn) {
|
if (signedIn) {
|
||||||
if (settings.get('confirm_boost_missing_media_description') && status.get('media_attachments').some(item => !item.get('description')) && !status.get('reblogged')) {
|
if (settings.get('confirm_boost_missing_media_description') && status.get('media_attachments').some(item => !item.get('description')) && !status.get('reblogged')) {
|
||||||
|
@ -792,4 +789,4 @@ class Status extends ImmutablePureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withRouter(injectIntl(connect(makeMapStateToProps)(Status)));
|
export default withRouter(injectIntl(connect(makeMapStateToProps)(withIdentity(Status))));
|
||||||
|
|
|
@ -7,16 +7,13 @@ import { mountCompose, unmountCompose } from 'flavours/glitch/actions/compose';
|
||||||
import ServerBanner from 'flavours/glitch/components/server_banner';
|
import ServerBanner from 'flavours/glitch/components/server_banner';
|
||||||
import ComposeFormContainer from 'flavours/glitch/features/compose/containers/compose_form_container';
|
import ComposeFormContainer from 'flavours/glitch/features/compose/containers/compose_form_container';
|
||||||
import SearchContainer from 'flavours/glitch/features/compose/containers/search_container';
|
import SearchContainer from 'flavours/glitch/features/compose/containers/search_container';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
|
|
||||||
import LinkFooter from './link_footer';
|
import LinkFooter from './link_footer';
|
||||||
|
|
||||||
class ComposePanel extends PureComponent {
|
class ComposePanel extends PureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,7 +28,7 @@ class ComposePanel extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='compose-panel'>
|
<div className='compose-panel'>
|
||||||
|
@ -55,4 +52,4 @@ class ComposePanel extends PureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect()(ComposePanel);
|
export default connect()(withIdentity(ComposePanel));
|
||||||
|
|
|
@ -14,6 +14,7 @@ import { Avatar } from 'flavours/glitch/components/avatar';
|
||||||
import { Icon } from 'flavours/glitch/components/icon';
|
import { Icon } from 'flavours/glitch/components/icon';
|
||||||
import { WordmarkLogo, SymbolLogo } from 'flavours/glitch/components/logo';
|
import { WordmarkLogo, SymbolLogo } from 'flavours/glitch/components/logo';
|
||||||
import { Permalink } from 'flavours/glitch/components/permalink';
|
import { Permalink } from 'flavours/glitch/components/permalink';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { registrationsOpen, me, sso_redirect } from 'flavours/glitch/initial_state';
|
import { registrationsOpen, me, sso_redirect } from 'flavours/glitch/initial_state';
|
||||||
|
|
||||||
const Account = connect(state => ({
|
const Account = connect(state => ({
|
||||||
|
@ -42,12 +43,8 @@ const mapDispatchToProps = (dispatch) => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
class Header extends PureComponent {
|
class Header extends PureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
openClosedRegistrationsModal: PropTypes.func,
|
openClosedRegistrationsModal: PropTypes.func,
|
||||||
location: PropTypes.object,
|
location: PropTypes.object,
|
||||||
signupUrl: PropTypes.string.isRequired,
|
signupUrl: PropTypes.string.isRequired,
|
||||||
|
@ -61,7 +58,7 @@ class Header extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
const { location, openClosedRegistrationsModal, signupUrl, intl } = this.props;
|
const { location, openClosedRegistrationsModal, signupUrl, intl } = this.props;
|
||||||
|
|
||||||
let content;
|
let content;
|
||||||
|
@ -122,4 +119,4 @@ class Header extends PureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default injectIntl(withRouter(connect(mapStateToProps, mapDispatchToProps)(Header)));
|
export default injectIntl(withRouter(withIdentity(connect(mapStateToProps, mapDispatchToProps)(Header))));
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { Link } from 'react-router-dom';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { openModal } from 'flavours/glitch/actions/modal';
|
import { openModal } from 'flavours/glitch/actions/modal';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { domain, version, source_url, statusPageUrl, profile_directory as profileDirectory } from 'flavours/glitch/initial_state';
|
import { domain, version, source_url, statusPageUrl, profile_directory as profileDirectory } from 'flavours/glitch/initial_state';
|
||||||
import { PERMISSION_INVITE_USERS } from 'flavours/glitch/permissions';
|
import { PERMISSION_INVITE_USERS } from 'flavours/glitch/permissions';
|
||||||
import { logOut } from 'flavours/glitch/utils/log_out';
|
import { logOut } from 'flavours/glitch/utils/log_out';
|
||||||
|
@ -32,12 +33,8 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
class LinkFooter extends PureComponent {
|
class LinkFooter extends PureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
multiColumn: PropTypes.bool,
|
multiColumn: PropTypes.bool,
|
||||||
onLogout: PropTypes.func.isRequired,
|
onLogout: PropTypes.func.isRequired,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
|
@ -53,7 +50,7 @@ class LinkFooter extends PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { signedIn, permissions } = this.context.identity;
|
const { signedIn, permissions } = this.props.identity;
|
||||||
const { multiColumn } = this.props;
|
const { multiColumn } = this.props;
|
||||||
|
|
||||||
const canInvite = signedIn && ((permissions & PERMISSION_INVITE_USERS) === PERMISSION_INVITE_USERS);
|
const canInvite = signedIn && ((permissions & PERMISSION_INVITE_USERS) === PERMISSION_INVITE_USERS);
|
||||||
|
@ -108,4 +105,4 @@ class LinkFooter extends PureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default injectIntl(connect(null, mapDispatchToProps)(LinkFooter));
|
export default injectIntl(withIdentity(connect(null, mapDispatchToProps)(LinkFooter)));
|
||||||
|
|
|
@ -30,6 +30,7 @@ import StarIcon from '@/material-icons/400-24px/star.svg?react';
|
||||||
import { fetchFollowRequests } from 'flavours/glitch/actions/accounts';
|
import { fetchFollowRequests } from 'flavours/glitch/actions/accounts';
|
||||||
import { IconWithBadge } from 'flavours/glitch/components/icon_with_badge';
|
import { IconWithBadge } from 'flavours/glitch/components/icon_with_badge';
|
||||||
import { NavigationPortal } from 'flavours/glitch/components/navigation_portal';
|
import { NavigationPortal } from 'flavours/glitch/components/navigation_portal';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { timelinePreview, trendsEnabled } from 'flavours/glitch/initial_state';
|
import { timelinePreview, trendsEnabled } from 'flavours/glitch/initial_state';
|
||||||
import { transientSingleColumn } from 'flavours/glitch/is_mobile';
|
import { transientSingleColumn } from 'flavours/glitch/is_mobile';
|
||||||
import { preferencesLink } from 'flavours/glitch/utils/backend_links';
|
import { preferencesLink } from 'flavours/glitch/utils/backend_links';
|
||||||
|
@ -98,12 +99,8 @@ const FollowRequestsLink = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
class NavigationPanel extends Component {
|
class NavigationPanel extends Component {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
onOpenSettings: PropTypes.func,
|
onOpenSettings: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
@ -114,7 +111,7 @@ class NavigationPanel extends Component {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, onOpenSettings } = this.props;
|
const { intl, onOpenSettings } = this.props;
|
||||||
const { signedIn, disabledAccountId } = this.context.identity;
|
const { signedIn, disabledAccountId } = this.props.identity;
|
||||||
|
|
||||||
let banner = undefined;
|
let banner = undefined;
|
||||||
|
|
||||||
|
@ -188,4 +185,4 @@ class NavigationPanel extends Component {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default injectIntl(NavigationPanel);
|
export default injectIntl(withIdentity(NavigationPanel));
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { synchronouslySubmitMarkers, submitMarkers, fetchMarkers } from 'flavour
|
||||||
import { INTRODUCTION_VERSION } from 'flavours/glitch/actions/onboarding';
|
import { INTRODUCTION_VERSION } from 'flavours/glitch/actions/onboarding';
|
||||||
import { Permalink } from 'flavours/glitch/components/permalink';
|
import { Permalink } from 'flavours/glitch/components/permalink';
|
||||||
import { PictureInPicture } from 'flavours/glitch/features/picture_in_picture';
|
import { PictureInPicture } from 'flavours/glitch/features/picture_in_picture';
|
||||||
|
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||||
import { layoutFromWindow } from 'flavours/glitch/is_mobile';
|
import { layoutFromWindow } from 'flavours/glitch/is_mobile';
|
||||||
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
||||||
|
|
||||||
|
@ -129,12 +130,8 @@ const keyMap = {
|
||||||
};
|
};
|
||||||
|
|
||||||
class SwitchingColumnsArea extends PureComponent {
|
class SwitchingColumnsArea extends PureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
location: PropTypes.object,
|
location: PropTypes.object,
|
||||||
singleColumn: PropTypes.bool,
|
singleColumn: PropTypes.bool,
|
||||||
|
@ -169,7 +166,7 @@ class SwitchingColumnsArea extends PureComponent {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { children, singleColumn } = this.props;
|
const { children, singleColumn } = this.props;
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
const pathName = this.props.location.pathname;
|
const pathName = this.props.location.pathname;
|
||||||
|
|
||||||
let redirect;
|
let redirect;
|
||||||
|
@ -262,12 +259,8 @@ class SwitchingColumnsArea extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
class UI extends PureComponent {
|
class UI extends PureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
identity: PropTypes.object.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
identity: identityContextPropShape,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
isWide: PropTypes.bool,
|
isWide: PropTypes.bool,
|
||||||
|
@ -323,7 +316,7 @@ class UI extends PureComponent {
|
||||||
this.dragTargets.push(e.target);
|
this.dragTargets.push(e.target);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.dataTransfer && Array.from(e.dataTransfer.types).includes('Files') && this.props.canUploadMore && this.context.identity.signedIn) {
|
if (e.dataTransfer && Array.from(e.dataTransfer.types).includes('Files') && this.props.canUploadMore && this.props.identity.signedIn) {
|
||||||
this.setState({ draggingOver: true });
|
this.setState({ draggingOver: true });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -351,7 +344,7 @@ class UI extends PureComponent {
|
||||||
this.setState({ draggingOver: false });
|
this.setState({ draggingOver: false });
|
||||||
this.dragTargets = [];
|
this.dragTargets = [];
|
||||||
|
|
||||||
if (e.dataTransfer && e.dataTransfer.files.length >= 1 && this.props.canUploadMore && this.context.identity.signedIn) {
|
if (e.dataTransfer && e.dataTransfer.files.length >= 1 && this.props.canUploadMore && this.props.identity.signedIn) {
|
||||||
this.props.dispatch(uploadCompose(e.dataTransfer.files));
|
this.props.dispatch(uploadCompose(e.dataTransfer.files));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -403,7 +396,7 @@ class UI extends PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.props.identity;
|
||||||
|
|
||||||
window.addEventListener('beforeunload', this.handleBeforeUnload, false);
|
window.addEventListener('beforeunload', this.handleBeforeUnload, false);
|
||||||
window.addEventListener('resize', this.handleResize, { passive: true });
|
window.addEventListener('resize', this.handleResize, { passive: true });
|
||||||
|
@ -649,7 +642,7 @@ class UI extends PureComponent {
|
||||||
|
|
||||||
<Header />
|
<Header />
|
||||||
|
|
||||||
<SwitchingColumnsArea location={location} singleColumn={layout === 'mobile' || layout === 'single-column'}>
|
<SwitchingColumnsArea identity={this.props.identity} location={location} singleColumn={layout === 'mobile' || layout === 'single-column'}>
|
||||||
{children}
|
{children}
|
||||||
</SwitchingColumnsArea>
|
</SwitchingColumnsArea>
|
||||||
|
|
||||||
|
@ -665,4 +658,4 @@ class UI extends PureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps)(injectIntl(withRouter(UI)));
|
export default connect(mapStateToProps)(injectIntl(withRouter(withIdentity(UI))));
|
||||||
|
|
74
app/javascript/flavours/glitch/identity_context.tsx
Normal file
74
app/javascript/flavours/glitch/identity_context.tsx
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { createContext, useContext } from 'react';
|
||||||
|
|
||||||
|
import hoistStatics from 'hoist-non-react-statics';
|
||||||
|
|
||||||
|
import type { InitialState } from 'flavours/glitch/initial_state';
|
||||||
|
|
||||||
|
export interface IdentityContextType {
|
||||||
|
signedIn: boolean;
|
||||||
|
accountId: string | undefined;
|
||||||
|
disabledAccountId: string | undefined;
|
||||||
|
accessToken: string | undefined;
|
||||||
|
permissions: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const identityContextPropShape = PropTypes.shape({
|
||||||
|
signedIn: PropTypes.bool.isRequired,
|
||||||
|
accountId: PropTypes.string,
|
||||||
|
disabledAccountId: PropTypes.string,
|
||||||
|
accessToken: PropTypes.string,
|
||||||
|
}).isRequired;
|
||||||
|
|
||||||
|
export const createIdentityContext = (state: InitialState) => ({
|
||||||
|
signedIn: !!state.meta.me,
|
||||||
|
accountId: state.meta.me,
|
||||||
|
disabledAccountId: state.meta.disabled_account_id,
|
||||||
|
accessToken: state.meta.access_token,
|
||||||
|
permissions: state.role?.permissions ?? 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const IdentityContext = createContext<IdentityContextType>({
|
||||||
|
signedIn: false,
|
||||||
|
permissions: 0,
|
||||||
|
accountId: undefined,
|
||||||
|
disabledAccountId: undefined,
|
||||||
|
accessToken: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const useIdentity = () => useContext(IdentityContext);
|
||||||
|
|
||||||
|
export interface IdentityProps {
|
||||||
|
ref?: unknown;
|
||||||
|
wrappedComponentRef?: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Injects an `identity` props into the wrapped component to be able to use the new context in class components */
|
||||||
|
export function withIdentity<
|
||||||
|
ComponentType extends React.ComponentType<IdentityProps>,
|
||||||
|
>(Component: ComponentType) {
|
||||||
|
const displayName = `withIdentity(${Component.displayName ?? Component.name})`;
|
||||||
|
const C = (props: React.ComponentProps<ComponentType>) => {
|
||||||
|
const { wrappedComponentRef, ...remainingProps } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IdentityContext.Consumer>
|
||||||
|
{(context) => {
|
||||||
|
return (
|
||||||
|
// @ts-expect-error - Dynamic covariant generic components are tough to type.
|
||||||
|
<Component
|
||||||
|
{...remainingProps}
|
||||||
|
identity={context}
|
||||||
|
ref={wrappedComponentRef}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</IdentityContext.Consumer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
C.displayName = displayName;
|
||||||
|
C.WrappedComponent = Component;
|
||||||
|
|
||||||
|
return hoistStatics(C, Component);
|
||||||
|
}
|
|
@ -50,12 +50,22 @@
|
||||||
* @property {string} default_content_type
|
* @property {string} default_content_type
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef Role
|
||||||
|
* @property {string} id
|
||||||
|
* @property {string} name
|
||||||
|
* @property {string} permissions
|
||||||
|
* @property {string} color
|
||||||
|
* @property {boolean} highlighted
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef InitialState
|
* @typedef InitialState
|
||||||
* @property {Record<string, import("./api_types/accounts").ApiAccountJSON>} accounts
|
* @property {Record<string, import("./api_types/accounts").ApiAccountJSON>} accounts
|
||||||
* @property {InitialStateLanguage[]} languages
|
* @property {InitialStateLanguage[]} languages
|
||||||
* @property {boolean=} critical_updates_pending
|
* @property {boolean=} critical_updates_pending
|
||||||
* @property {InitialStateMeta} meta
|
* @property {InitialStateMeta} meta
|
||||||
|
* @property {Role?} role
|
||||||
* @property {object} local_settings
|
* @property {object} local_settings
|
||||||
* @property {number} max_feed_hashtags
|
* @property {number} max_feed_hashtags
|
||||||
* @property {number} poll_limits
|
* @property {number} poll_limits
|
||||||
|
|
Loading…
Reference in a new issue