Merge branch 'developers' into 'develop'
Developers See merge request soapbox-pub/soapbox-fe!487
This commit is contained in:
commit
7c2aacb71e
9 changed files with 72 additions and 4 deletions
|
@ -38,6 +38,8 @@ export const defaultSettings = ImmutableMap({
|
||||||
dyslexicFont: false,
|
dyslexicFont: false,
|
||||||
demetricator: false,
|
demetricator: false,
|
||||||
|
|
||||||
|
isDeveloper: false,
|
||||||
|
|
||||||
chats: ImmutableMap({
|
chats: ImmutableMap({
|
||||||
panes: ImmutableList(),
|
panes: ImmutableList(),
|
||||||
mainWindow: 'minimized',
|
mainWindow: 'minimized',
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { NavLink, withRouter } from 'react-router-dom';
|
||||||
import Icon from 'soapbox/components/icon';
|
import Icon from 'soapbox/components/icon';
|
||||||
import IconWithCounter from 'soapbox/components/icon_with_counter';
|
import IconWithCounter from 'soapbox/components/icon_with_counter';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import { getSettings } from 'soapbox/actions/settings';
|
||||||
import { getFeatures } from 'soapbox/utils/features';
|
import { getFeatures } from 'soapbox/utils/features';
|
||||||
import { getSoapboxConfig } from 'soapbox/actions/soapbox';
|
import { getSoapboxConfig } from 'soapbox/actions/soapbox';
|
||||||
import { isStaff, getBaseURL } from 'soapbox/utils/accounts';
|
import { isStaff, getBaseURL } from 'soapbox/utils/accounts';
|
||||||
|
@ -27,6 +28,7 @@ const mapStateToProps = state => {
|
||||||
chatsCount: state.get('chats').reduce((acc, curr) => acc + Math.min(curr.get('unread', 0), 1), 0),
|
chatsCount: state.get('chats').reduce((acc, curr) => acc + Math.min(curr.get('unread', 0), 1), 0),
|
||||||
dashboardCount: reportsCount + approvalCount,
|
dashboardCount: reportsCount + approvalCount,
|
||||||
baseURL: getBaseURL(account),
|
baseURL: getBaseURL(account),
|
||||||
|
settings: getSettings(state),
|
||||||
features: getFeatures(instance),
|
features: getFeatures(instance),
|
||||||
instance,
|
instance,
|
||||||
};
|
};
|
||||||
|
@ -47,13 +49,14 @@ class PrimaryNavigation extends React.PureComponent {
|
||||||
notificationCount: PropTypes.number,
|
notificationCount: PropTypes.number,
|
||||||
chatsCount: PropTypes.number,
|
chatsCount: PropTypes.number,
|
||||||
baseURL: PropTypes.string,
|
baseURL: PropTypes.string,
|
||||||
|
settings: PropTypes.object.isRequired,
|
||||||
features: PropTypes.object.isRequired,
|
features: PropTypes.object.isRequired,
|
||||||
location: PropTypes.object,
|
location: PropTypes.object,
|
||||||
instance: ImmutablePropTypes.map.isRequired,
|
instance: ImmutablePropTypes.map.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { account, features, notificationCount, chatsCount, dashboardCount, location, instance, baseURL } = this.props;
|
const { account, settings, features, notificationCount, chatsCount, dashboardCount, location, instance, baseURL } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='column-header__wrapper primary-navigation__wrapper'>
|
<div className='column-header__wrapper primary-navigation__wrapper'>
|
||||||
|
@ -127,6 +130,16 @@ class PrimaryNavigation extends React.PureComponent {
|
||||||
</a>
|
</a>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{(settings.get('isDeveloper')) && (
|
||||||
|
<NavLink key='developers' className='btn grouped' to='/developers'>
|
||||||
|
<Icon
|
||||||
|
src={require('@tabler/icons/icons/code.svg')}
|
||||||
|
className={classNames('primary-navigation__icon', { 'svg-icon--active': location.pathname.startsWith('/developers') })}
|
||||||
|
/>
|
||||||
|
<FormattedMessage id='navigation.developers' defaultMessage='Developers' />
|
||||||
|
</NavLink>
|
||||||
|
)}
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
{features.federating ? (
|
{features.federating ? (
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { logOut, switchAccount } from 'soapbox/actions/auth';
|
||||||
import ThemeToggle from '../features/ui/components/theme_toggle_container';
|
import ThemeToggle from '../features/ui/components/theme_toggle_container';
|
||||||
import { fetchOwnAccounts } from 'soapbox/actions/auth';
|
import { fetchOwnAccounts } from 'soapbox/actions/auth';
|
||||||
import { is as ImmutableIs } from 'immutable';
|
import { is as ImmutableIs } from 'immutable';
|
||||||
|
import { getSettings } from 'soapbox/actions/settings';
|
||||||
import { getSoapboxConfig } from 'soapbox/actions/soapbox';
|
import { getSoapboxConfig } from 'soapbox/actions/soapbox';
|
||||||
import { getFeatures } from 'soapbox/utils/features';
|
import { getFeatures } from 'soapbox/utils/features';
|
||||||
|
|
||||||
|
@ -45,6 +46,7 @@ const messages = defineMessages({
|
||||||
donate: { id: 'donate', defaultMessage: 'Donate' },
|
donate: { id: 'donate', defaultMessage: 'Donate' },
|
||||||
donate_crypto: { id: 'donate_crypto', defaultMessage: 'Donate cryptocurrency' },
|
donate_crypto: { id: 'donate_crypto', defaultMessage: 'Donate cryptocurrency' },
|
||||||
info: { id: 'column.info', defaultMessage: 'Server information' },
|
info: { id: 'column.info', defaultMessage: 'Server information' },
|
||||||
|
developers: { id: 'navigation.developers', defaultMessage: 'Developers' },
|
||||||
add_account: { id: 'profile_dropdown.add_account', defaultMessage: 'Add an existing account' },
|
add_account: { id: 'profile_dropdown.add_account', defaultMessage: 'Add an existing account' },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -67,6 +69,7 @@ const makeMapStateToProps = () => {
|
||||||
hasCrypto: typeof soapbox.getIn(['cryptoAddresses', 0, 'ticker']) === 'string',
|
hasCrypto: typeof soapbox.getIn(['cryptoAddresses', 0, 'ticker']) === 'string',
|
||||||
otherAccounts: getOtherAccounts(state),
|
otherAccounts: getOtherAccounts(state),
|
||||||
features,
|
features,
|
||||||
|
settings: getSettings(state),
|
||||||
siteTitle: instance.get('title'),
|
siteTitle: instance.get('title'),
|
||||||
baseURL: getBaseURL(account),
|
baseURL: getBaseURL(account),
|
||||||
};
|
};
|
||||||
|
@ -101,6 +104,7 @@ class SidebarMenu extends ImmutablePureComponent {
|
||||||
otherAccounts: ImmutablePropTypes.list,
|
otherAccounts: ImmutablePropTypes.list,
|
||||||
sidebarOpen: PropTypes.bool,
|
sidebarOpen: PropTypes.bool,
|
||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
|
settings: PropTypes.object.isRequired,
|
||||||
features: PropTypes.object.isRequired,
|
features: PropTypes.object.isRequired,
|
||||||
baseURL: PropTypes.string,
|
baseURL: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
@ -159,7 +163,7 @@ class SidebarMenu extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { sidebarOpen, intl, account, onClickLogOut, donateUrl, otherAccounts, hasCrypto, features, siteTitle, baseURL } = this.props;
|
const { sidebarOpen, intl, account, onClickLogOut, donateUrl, otherAccounts, hasCrypto, settings, features, siteTitle, baseURL } = this.props;
|
||||||
const { switcher } = this.state;
|
const { switcher } = this.state;
|
||||||
if (!account) return null;
|
if (!account) return null;
|
||||||
const acct = account.get('acct');
|
const acct = account.get('acct');
|
||||||
|
@ -319,6 +323,13 @@ class SidebarMenu extends ImmutablePureComponent {
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{(settings.get('isDeveloper')) && (
|
||||||
|
<Link className='sidebar-menu-item' to='/developers' onClick={this.handleClose}>
|
||||||
|
<Icon src={require('@tabler/icons/icons/code.svg')} />
|
||||||
|
<span className='sidebar-menu-item__title'>{intl.formatMessage(messages.developers)}</span>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className='sidebar-menu__section'>
|
<div className='sidebar-menu__section'>
|
||||||
<Link className='sidebar-menu-item' to='/auth/sign_out' onClick={onClickLogOut}>
|
<Link className='sidebar-menu-item' to='/auth/sign_out' onClick={onClickLogOut}>
|
||||||
<Icon src={require('@tabler/icons/icons/logout.svg')} />
|
<Icon src={require('@tabler/icons/icons/logout.svg')} />
|
||||||
|
|
29
app/soapbox/features/developers/index.js
Normal file
29
app/soapbox/features/developers/index.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { injectIntl, defineMessages } from 'react-intl';
|
||||||
|
import Column from '../ui/components/column';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
heading: { id: 'column.developers', defaultMessage: 'Developers' },
|
||||||
|
});
|
||||||
|
|
||||||
|
export default @injectIntl
|
||||||
|
class Developers extends React.Component {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
intl: PropTypes.object.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { intl } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Column heading={intl.formatMessage(messages.heading)}>
|
||||||
|
<div style={{ padding: '20px 10px', textAlign: 'center' }}>
|
||||||
|
WIP: Developers page
|
||||||
|
</div>
|
||||||
|
</Column>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -262,6 +262,10 @@ class Preferences extends ImmutablePureComponent {
|
||||||
hint={<FormattedMessage id='preferences.hints.demetricator' defaultMessage='Decrease social media anxiety by hiding all numbers from the site.' />}
|
hint={<FormattedMessage id='preferences.hints.demetricator' defaultMessage='Decrease social media anxiety by hiding all numbers from the site.' />}
|
||||||
path={['demetricator']}
|
path={['demetricator']}
|
||||||
/>
|
/>
|
||||||
|
<SettingsCheckbox
|
||||||
|
label={<FormattedMessage id='preferences.fields.developer_label' defaultMessage='Developer tools' />}
|
||||||
|
path={['isDeveloper']}
|
||||||
|
/>
|
||||||
</FieldsGroup>
|
</FieldsGroup>
|
||||||
</SimpleForm>
|
</SimpleForm>
|
||||||
</Column>
|
</Column>
|
||||||
|
|
|
@ -115,6 +115,7 @@ import {
|
||||||
Share,
|
Share,
|
||||||
NewStatus,
|
NewStatus,
|
||||||
IntentionalError,
|
IntentionalError,
|
||||||
|
Developers,
|
||||||
} from './util/async-components';
|
} from './util/async-components';
|
||||||
|
|
||||||
// Dummy import, to make sure that <Status /> ends up in the application bundle.
|
// Dummy import, to make sure that <Status /> ends up in the application bundle.
|
||||||
|
@ -318,7 +319,9 @@ class SwitchingColumnsArea extends React.PureComponent {
|
||||||
<WrappedRoute path='/admin/log' page={AdminPage} component={ModerationLog} content={children} exact />
|
<WrappedRoute path='/admin/log' page={AdminPage} component={ModerationLog} content={children} exact />
|
||||||
<WrappedRoute path='/admin/users' page={AdminPage} component={UserIndex} content={children} exact />
|
<WrappedRoute path='/admin/users' page={AdminPage} component={UserIndex} content={children} exact />
|
||||||
<WrappedRoute path='/info' page={EmptyPage} component={ServerInfo} content={children} />
|
<WrappedRoute path='/info' page={EmptyPage} component={ServerInfo} content={children} />
|
||||||
|
|
||||||
<WrappedRoute path='/error' page={EmptyPage} component={IntentionalError} content={children} />
|
<WrappedRoute path='/error' page={EmptyPage} component={IntentionalError} content={children} />
|
||||||
|
<WrappedRoute path='/developers' page={DefaultPage} component={Developers} content={children} />
|
||||||
|
|
||||||
<WrappedRoute path='/donate/crypto' publicRoute page={DefaultPage} component={CryptoDonate} content={children} />
|
<WrappedRoute path='/donate/crypto' publicRoute page={DefaultPage} component={CryptoDonate} content={children} />
|
||||||
<WrappedRoute path='/federation_restrictions' publicRoute page={DefaultPage} component={FederationRestrictions} content={children} />
|
<WrappedRoute path='/federation_restrictions' publicRoute page={DefaultPage} component={FederationRestrictions} content={children} />
|
||||||
|
|
|
@ -425,3 +425,7 @@ export function NewStatus() {
|
||||||
export function IntentionalError() {
|
export function IntentionalError() {
|
||||||
return import(/* webpackChunkName: "error" */'../../intentional_error');
|
return import(/* webpackChunkName: "error" */'../../intentional_error');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function Developers() {
|
||||||
|
return import(/* webpackChunkName: "features/developers" */'../../developers');
|
||||||
|
}
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
fill: currentColor;
|
fill: currentColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
svg.icon-tabler-search {
|
svg.icon-tabler-search,
|
||||||
|
svg.icon-tabler-code {
|
||||||
stroke-width: 2.3px;
|
stroke-width: 2.3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&--active {
|
&--active {
|
||||||
svg.icon-tabler-search {
|
svg.icon-tabler-search,
|
||||||
|
svg.icon-tabler-code {
|
||||||
stroke-width: 2.5px;
|
stroke-width: 2.5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue