diff --git a/app.json b/app.json index e498c5168..5faa23bc2 100644 --- a/app.json +++ b/app.json @@ -29,5 +29,5 @@ "as": "POSTMARK" }], "image": "heroku/nodejs", - "success_url": "/admin/setup" + "success_url": "/admin/install" } diff --git a/client/coral-admin/src/containers/Configure/CommentSettings.js b/client/coral-admin/src/containers/Configure/CommentSettings.js index 5a14cf565..90057c5fe 100644 --- a/client/coral-admin/src/containers/Configure/CommentSettings.js +++ b/client/coral-admin/src/containers/Configure/CommentSettings.js @@ -52,7 +52,6 @@ const updateClosedMessage = (updateSettings) => (event) => { }; const updateCustomCssUrl = (updateSettings) => (event) => { - console.log('updateCustomCssUrl', event.target.value); const customCssUrl = event.target.value; updateSettings({customCssUrl}); }; diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js index 5e979d243..5c72e65d6 100644 --- a/client/coral-embed-stream/src/Embed.js +++ b/client/coral-embed-stream/src/Embed.js @@ -2,6 +2,9 @@ import React, {Component} from 'react'; import {compose} from 'react-apollo'; import {connect} from 'react-redux'; import isEqual from 'lodash/isEqual'; +import I18n from 'coral-framework/modules/i18n/i18n'; +import translations from 'coral-framework/translations'; +const lang = new I18n(translations); import {TabBar, Tab, TabContent, Spinner} from 'coral-ui'; @@ -25,7 +28,7 @@ import UserBox from 'coral-sign-in/components/UserBox'; import SignInContainer from 'coral-sign-in/containers/SignInContainer'; import SuspendedAccount from 'coral-framework/components/SuspendedAccount'; import ChangeUsernameContainer from '../../coral-sign-in/containers/ChangeUsernameContainer'; -import SettingsContainer from 'coral-settings/containers/SettingsContainer'; +import ProfileContainer from 'coral-settings/containers/ProfileContainer'; import RestrictedContent from 'coral-framework/components/RestrictedContent'; import ConfigureStreamContainer from 'coral-configure/containers/ConfigureStreamContainer'; import LoadMore from './LoadMore'; @@ -110,7 +113,7 @@ class Embed extends Component {
- Settings + {lang.t('profile')} Configure Stream {loggedIn && } @@ -190,7 +193,7 @@ class Embed extends Component { loadMore={this.props.loadMore}/> - dispatch => { dispatch(verifyEmailSuccess()); }) .catch(err => { - console.log('failed to send email verification', err); // email might have already been verifyed - dispatch(verifyEmailFailure()); + dispatch(verifyEmailFailure(err)); }); }; diff --git a/client/coral-framework/helpers/response.js b/client/coral-framework/helpers/response.js index 64803faef..0fce878cd 100644 --- a/client/coral-framework/helpers/response.js +++ b/client/coral-framework/helpers/response.js @@ -45,7 +45,7 @@ const handleResp = res => { } if (err.error && err.error.translation_key) { - message = err.error.translation_key; + error.translation_key = err.error.translation_key; } error.message = message; diff --git a/client/coral-framework/translations.json b/client/coral-framework/translations.json index c817925eb..d115aedca 100644 --- a/client/coral-framework/translations.json +++ b/client/coral-framework/translations.json @@ -1,5 +1,6 @@ { "en": { + "profile": "Profile", "successUpdateSettings": "The changes you have made have been applied to the comment stream on this article", "successNameUpdate": "Your username has been updated", "contentNotAvailable": "This content is not available", @@ -36,6 +37,7 @@ } }, "es": { + "profile": "Perfil", "successUpdateSettings": "La configuración de este articulo fue actualizada", "successBioUpdate": "Tu bio fue actualizada", "contentNotAvailable": "El contenido no se encuentra disponible", diff --git a/client/coral-plugin-commentbox/CommentBox.js b/client/coral-plugin-commentbox/CommentBox.js index 3d895df07..19472ef70 100644 --- a/client/coral-plugin-commentbox/CommentBox.js +++ b/client/coral-plugin-commentbox/CommentBox.js @@ -30,6 +30,7 @@ class CommentBox extends Component { postItem, assetId, updateCountCache, + isReply, countCache, parentId, addNotification, @@ -46,19 +47,17 @@ class CommentBox extends Component { if (this.props.charCount && this.state.body.length > this.props.charCount) { return; } - updateCountCache(assetId, countCache + 1); + !isReply && updateCountCache(assetId, countCache + 1); postItem(comment, 'comments') .then(({data}) => { const postedComment = data.createComment.comment; if (postedComment.status === 'REJECTED') { addNotification('error', lang.t('comment-post-banned-word')); - updateCountCache(assetId, countCache); + !isReply && updateCountCache(assetId, countCache); } else if (postedComment.status === 'PREMOD') { addNotification('success', lang.t('comment-post-notif-premod')); - updateCountCache(assetId, countCache); - } else { - addNotification('success', 'Your comment has been posted.'); + !isReply && updateCountCache(assetId, countCache); } if (commentPostedHandler) { @@ -110,7 +109,6 @@ class CommentBox extends Component { cStyle='darkGrey' className={`${name}-cancel-button`} onClick={() => { - console.log('cancel button in comment box'); cancelButtonClicked(''); }}> {lang.t('cancel')} diff --git a/client/coral-plugin-stream/RileysAwesomeCommentBox.js b/client/coral-plugin-stream/RileysAwesomeCommentBox.js deleted file mode 100644 index 73fa6407d..000000000 --- a/client/coral-plugin-stream/RileysAwesomeCommentBox.js +++ /dev/null @@ -1,58 +0,0 @@ -import React, {Component} from 'react'; -import {graphql} from 'react-apollo'; -import gql from 'graphql-tag'; - -export class RileysAwesomeCommentBox extends Component { - - postComment() { - console.log(this.props); - console.log('postComment', this.props.asset_id); - this.props.mutate({ - variables: { - asset_id: this.props.asset_id, - body: this.textarea.value, - parent_id: null - } - }).then(({data}) => { - console.log('it workt'); - console.log(data); - }); - } - - render() { - return
- - -
; - } -} - -const postComment = gql` - fragment commentView on Comment { - id - body - user { - name: username - } - actions { - type: action_type - count - current: current_user { - id - created_at - } - } - } - - mutation CreateComment ($asset_id: ID!, $parent_id: ID, $body: String!) { - createComment(asset_id:$asset_id, parent_id:$parent_id, body:$body) { - ...commentView - } - } -`; - -const RileysAwesomeCommentBoxWithData = graphql( - postComment -)(RileysAwesomeCommentBox); - -export default RileysAwesomeCommentBoxWithData; diff --git a/client/coral-plugin-stream/Stream.js b/client/coral-plugin-stream/Stream.js deleted file mode 100644 index 72e03d4ae..000000000 --- a/client/coral-plugin-stream/Stream.js +++ /dev/null @@ -1,100 +0,0 @@ -import React, {Component} from 'react'; -import {graphql} from 'react-apollo'; -import gql from 'graphql-tag'; -import {fetchSignIn} from 'coral-framework/actions/auth'; -import RileysAwesomeCommentBox from 'coral-plugin-stream/RileysAwesomeCommentBox'; - -const assetID = '6187a94b-0b6d-4a96-ac6b-62b529cd8410'; - -// MyComponent is a "presentational" or apollo-unaware component, -// It could be a simple React class: -class Stream extends Component { - - constructor(props) { - super(props); - } - - logMeIn() { - fetchSignIn({email: 'your@example.com', password: 'dfasidfaisdufoiausdfoiuaspdoifas'})(() => {}); - } - - render() { - const {data} = this.props; - return
- - { - data.loading - ? 'loading!' - :
- -

Asset ID: {data.asset.id}

-
    - { - data.asset.comments.map(comment => { - return
  • - {comment.body} [{comment.id}] -
      - { - comment.replies.map(reply => { - return
    • {reply.body}
    • ; - }) - } -
    -
  • ; - }) - } -
-
- } -
; - } -} - -// Initialize GraphQL queries or mutations with the gql tag -const StreamQuery = gql`fragment commentView on Comment { - id - body - user { - name: username - } - tags { - name - } - actions { - type: action_type - count - current: current_user { - id - created_at - } - } -} - -query AssetQuery($asset_id: ID!) { - asset(id: $asset_id) { - id - title - url - commentCount - comments { - ...commentView - replies { - ...commentView - } - } - } -}`; - -// We then can use `graphql` to pass the query results returned by MyQuery -// to MyComponent as a prop (and update them as the results change) -const StreamWithData = graphql( - StreamQuery, { - options: { - variables: { - asset_id: assetID - } - } - } -)(Stream); - -export default StreamWithData; diff --git a/client/coral-settings/components/NotLoggedIn.js b/client/coral-settings/components/NotLoggedIn.js index 2e2b64181..acd3ae7e6 100644 --- a/client/coral-settings/components/NotLoggedIn.js +++ b/client/coral-settings/components/NotLoggedIn.js @@ -10,7 +10,6 @@ export default ({showSignInDialog}) => ( diff --git a/client/coral-settings/components/SettingsHeader.css b/client/coral-settings/components/ProfileHeader.css similarity index 100% rename from client/coral-settings/components/SettingsHeader.css rename to client/coral-settings/components/ProfileHeader.css diff --git a/client/coral-settings/components/ProfileHeader.js b/client/coral-settings/components/ProfileHeader.js new file mode 100644 index 000000000..24b2222bd --- /dev/null +++ b/client/coral-settings/components/ProfileHeader.js @@ -0,0 +1,12 @@ +import React, {PropTypes} from 'react'; +import styles from './ProfileHeader.css'; + +const ProfileHeader = ({username}) => ( +
+

