Skip to content

Commit

Permalink
Merge branch 'master' into gdpr-delete
Browse files Browse the repository at this point in the history
  • Loading branch information
wyattjoh committed May 2, 2018
2 parents 864e062 + 9dc040f commit ddaa8eb
Show file tree
Hide file tree
Showing 59 changed files with 650 additions and 211 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ plugins/*
!plugins/talk-plugin-notifications-digest-hourly
!plugins/talk-plugin-offtopic
!plugins/talk-plugin-permalink
!plugins/talk-plugin-profile-settings
!plugins/talk-plugin-profile-data
!plugins/talk-plugin-remember-sort
!plugins/talk-plugin-respect
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ You’ve installed Talk on your server, and you’re preparing to launch it on y

## End-to-End Testing

Talk uses [Nightwatch](https://nightwatchjs.org/) as our e2e testing framework. The testing infrastructure that allows us to run our tests in real browsers is provided with love by our friends at [Browserstack](https://browserstack.com).
Talk uses [Nightwatch](http://nightwatchjs.org/) as our e2e testing framework. The testing infrastructure that allows us to run our tests in real browsers is provided with love by our friends at [Browserstack](https://browserstack.com).

[![Browserstack](/public/img/browserstack_logo.png)](https://browserstack.com)

Expand Down
9 changes: 8 additions & 1 deletion bin/cli-users
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,15 @@ async function createUser() {

const { email, username, password, role } = answers;

const ctx = Context.forSystem();

// Create the user.
const user = await UsersService.createLocalUser(email, password, username);
const user = await UsersService.createLocalUser(
ctx,
email,
password,
username
);

// Set the role.
await UsersService.setRole(user.id, role);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ class OrganizationSettings extends React.Component {
await this.props.savePending();
this.disableEditing();
};

displayErrors = (errors = []) => (
<ul className={styles.errorList}>
{errors.map((errKey, i) => (
Expand All @@ -85,7 +84,6 @@ class OrganizationSettings extends React.Component {
render() {
const { settings, slotPassthrough, canSave } = this.props;
const hasErrors = this.state.errors.length;

return (
<ConfigurePage title={t('configure.organization_information')}>
<p>{t('configure.organization_info_copy')}</p>
Expand Down Expand Up @@ -126,7 +124,7 @@ class OrganizationSettings extends React.Component {
[styles.editable]: this.state.editing,
})}
onChange={this.updateEmail}
value={settings.organizationContactEmail}
value={settings.organizationContactEmail || ''}
id={t('configure.organization_contact_email')}
readOnly={!this.state.editing}
/>
Expand Down
40 changes: 28 additions & 12 deletions client/coral-admin/src/routes/Configure/containers/Configure.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import OrganizationSettings from './OrganizationSettings';
import { withRouter } from 'react-router';

class ConfigureContainer extends React.Component {
state = { nextRoute: '' };
nextRoute = '';
unregisterLeaveHook = null;

savePending = async () => {
await this.props.updateSettings(this.props.pending);
Expand All @@ -40,39 +41,54 @@ class ConfigureContainer extends React.Component {
};

gotoNextRoute = () => {
const { nextRoute } = this.state;
if (nextRoute) {
this.props.router.push(nextRoute);
this.setState({ nextRoute: '' });
if (this.nextRoute) {
this.props.router.push(this.nextRoute);
this.nextRoute = '';
}
};

handleSectionChange = async section => {
const nextRoute = `/admin/configure/${section}`;

if (this.shouldShowSaveDialog()) {
await this.setState({ nextRoute });
if (this.hasPendingData()) {
this.nextRoute = nextRoute;
this.props.showSaveDialog();
} else {
// Just go to the section
this.props.router.push(nextRoute);
}
};

shouldShowSaveDialog = () => {
navigationPrompt = e => {
if (this.hasPendingData()) {
const confirmationMessage = 'Changes that you made may not be saved.';
e.returnValue = confirmationMessage; // Gecko, Trident, Chrome 34+
return confirmationMessage; // Gecko, WebKit, Chrome <34
}
};

hasPendingData = () => {
return !!Object.keys(this.props.pending).length;
};

routeLeave = ({ pathname }) => {
if (this.shouldShowSaveDialog()) {
this.setState({ nextRoute: pathname });
if (this.hasPendingData()) {
this.nextRoute = pathname;
this.props.showSaveDialog();
return false;
}
};

componentDidMount() {
this.props.router.setRouteLeaveHook(this.props.route, this.routeLeave);
this.unregisterLeaveHook = this.props.router.setRouteLeaveHook(
this.props.route,
this.routeLeave
);
window.addEventListener('beforeunload', this.navigationPrompt);
}

componentWillUnmount() {
this.unregisterLeaveHook();
window.removeEventListener('beforeunload', this.navigationPrompt);
}

render() {
Expand Down
30 changes: 25 additions & 5 deletions client/coral-embed-stream/src/tabs/profile/components/Profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,40 @@ import Slot from 'coral-framework/components/Slot';
import styles from './Profile.css';
import TabPanel from '../containers/TabPanel';

const Profile = ({ username, emailAddress, root, slotPassthrough }) => {
const DefaultProfileHeader = ({ username, emailAddress }) => (
<div className={styles.userInfo}>
<h2 className={styles.username}>{username}</h2>
{emailAddress ? <p className={styles.email}>{emailAddress}</p> : null}
</div>
);

DefaultProfileHeader.propTypes = {
username: PropTypes.string,
emailAddress: PropTypes.string,
};

const Profile = ({ id, username, emailAddress, root, slotPassthrough }) => {
return (
<div className="talk-my-profile talk-profile-container">
<div className={styles.userInfo}>
<h2 className={styles.username}>{username}</h2>
{emailAddress ? <p className={styles.email}>{emailAddress}</p> : null}
</div>
<Slot
fill="profileHeader"
size={1}
defaultComponent={DefaultProfileHeader}
passthrough={{
...slotPassthrough,
id,
username,
emailAddress,
}}
/>
<Slot fill="profileSections" passthrough={slotPassthrough} />
<TabPanel root={root} slotPassthrough={slotPassthrough} />
</div>
);
};

Profile.propTypes = {
id: PropTypes.string,
username: PropTypes.string,
emailAddress: PropTypes.string,
root: PropTypes.object,
Expand Down
10 changes: 10 additions & 0 deletions client/coral-embed-stream/src/tabs/profile/containers/Profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class ProfileContainer extends Component {

return (
<Profile
id={me.id}
username={me.username}
emailAddress={emailAddress}
root={root}
Expand All @@ -53,6 +54,15 @@ const withProfileQuery = withQuery(
me {
id
username
state {
status {
username {
history {
created_at
}
}
}
}
}
...${getDefinitionName(TabPanel.fragments.root)}
${getSlotFragmentSpreads(slots, 'root')}
Expand Down
4 changes: 2 additions & 2 deletions client/coral-embed-stream/style/default.css
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,8 @@ button.comment__action-button[disabled],
}

.talk-plugin-flags-popup-header {
font-weight: bolder;
font-size: 1.33rem;
font-weight: bold;
font-size: 1rem;
margin-bottom: 10px;
}

Expand Down
3 changes: 2 additions & 1 deletion client/coral-framework/graphql/fragments.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default {
'UpdateSettingsResponse',
'RequestAccountDeletionResponse',
'RequestDownloadLinkResponse',
'CancelAccountDeletionResponse'
'CancelAccountDeletionResponse',
'ChangePasswordResponse'
),
};
21 changes: 21 additions & 0 deletions client/coral-framework/graphql/mutations.js
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,27 @@ export const withUpdateSettings = withMutation(
}
);

export const withChangePassword = withMutation(
gql`
mutation ChangePassword($input: ChangePasswordInput!) {
changePassword(input: $input) {
...ChangePasswordResponse
}
}
`,
{
props: ({ mutate }) => ({
changePassword: input => {
return mutate({
variables: {
input,
},
});
},
}),
}
);

export const withRequestAccountDeletion = withMutation(
gql`
mutation RequestAccountDeletion {
Expand Down
7 changes: 4 additions & 3 deletions client/coral-framework/services/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'moment/locale/da';
import 'moment/locale/de';
import 'moment/locale/es';
import 'moment/locale/fr';
import 'moment/locale/nl';
import 'moment/locale/pt-br';

import { createStorage } from 'coral-framework/services/storage';
Expand All @@ -18,21 +19,21 @@ import daTA from 'timeago.js/locales/da';
import deTA from 'timeago.js/locales/de';
import esTA from 'timeago.js/locales/es';
import frTA from 'timeago.js/locales/fr';
import nlTA from 'timeago.js/locales/nl';
import pt_BRTA from 'timeago.js/locales/pt_BR';
import zh_CNTA from 'timeago.js/locales/zh_CN';
import zh_TWTA from 'timeago.js/locales/zh_TW';
import nl from 'timeago.js/locales/nl';

import ar from '../../../locales/ar.yml';
import en from '../../../locales/en.yml';
import da from '../../../locales/da.yml';
import de from '../../../locales/de.yml';
import es from '../../../locales/es.yml';
import fr from '../../../locales/fr.yml';
import nl_NL from '../../../locales/nl_NL.yml';
import pt_BR from '../../../locales/pt_BR.yml';
import zh_CN from '../../../locales/zh_CN.yml';
import zh_TW from '../../../locales/zh_TW.yml';
import nl_NL from '../../../locales/nl_NL.yml';

const defaultLanguage = process.env.TALK_DEFAULT_LANG;
const translations = {
Expand Down Expand Up @@ -112,10 +113,10 @@ export function setupTranslations() {
ta.register('da', daTA);
ta.register('de', deTA);
ta.register('fr', frTA);
ta.register('nl_NL', nlTA);
ta.register('pt_BR', pt_BRTA);
ta.register('zh_CN', zh_CNTA);
ta.register('zh_TW', zh_TWTA);
ta.register('nl_NL', nl);

timeagoInstance = ta();
}
Expand Down
6 changes: 5 additions & 1 deletion client/coral-framework/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,11 @@ export function getTotalReactionsCount(actionSummaries) {

// Like lodash merge but does not recurse into arrays.
export function mergeExcludingArrays(objValue, srcValue) {
if (typeof srcValue === 'object' && !Array.isArray(srcValue)) {
if (
typeof srcValue === 'object' &&
!Array.isArray(srcValue) &&
srcValue !== null
) {
return assignWith({}, objValue, srcValue, mergeExcludingArrays);
}
return srcValue;
Expand Down
16 changes: 16 additions & 0 deletions client/coral-framework/utils/user.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import get from 'lodash/get';
import moment from 'moment';

/**
* getReliability
Expand Down Expand Up @@ -33,3 +34,18 @@ export const isSuspended = user => {
export const isBanned = user => {
return get(user, 'state.status.banned.status');
};

/**
* canUsernameBeUpdated
* retrieves boolean whether a username can be updated or not
*/

