mirror of
https://github.com/wassname/talk.git
synced 2026-07-04 17:06:37 +08:00
Merge branch 'master' into scraper
This commit is contained in:
@@ -6,6 +6,7 @@ npm-debug.log*
|
||||
dump.rdb
|
||||
|
||||
client/coral-framework/graphql/introspection.json
|
||||
docs/source/_data/introspection.json
|
||||
|
||||
.env
|
||||
*.cfg
|
||||
|
||||
@@ -35,12 +35,9 @@ class ExtendableTabPanelContainer extends React.Component {
|
||||
|
||||
createPluginTabFactory = (props = this.props) => el => {
|
||||
return (
|
||||
<ExtendableTab
|
||||
tabId={el.type.talkPluginName}
|
||||
key={el.type.talkPluginName}
|
||||
>
|
||||
<ExtendableTab tabId={el.key} key={el.key}>
|
||||
{React.cloneElement(el, {
|
||||
active: props.activeTab === el.type.talkPluginName,
|
||||
active: props.activeTab === el.key,
|
||||
})}
|
||||
</ExtendableTab>
|
||||
);
|
||||
@@ -59,7 +56,7 @@ class ExtendableTabPanelContainer extends React.Component {
|
||||
|
||||
createPluginTabPane(el) {
|
||||
return (
|
||||
<TabPane tabId={el.type.talkPluginName} key={el.type.talkPluginName}>
|
||||
<TabPane tabId={el.key} key={el.key}>
|
||||
{el}
|
||||
</TabPane>
|
||||
);
|
||||
|
||||
@@ -136,6 +136,7 @@ export function t(key, ...replacements) {
|
||||
replacements.forEach((str, i) => {
|
||||
translation = translation.replace(new RegExp(`\\{${i}\\}`, 'g'), str);
|
||||
});
|
||||
|
||||
return translation;
|
||||
} else {
|
||||
console.warn(`${lang}.${key} and en.${key} language key not set`);
|
||||
|
||||
@@ -173,11 +173,30 @@ class PluginsService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This adds a consistent keying for the slot elements.
|
||||
* It uses the plugin name as the key. If the same plugin inserts
|
||||
* multiple elements it will append `.${noOfOccurence}` to the
|
||||
* key starting with the second element.
|
||||
*/
|
||||
const getKey = (() => {
|
||||
const map = {};
|
||||
return component => {
|
||||
if (map[component.talkPluginName] === undefined) {
|
||||
map[component.talkPluginName] = 0;
|
||||
} else {
|
||||
map[component.talkPluginName]++;
|
||||
}
|
||||
const i = map[component.talkPluginName];
|
||||
return `${component.talkPluginName}${i > 0 ? `.${i}` : ''}`;
|
||||
};
|
||||
})();
|
||||
|
||||
return (size > 0 ? slots.slice(0, size) : slots)
|
||||
.map((component, i) => ({
|
||||
.map(component => ({
|
||||
component,
|
||||
disabled: isDisabled(component),
|
||||
key: i,
|
||||
key: getKey(component),
|
||||
}))
|
||||
.filter(o => !o.disabled)
|
||||
.map(({ component, key }) =>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Slot } from 'plugin-api/beta/client/components';
|
||||
import {
|
||||
Button,
|
||||
TextField,
|
||||
@@ -28,6 +29,15 @@ class SignUp extends React.Component {
|
||||
this.props.onSubmit();
|
||||
};
|
||||
|
||||
childFactory = el => {
|
||||
const key = el.key;
|
||||
const props = {
|
||||
indicateBlocker: () => this.props.indicateBlocker(key),
|
||||
indicateBlockerResolved: () => this.props.indicateBlockerResolved(key),
|
||||
};
|
||||
return React.cloneElement(el, props);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
username,
|
||||
@@ -42,6 +52,7 @@ class SignUp extends React.Component {
|
||||
errorMessage,
|
||||
requireEmailConfirmation,
|
||||
success,
|
||||
blocked,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
@@ -103,6 +114,10 @@ class SignUp extends React.Component {
|
||||
onChange={this.handlePasswordRepeatChange}
|
||||
minLength="8"
|
||||
/>
|
||||
<Slot
|
||||
fill="talkPluginAuth.formField"
|
||||
childFactory={this.childFactory}
|
||||
/>
|
||||
<div className={styles.action}>
|
||||
<Button
|
||||
type="submit"
|
||||
@@ -110,6 +125,7 @@ class SignUp extends React.Component {
|
||||
id="coralSignUpButton"
|
||||
className={styles.button}
|
||||
full
|
||||
disabled={blocked}
|
||||
>
|
||||
{t('talk-plugin-auth.login.sign_up')}
|
||||
</Button>
|
||||
@@ -161,6 +177,9 @@ SignUp.propTypes = {
|
||||
errorMessage: PropTypes.string,
|
||||
requireEmailConfirmation: PropTypes.bool.isRequired,
|
||||
success: PropTypes.bool.isRequired,
|
||||
blocked: PropTypes.bool.isRequired,
|
||||
indicateBlocker: PropTypes.func.isRequired,
|
||||
indicateBlockerResolved: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default SignUp;
|
||||
|
||||
@@ -16,8 +16,19 @@ class SignUpContainer extends Component {
|
||||
emailError: null,
|
||||
passwordError: null,
|
||||
passwordRepeatError: null,
|
||||
blockers: [],
|
||||
};
|
||||
|
||||
indicateBlocker = key =>
|
||||
this.setState(state => ({
|
||||
blockers: state.blockers.concat(key),
|
||||
}));
|
||||
|
||||
indicateBlockerResolved = key =>
|
||||
this.setState(state => ({
|
||||
blockers: state.blockers.filter(i => i !== key),
|
||||
}));
|
||||
|
||||
validate = data => {
|
||||
let valid = true;
|
||||
const changes = {};
|
||||
@@ -48,7 +59,7 @@ class SignUpContainer extends Component {
|
||||
passwordRepeat: this.state.passwordRepeat,
|
||||
};
|
||||
|
||||
if (this.validate(data)) {
|
||||
if (this.validate(data) && !this.state.blockers.length) {
|
||||
this.props.signUp(data);
|
||||
}
|
||||
};
|
||||
@@ -76,6 +87,9 @@ class SignUpContainer extends Component {
|
||||
render() {
|
||||
return (
|
||||
<SignUp
|
||||
indicateBlocker={this.indicateBlocker}
|
||||
indicateBlockerResolved={this.indicateBlockerResolved}
|
||||
blocked={!!this.state.blockers.length}
|
||||
onSubmit={this.handleSubmit}
|
||||
onUsernameChange={this.setUsername}
|
||||
onEmailChange={this.props.setEmail}
|
||||
|
||||
@@ -14,10 +14,10 @@ import cn from 'classnames';
|
||||
|
||||
class Settings extends React.Component {
|
||||
childFactory = el => {
|
||||
const pluginName = el.type.talkPluginName;
|
||||
const key = el.key;
|
||||
const props = {
|
||||
indicateOn: () => this.props.indicateOn(pluginName),
|
||||
indicateOff: () => this.props.indicateOff(pluginName),
|
||||
indicateOn: () => this.props.indicateOn(key),
|
||||
indicateOff: () => this.props.indicateOff(key),
|
||||
};
|
||||
return React.cloneElement(el, props);
|
||||
};
|
||||
|
||||
@@ -20,14 +20,14 @@ class SettingsContainer extends React.Component {
|
||||
turnOffInput: {},
|
||||
};
|
||||
|
||||
indicateOn = plugin =>
|
||||
indicateOn = key =>
|
||||
this.setState(state => ({
|
||||
hasNotifications: state.hasNotifications.concat(plugin),
|
||||
hasNotifications: state.hasNotifications.concat(key),
|
||||
}));
|
||||
|
||||
indicateOff = plugin =>
|
||||
indicateOff = key =>
|
||||
this.setState(state => ({
|
||||
hasNotifications: state.hasNotifications.filter(i => i !== plugin),
|
||||
hasNotifications: state.hasNotifications.filter(i => i !== key),
|
||||
}));
|
||||
|
||||
setTurnOffInputFragment = fragment =>
|
||||
|
||||
Reference in New Issue
Block a user