{username}

+
+); + +ProfileHeader.propTypes = {username: PropTypes.string.isRequired}; + +export default ProfileHeader; diff --git a/client/coral-settings/components/SettingsHeader.js b/client/coral-settings/components/SettingsHeader.js deleted file mode 100644 index 34d347314..000000000 --- a/client/coral-settings/components/SettingsHeader.js +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import styles from './SettingsHeader.css'; - -export default ({userData}) => ( -
-

{userData.username}

- - { - - // Hiding display of users ID unless there's a use case for it. - //

{userData.profiles.map(profile => profile.id)}

- } -
-); diff --git a/client/coral-settings/containers/SettingsContainer.js b/client/coral-settings/containers/ProfileContainer.js similarity index 92% rename from client/coral-settings/containers/SettingsContainer.js rename to client/coral-settings/containers/ProfileContainer.js index 9e72cdadc..4a98ed8ff 100644 --- a/client/coral-settings/containers/SettingsContainer.js +++ b/client/coral-settings/containers/ProfileContainer.js @@ -8,13 +8,13 @@ import {myCommentHistory} from 'coral-framework/graphql/queries'; import {link} from 'coral-framework/services/PymConnection'; import NotLoggedIn from '../components/NotLoggedIn'; import {Spinner} from 'coral-ui'; -import SettingsHeader from '../components/SettingsHeader'; +import ProfileHeader from '../components/ProfileHeader'; import CommentHistory from 'coral-plugin-history/CommentHistory'; import translations from '../translations'; const lang = new I18n(translations); -class SettingsContainer extends Component { +class ProfileContainer extends Component { constructor (props) { super(props); this.state = { @@ -44,7 +44,7 @@ class SettingsContainer extends Component { return (
- + { // Hiding bio until moderation can get figured out @@ -88,4 +88,4 @@ const mapDispatchToProps = () => ({ export default compose( connect(mapStateToProps, mapDispatchToProps), myCommentHistory -)(SettingsContainer); +)(ProfileContainer); diff --git a/client/coral-settings/translations.json b/client/coral-settings/translations.json index c8398bd7b..945d71b87 100644 --- a/client/coral-settings/translations.json +++ b/client/coral-settings/translations.json @@ -1,20 +1,22 @@ { "en":{ + "profile": "Profile", "userNoComment": "You've never left a comment. Join the conversation!", "allComments": "All Comments", "profileSettings": "Profile Settings", "myCommentHistory": "My comment History", "signIn": "Sign in", - "toAccess": " to access Settings", - "fromSettingsPage": "From the Settings Page you can see your comment history." + "toAccess": " to access Profile", + "fromSettingsPage": "From the Profile Page you can see your comment history." }, "es":{ + "profile": "Perfil", "userNoComment": "No has dejado áun ningún comentario. ¡Unete a la conversación!", "allComments": "Todos los comentarios", "profileSettings": "Configuración del perfil", "myCommentHistory": "Mi historial de comentarios", "signIn": "Entrar", - "toAccess": "para acceder a la configuración", + "toAccess": "para acceder a al perfil", "fromSettingsPage": "Desde la peagina de configuración puede ver su historia de comentarios." } } diff --git a/client/coral-sign-in/components/CreateUsernameDialog.js b/client/coral-sign-in/components/CreateUsernameDialog.js index d245b38ac..d0e348046 100644 --- a/client/coral-sign-in/components/CreateUsernameDialog.js +++ b/client/coral-sign-in/components/CreateUsernameDialog.js @@ -3,14 +3,18 @@ import TextField from 'coral-ui/components/TextField'; import Alert from './Alert'; import Button from 'coral-ui/components/Button'; import {Dialog} from 'coral-ui'; +import FakeComment from './FakeComment'; + import styles from './styles.css'; + import I18n from 'coral-framework/modules/i18n/i18n'; import translations from '../translations'; const lang = new I18n(translations); -const CreateUsernameDialog = ({open, handleClose, offset, formData, handleSubmitUsername, handleChange, ...props}) => ( +const CreateUsernameDialog = ({open, handleClose, offset, formData, handleSubmitUsername, handleChange, ...props}) => { + return (
- +

{lang.t('createdisplay.yourusername')}

+ +

{lang.t('createdisplay.ifyoudontchangeyourname')}

{ props.auth.error && {props.auth.error} }
- - { props.errors.username && {lang.t('createdisplay.specialCharacters')} } -
+ { props.errors.username && {lang.t('createdisplay.specialCharacters')} } +
+
-); + ); +}; export default CreateUsernameDialog; diff --git a/client/coral-sign-in/components/FakeComment.js b/client/coral-sign-in/components/FakeComment.js new file mode 100644 index 000000000..b5af6bf1c --- /dev/null +++ b/client/coral-sign-in/components/FakeComment.js @@ -0,0 +1,66 @@ +import React from 'react'; +import styles from 'coral-embed-stream/src/Comment.css'; + +import AuthorName from 'coral-plugin-author-name/AuthorName'; +import Content from 'coral-plugin-commentcontent/CommentContent'; +import PubDate from 'coral-plugin-pubdate/PubDate'; +import {ReplyButton} from 'coral-plugin-replies'; + +import I18n from 'coral-framework/modules/i18n/i18n'; +import translations from '../translations'; + +const lang = new I18n(translations); + +class FakeComment extends React.Component { + constructor (props) { + super(props); + } + + render () { + const {username, created_at, body} = this.props; + + return ( +
+
+ + + +
+
+ +
+ {}} + parentCommentId={'commentID'} + currentUserId={{}} + banned={false} + /> +
+
+
+ +
+
+ +
+
+
+ ); + } +} + +export default FakeComment; diff --git a/client/coral-sign-in/components/styles.css b/client/coral-sign-in/components/styles.css index 87e762ebf..31d4a4fed 100644 --- a/client/coral-sign-in/components/styles.css +++ b/client/coral-sign-in/components/styles.css @@ -118,7 +118,7 @@ input.error{ } .action { - margin-top: 15px; + margin-top: 0px; } .passwordRequestSuccess { @@ -141,6 +141,40 @@ input.error{ display: block; } -.confirmSubmit { +/* Change username Dialog*/ +.dialogusername { + border: none; + box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2); + width: 400px; + top: 10px; +} + +.yourusername { + display: block; +} + +.example { + display: block; +} + +.ifyoudont { + display: block; + margin-top: 15px; +} + +.saveusername { + display: block; + width: 100%; +} + +.savebutton { + display: inline; + background-color: rgb(105,105,105); + color: white; +} + +.fakeComment { + display: block; + margin-bottom: 5px; } diff --git a/client/coral-sign-in/containers/ChangeUsernameContainer.js b/client/coral-sign-in/containers/ChangeUsernameContainer.js index 33ae63614..c4450aa56 100644 --- a/client/coral-sign-in/containers/ChangeUsernameContainer.js +++ b/client/coral-sign-in/containers/ChangeUsernameContainer.js @@ -29,6 +29,7 @@ class ChangeUsernameContainer extends Component { constructor(props) { super(props); + this.initialState.formData.username = props.user.username; this.state = this.initialState; this.handleChange = this.handleChange.bind(this); this.handleSubmitUsername = this.handleSubmitUsername.bind(this); @@ -103,7 +104,7 @@ class ChangeUsernameContainer extends Component { return (
(err, user) => { /** * Returns the response to the login attempt via a popup callback with some JS. */ + const HandleAuthPopupCallback = (req, res, next) => (err, user) => { if (err) { return res.render('auth-callback', {err: JSON.stringify(err), data: null}); @@ -70,20 +70,15 @@ const HandleAuthPopupCallback = (req, res, next) => (err, user) => { return res.render('auth-callback', {err: JSON.stringify(errors.ErrNotAuthorized), data: null}); } - // Authorize the user to edit their username. - UsersService.toggleNameEdit(user.id, true) - .then(() => { - - // Perform the login of the user! - req.logIn(user, (err) => { - if (err) { - return res.render('auth-callback', {err: JSON.stringify(err), data: null}); - } + // Perform the login of the user! + req.logIn(user, (err) => { + if (err) { + return res.render('auth-callback', {err: JSON.stringify(err), data: null}); + } - // We logged in the user! Let's send back the user data. - res.render('auth-callback', {err: null, data: JSON.stringify(user)}); - }); - }); + // We logged in the user! Let's send back the user data. + res.render('auth-callback', {err: null, data: JSON.stringify(user)}); + }); }; /** diff --git a/services/users.js b/services/users.js index cf3a0063d..b58776a75 100644 --- a/services/users.js +++ b/services/users.js @@ -124,6 +124,8 @@ module.exports = class UsersService { return user; } + // User does not exist and need to be created. + let username = UsersService.castUsername(displayName); // The user was not found, lets create them! @@ -131,7 +133,8 @@ module.exports = class UsersService { username, lowercaseUsername: username.toLowerCase(), roles: [], - profiles: [{id, provider}] + profiles: [{id, provider}], + canEditName: true }); return user.save();