export const canUsernameBeUpdated = status => {
const oldestEditTime = moment()
.subtract(14, 'days')
.toDate();

return !status.username.history.some(({ created_at }) =>
moment(created_at).isAfter(oldestEditTime)
);
};
2 changes: 1 addition & 1 deletion client/coral-ui/components/PopupMenu.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
box-sizing: border-box;
background: white;
border-radius: 3px;
padding: 20px 10px;
padding: 10px 10px;
z-index: 300;
right: 1%;
}
Expand Down
5 changes: 3 additions & 2 deletions docs/source/03-03-product-guide-moderator-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,9 @@ moderators.

All your team and commenters show in the People sub-tab. From here, you can
manage your team members’ roles (Admins, Moderators, Staff), as well as search
for commenters and take action on them (e.g. Ban/Un-ban, Suspend, etc.). ###
Configure
for commenters and take action on them (e.g. Ban/Un-ban, Suspend, etc.).

### Configure

See [Configuring Talk](/talk/configuring-talk/).

Expand Down
3 changes: 1 addition & 2 deletions docs/source/api/slots.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ By default, Talk has various plugins provided by default. We can see this in `pl
"talk-plugin-sort-most-respected",
"talk-plugin-sort-newest",
"talk-plugin-sort-oldest",
"talk-plugin-viewing-options",
"talk-plugin-profile-settings"
"talk-plugin-viewing-options"
]
}
```
Expand Down
4 changes: 0 additions & 4 deletions docs/source/integrating/configuring-comment-stream.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@ First, you'll enable `talk-plugin-author-menu`, as this houses the Ignore button

And then we will enable the Ignore User plugin: `talk-plugin-ignore-user`.

And finally, we will need to enable Profile Settings; this is the tab on My Profile > Settings where commenters can manage their Ignored Users list.

`talk-plugin-profile-settings`

### Featured Comments

To enable the featuring of comments, you'll need to activate `talk-plugin-featured-comments`. If you would like the Featured Comments tab to be the default tab you land on for the stream, you will need to set the default tab ENV variable:
Expand Down
4 changes: 0 additions & 4 deletions docs/source/integrating/notifications.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ Adding the `talk-plugin-notifications` plugin will also enable the `notification

See https://github.com/coralproject/talk/blob/8b669a31c551a042f0f079d8cfc16825673eb8f0/plugins/talk-plugin-notifications-reply/index.js for an example.

### Commenter Notification Settings

Note that notifications REQUIRE the `talk-plugin-profile-settings` plugin; this is where on My Profile commenters will enable and manage their notification settings.

### Notification Categories

Talk currently supports the following Notifications options out of the box:
Expand Down
Loading

0 comments on commit ddaa8eb

Please sign in to comment.