From 09bd0a6735f06d8deb7adc1577d46ef68dfa53d7 Mon Sep 17 00:00:00 2001 From: gaba Date: Thu, 25 May 2017 10:43:34 -0400 Subject: [PATCH 01/19] Move templates to a folder for translations. --- services/mailer.js | 4 ++-- services/templates/email_confirm/es/html.ejs | 3 +++ services/templates/email_confirm/es/text.ejs | 9 +++++++++ services/templates/email_confirm/html.ejs | 3 +++ services/templates/email_confirm/text.ejs | 9 +++++++++ services/templates/notification/es/html.ejs | 1 + services/templates/notification/es/text.ejs | 1 + services/templates/notification/html.ejs | 1 + services/templates/notification/text.ejs | 1 + services/templates/password-reset/es/html.ejs | 2 ++ services/templates/password-reset/es/text.ejs | 5 +++++ services/templates/password-reset/html.ejs | 2 ++ services/templates/password-reset/text.ejs | 5 +++++ services/templates/suspension/es/html.ejs | 1 + services/templates/suspension/es/text.ejs | 1 + services/templates/suspension/html.ejs | 1 + services/templates/suspension/text.ejs | 1 + 17 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 services/templates/email_confirm/es/html.ejs create mode 100644 services/templates/email_confirm/es/text.ejs create mode 100644 services/templates/email_confirm/html.ejs create mode 100644 services/templates/email_confirm/text.ejs create mode 100644 services/templates/notification/es/html.ejs create mode 100644 services/templates/notification/es/text.ejs create mode 100644 services/templates/notification/html.ejs create mode 100644 services/templates/notification/text.ejs create mode 100644 services/templates/password-reset/es/html.ejs create mode 100644 services/templates/password-reset/es/text.ejs create mode 100644 services/templates/password-reset/html.ejs create mode 100644 services/templates/password-reset/text.ejs create mode 100644 services/templates/suspension/es/html.ejs create mode 100644 services/templates/suspension/es/text.ejs create mode 100644 services/templates/suspension/html.ejs create mode 100644 services/templates/suspension/text.ejs diff --git a/services/mailer.js b/services/mailer.js index f3d9235ba..5d70fcf50 100644 --- a/services/mailer.js +++ b/services/mailer.js @@ -18,7 +18,7 @@ const templates = { data: {} }; -// load the temlates per request during development +// load the templates per request during development templates.render = (name, format = 'txt', context) => new Promise((resolve, reject) => { // If we are in production mode, check the view cache. @@ -50,7 +50,7 @@ templates.render = (name, format = 'txt', context) => new Promise((resolve, reje return resolve(view(context)); }); -}); +}); // ends templates.render const options = { host: SMTP_HOST, diff --git a/services/templates/email_confirm/es/html.ejs b/services/templates/email_confirm/es/html.ejs new file mode 100644 index 000000000..1da7a1e9d --- /dev/null +++ b/services/templates/email_confirm/es/html.ejs @@ -0,0 +1,3 @@ +

Un correo de confirmación ha sido pedido para esta cuenta: <%= email %>.

+

To confirm the account, please visit the following link: Confirm Email

+

If you did not request this, you can safely ignore this email.

diff --git a/services/templates/email_confirm/es/text.ejs b/services/templates/email_confirm/es/text.ejs new file mode 100644 index 000000000..4c7d7d312 --- /dev/null +++ b/services/templates/email_confirm/es/text.ejs @@ -0,0 +1,9 @@ +A email confirmation has been requested for the following account: + + <%= email %> + +To confirm the account, please visit the following link: + + <%= rootURL %>/confirm/endpoint#<%= token %> + +If you did not request this, you can safely ignore this email. diff --git a/services/templates/email_confirm/html.ejs b/services/templates/email_confirm/html.ejs new file mode 100644 index 000000000..dd2397edf --- /dev/null +++ b/services/templates/email_confirm/html.ejs @@ -0,0 +1,3 @@ +

A email confirmation has been requested for the following account: <%= email %>.

+

To confirm the account, please visit the following link: Confirm Email

+

If you did not request this, you can safely ignore this email.

diff --git a/services/templates/email_confirm/text.ejs b/services/templates/email_confirm/text.ejs new file mode 100644 index 000000000..4c7d7d312 --- /dev/null +++ b/services/templates/email_confirm/text.ejs @@ -0,0 +1,9 @@ +A email confirmation has been requested for the following account: + + <%= email %> + +To confirm the account, please visit the following link: + + <%= rootURL %>/confirm/endpoint#<%= token %> + +If you did not request this, you can safely ignore this email. diff --git a/services/templates/notification/es/html.ejs b/services/templates/notification/es/html.ejs new file mode 100644 index 000000000..b36560ec5 --- /dev/null +++ b/services/templates/notification/es/html.ejs @@ -0,0 +1 @@ +<%= body %> diff --git a/services/templates/notification/es/text.ejs b/services/templates/notification/es/text.ejs new file mode 100644 index 000000000..b36560ec5 --- /dev/null +++ b/services/templates/notification/es/text.ejs @@ -0,0 +1 @@ +<%= body %> diff --git a/services/templates/notification/html.ejs b/services/templates/notification/html.ejs new file mode 100644 index 000000000..b36560ec5 --- /dev/null +++ b/services/templates/notification/html.ejs @@ -0,0 +1 @@ +<%= body %> diff --git a/services/templates/notification/text.ejs b/services/templates/notification/text.ejs new file mode 100644 index 000000000..b36560ec5 --- /dev/null +++ b/services/templates/notification/text.ejs @@ -0,0 +1 @@ +<%= body %> diff --git a/services/templates/password-reset/es/html.ejs b/services/templates/password-reset/es/html.ejs new file mode 100644 index 000000000..e478ceeba --- /dev/null +++ b/services/templates/password-reset/es/html.ejs @@ -0,0 +1,2 @@ +

We received a request to reset your password. If you did not request this change, you can ignore this email.
+If you did, please click here to reset password.

diff --git a/services/templates/password-reset/es/text.ejs b/services/templates/password-reset/es/text.ejs new file mode 100644 index 000000000..1e44a6629 --- /dev/null +++ b/services/templates/password-reset/es/text.ejs @@ -0,0 +1,5 @@ +We received a request to reset your password, click here to reset your password: + +<%= rootURL %>/admin/password-reset#<%= token %> + +If you did not request this change, you can ignore this email. diff --git a/services/templates/password-reset/html.ejs b/services/templates/password-reset/html.ejs new file mode 100644 index 000000000..e478ceeba --- /dev/null +++ b/services/templates/password-reset/html.ejs @@ -0,0 +1,2 @@ +

We received a request to reset your password. If you did not request this change, you can ignore this email.
+If you did, please click here to reset password.

diff --git a/services/templates/password-reset/text.ejs b/services/templates/password-reset/text.ejs new file mode 100644 index 000000000..1e44a6629 --- /dev/null +++ b/services/templates/password-reset/text.ejs @@ -0,0 +1,5 @@ +We received a request to reset your password, click here to reset your password: + +<%= rootURL %>/admin/password-reset#<%= token %> + +If you did not request this change, you can ignore this email. diff --git a/services/templates/suspension/es/html.ejs b/services/templates/suspension/es/html.ejs new file mode 100644 index 000000000..4fd8f191c --- /dev/null +++ b/services/templates/suspension/es/html.ejs @@ -0,0 +1 @@ +<%= body.replace(/\n/g, '
') %> diff --git a/services/templates/suspension/es/text.ejs b/services/templates/suspension/es/text.ejs new file mode 100644 index 000000000..b36560ec5 --- /dev/null +++ b/services/templates/suspension/es/text.ejs @@ -0,0 +1 @@ +<%= body %> diff --git a/services/templates/suspension/html.ejs b/services/templates/suspension/html.ejs new file mode 100644 index 000000000..4fd8f191c --- /dev/null +++ b/services/templates/suspension/html.ejs @@ -0,0 +1 @@ +<%= body.replace(/\n/g, '
') %> diff --git a/services/templates/suspension/text.ejs b/services/templates/suspension/text.ejs new file mode 100644 index 000000000..b36560ec5 --- /dev/null +++ b/services/templates/suspension/text.ejs @@ -0,0 +1 @@ +<%= body %> From 29753a958bdd2d2a07ad47aee486b853f529c576 Mon Sep 17 00:00:00 2001 From: Riley Davis Date: Tue, 30 May 2017 15:50:56 -0600 Subject: [PATCH 02/19] show comments on the UserDetail drawer --- .../src/components/ActionButton.js | 4 +- .../src/components/ModerationList.css | 6 +++ .../ModerationQueue/ModerationContainer.js | 8 +++- .../containers/ModerationQueue/UserDetail.css | 2 +- .../containers/ModerationQueue/UserDetail.js | 44 ++++++++++++++++++- .../ModerationQueue/components/Comment.js | 3 ++ .../src/graphql/queries/userDetail.graphql | 8 ++++ client/coral-ui/components/Drawer.css | 16 +++++-- client/coral-ui/components/Drawer.js | 4 +- graph/typeDefs.graphql | 3 ++ 10 files changed, 88 insertions(+), 10 deletions(-) diff --git a/client/coral-admin/src/components/ActionButton.js b/client/coral-admin/src/components/ActionButton.js index cfd7eb2da..42af5db24 100644 --- a/client/coral-admin/src/components/ActionButton.js +++ b/client/coral-admin/src/components/ActionButton.js @@ -17,11 +17,11 @@ const ActionButton = ({type = '', active, ...props}) => { return ( + >{props.minimal ? '' : t(`modqueue.${text}`)} ); }; diff --git a/client/coral-admin/src/components/ModerationList.css b/client/coral-admin/src/components/ModerationList.css index 4d4f37c9a..99927e7ad 100644 --- a/client/coral-admin/src/components/ModerationList.css +++ b/client/coral-admin/src/components/ModerationList.css @@ -189,6 +189,12 @@ width: 140px; } +.minimal { + width: 45px; + min-width: 0; + float: right; +} + .approve__active { box-shadow: none; color: white; diff --git a/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js b/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js index 152121a63..06f7c9ef3 100644 --- a/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js +++ b/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js @@ -254,7 +254,13 @@ class ModerationContainer extends Component { {moderation.userDetailId && ( + hideUserDetail={hideUserDetail} + bannedWords={settings.wordlist.banned} + suspectWords={settings.wordlist.suspect} + showBanUserDialog={props.showBanUserDialog} + showSuspendUserDialog={props.showSuspendUserDialog} + acceptComment={props.acceptComment} + rejectComment={props.rejectComment} /> )} ); diff --git a/client/coral-admin/src/containers/ModerationQueue/UserDetail.css b/client/coral-admin/src/containers/ModerationQueue/UserDetail.css index e37971ada..7c84f62fa 100644 --- a/client/coral-admin/src/containers/ModerationQueue/UserDetail.css +++ b/client/coral-admin/src/containers/ModerationQueue/UserDetail.css @@ -36,6 +36,6 @@ background-color: transparent; font-size: 16px; position: absolute; - width: 100%; + width: 90%; outline: none; } diff --git a/client/coral-admin/src/containers/ModerationQueue/UserDetail.js b/client/coral-admin/src/containers/ModerationQueue/UserDetail.js index d9b85a060..cabd8bf9f 100644 --- a/client/coral-admin/src/containers/ModerationQueue/UserDetail.js +++ b/client/coral-admin/src/containers/ModerationQueue/UserDetail.js @@ -4,10 +4,18 @@ import styles from './UserDetail.css'; import {compose} from 'react-apollo'; import {getUserDetail} from 'coral-admin/src/graphql/queries'; import Slot from 'coral-framework/components/Slot'; +import Comment from './components/Comment'; +import {actionsMap} from './helpers/moderationQueueActionsMap'; class UserDetail extends React.Component { static propTypes = { id: PropTypes.string.isRequired, + bannedWords: PropTypes.array.isRequired, + suspectWords: PropTypes.array.isRequired, + showBanUserDialog: PropTypes.func.isRequired, + showSuspendUserDialog: PropTypes.func.isRequired, + acceptComment: PropTypes.func.isRequired, + rejectComment: PropTypes.func.isRequired, hideUserDetail: PropTypes.func.isRequired } @@ -22,13 +30,22 @@ class UserDetail extends React.Component { } render () { - const {data, hideUserDetail} = this.props; + const { + data, + hideUserDetail, + bannedWords, + suspectWords, + showBanUserDialog, + showSuspendUserDialog, + acceptComment, + rejectComment + } = this.props; if (!('user' in data)) { return null; } - const {user, totalComments, rejectedComments} = data; + const {user, comments, totalComments, rejectedComments} = data; const localProfile = user.profiles.find((p) => p.provider === 'local'); let profile; if (localProfile) { @@ -64,6 +81,29 @@ class UserDetail extends React.Component {

{`${(rejectedPercent).toFixed(1)}%`}

+
+ { + comments.map((comment, i) => { + const status = comment.action_summaries ? 'FLAGGED' : comment.status; + return {}} + actions={actionsMap[status]} + showBanUserDialog={showBanUserDialog} + showSuspendUserDialog={showSuspendUserDialog} + acceptComment={acceptComment} + rejectComment={rejectComment} + currentAsset={null} + currentUserId={this.props.id} + minimal={true} />; + }) + } +
); } diff --git a/client/coral-admin/src/containers/ModerationQueue/components/Comment.js b/client/coral-admin/src/containers/ModerationQueue/components/Comment.js index bf6b050a1..fe41f4d34 100644 --- a/client/coral-admin/src/containers/ModerationQueue/components/Comment.js +++ b/client/coral-admin/src/containers/ModerationQueue/components/Comment.js @@ -23,6 +23,7 @@ const Comment = ({ viewUserDetail, suspectWords, bannedWords, + minimal, ...props }) => { const links = linkify.getMatches(comment.body); @@ -118,6 +119,7 @@ const Comment = ({ (action === 'APPROVE' && comment.status === 'ACCEPTED'); return ( { return (
×
- {children} +
+ {children} +
); }; diff --git a/graph/typeDefs.graphql b/graph/typeDefs.graphql index 1abb894b8..15278f97e 100644 --- a/graph/typeDefs.graphql +++ b/graph/typeDefs.graphql @@ -148,6 +148,9 @@ enum ACTION_TYPE { # CommentsQuery allows the ability to query comments by a specific methods. input CommentsQuery { + # Author of the comments + author_id: ID + # Current status of a comment. Requires the `ADMIN` role. statuses: [COMMENT_STATUS!] From 6e458e01491bfa4fd8731d1b3ec9949ad4ad6518 Mon Sep 17 00:00:00 2001 From: riley Date: Wed, 31 May 2017 10:54:34 -0600 Subject: [PATCH 03/19] resolve missing files --- .../Moderation/components/UserDetail.js | 114 ++++++++++++++++++ .../Moderation/containers/UserDetail.js | 3 + 2 files changed, 117 insertions(+) create mode 100644 client/coral-admin/src/routes/Moderation/components/UserDetail.js diff --git a/client/coral-admin/src/routes/Moderation/components/UserDetail.js b/client/coral-admin/src/routes/Moderation/components/UserDetail.js new file mode 100644 index 000000000..2fe9730b9 --- /dev/null +++ b/client/coral-admin/src/routes/Moderation/components/UserDetail.js @@ -0,0 +1,114 @@ +import React, {PropTypes} from 'react'; +import {Button, Drawer} from 'coral-ui'; +import styles from './UserDetail.css'; +import Slot from 'coral-framework/components/Slot'; +import Comment from './Comment'; +import {actionsMap} from '../helpers/moderationQueueActionsMap'; + +export default class UserDetail extends React.Component { + static propTypes = { + id: PropTypes.string.isRequired, + hideUserDetail: PropTypes.func.isRequired, + root: PropTypes.object.isRequired, + bannedWords: PropTypes.array.isRequired, + suspectWords: PropTypes.array.isRequired, + showBanUserDialog: PropTypes.func.isRequired, + showSuspendUserDialog: PropTypes.func.isRequired, + acceptComment: PropTypes.func.isRequired, + rejectComment: PropTypes.func.isRequired, + } + + copyPermalink = () => { + this.profile.select(); + try { + document.execCommand('copy'); + } catch (e) { + + /* nothing */ + } + } + + render () { + const { + root: { + user, + totalComments, + rejectedComments, + comments + }, + bannedWords, + suspectWords, + showBanUserDialog, + showSuspendUserDialog, + acceptComment, + rejectComment, + hideUserDetail + } = this.props; + const localProfile = user.profiles.find((p) => p.provider === 'local'); + + let profile; + if (localProfile) { + profile = localProfile.id; + } + + let rejectedPercent = rejectedComments / totalComments; + if (rejectedPercent === Infinity || isNaN(rejectedPercent)) { + + // if totalComments is 0, you're dividing by zero, which is naughty + rejectedPercent = 0; + } + + return ( + +

{user.username}

+ + {profile && this.profile = ref} value={profile} />} + +

Member since {new Date(user.created_at).toLocaleString()}

+
+

+ Account summary +
Data represents the last six months of activity +

+
+
+

Total Comments

+

{totalComments}

+
+
+

Reject Rate

+

{`${(rejectedPercent).toFixed(1)}%`}

+
+
+
+ { + comments.map((comment, i) => { + const status = comment.action_summaries ? 'FLAGGED' : comment.status; + return {}} + actions={actionsMap[status]} + showBanUserDialog={showBanUserDialog} + showSuspendUserDialog={showSuspendUserDialog} + acceptComment={acceptComment} + rejectComment={rejectComment} + currentAsset={null} + currentUserId={this.props.id} + minimal={true} />; + }) + } +
+
+ ); + } +} diff --git a/client/coral-admin/src/routes/Moderation/containers/UserDetail.js b/client/coral-admin/src/routes/Moderation/containers/UserDetail.js index d6ab06af6..7a030fb86 100644 --- a/client/coral-admin/src/routes/Moderation/containers/UserDetail.js +++ b/client/coral-admin/src/routes/Moderation/containers/UserDetail.js @@ -45,8 +45,11 @@ export const withUserDetailQuery = withQuery(gql` }) { ...${getDefinitionName(Comment.fragments.comment)} } + ...${getDefinitionName(Comment.fragments.root)} ${pluginFragments.spreads('root')} } + ${Comment.fragments.root} + ${Comment.fragments.comment} ${pluginFragments.definitions('user')} ${pluginFragments.definitions('root')} `, { From 576cbed8e9fc692046200464d584f547e201768e Mon Sep 17 00:00:00 2001 From: Riley Davis Date: Wed, 31 May 2017 13:44:38 -0600 Subject: [PATCH 04/19] no more errors --- .../coral-admin/src/routes/Moderation/containers/UserDetail.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/coral-admin/src/routes/Moderation/containers/UserDetail.js b/client/coral-admin/src/routes/Moderation/containers/UserDetail.js index 7a030fb86..450988ea5 100644 --- a/client/coral-admin/src/routes/Moderation/containers/UserDetail.js +++ b/client/coral-admin/src/routes/Moderation/containers/UserDetail.js @@ -45,10 +45,8 @@ export const withUserDetailQuery = withQuery(gql` }) { ...${getDefinitionName(Comment.fragments.comment)} } - ...${getDefinitionName(Comment.fragments.root)} ${pluginFragments.spreads('root')} } - ${Comment.fragments.root} ${Comment.fragments.comment} ${pluginFragments.definitions('user')} ${pluginFragments.definitions('root')} From a126c94aa45ad0fdfa4421d888bfdc464c1c283f Mon Sep 17 00:00:00 2001 From: gaba Date: Wed, 31 May 2017 13:55:27 -0700 Subject: [PATCH 05/19] Adds service for translations in the backend. Clean yaml. --- client/coral-framework/services/i18n.js | 2 +- locales/en.yml | 21 ++- locales/es.yml | 178 +++++++----------------- package.json | 3 +- routes/api/users/index.js | 4 +- services/email/email-confirm.html.ejs | 6 +- services/email/email-confirm.txt.ejs | 6 +- services/i18n.js | 50 +++++++ services/mailer.js | 6 +- yarn.lock | 7 + 10 files changed, 140 insertions(+), 143 deletions(-) create mode 100644 services/i18n.js diff --git a/client/coral-framework/services/i18n.js b/client/coral-framework/services/i18n.js index 882127972..ecb3ce11c 100644 --- a/client/coral-framework/services/i18n.js +++ b/client/coral-framework/services/i18n.js @@ -8,7 +8,7 @@ import en from '../../../locales/en.yml'; import es from '../../../locales/es.yml'; import * as plugins from '../helpers/plugins'; -// Translations are happening at https://www.transifex.com/the-coral-project/talk-1/dashboard/. +// Translations are happening at https://translate.lingohub.com/the-coral-project/dashboard const defaultLanguage = 'en'; const translations = {...en, ...es}; diff --git a/locales/en.yml b/locales/en.yml index 99b2558ca..1c272ad32 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -3,17 +3,17 @@ en: are_you_sure: "Are you sure you would like to ban {0}?" ban_user: "Ban User?" banned_user: "Banned User" - cancel: Cancel + cancel: "Cancel" note: "Note: Banning this user will also place this comment in the Rejected queue." yes_ban_user: "Yes, Ban User" bio_offensive: "This bio is offensive" - cancel: Cancel + cancel: "Cancel" characters_remaining: "characters remaining" comment: - anon: Anonymous + anon: "Anonymous" ban_user: "Ban User" comment: "Post a comment" - flagged: flagged + flagged: "flagged" view_context: "View context" comment_box: post: "Post" @@ -125,7 +125,7 @@ en: title: "Configure Comment Stream" weeks: Weeks wordlist: "Banned Words" - continue: Continue + continue: "Continue" createdisplay: check_the_form: "Invalid Form. Please check the fields" continue: "Continue with the same Facebook username" @@ -159,6 +159,13 @@ en: second: "second" secondsPlural: "seconds" unexpectedError: "Unexpected error while saving changes. Sorry!" + email: + confirm: + has_been_requested: "A email confirmation has been requested for the following account:" + to_confirm: "To confirm the account, please visit the following link:" + confirm_email: "Confirm Email" + if_you_did_not: "If you did not request this, you can safely ignore this email." + subject: "Email Confirmation" embedlink: copy: "Copy to Clipboard" error: @@ -248,8 +255,8 @@ en: reject: "Reject" rejected: "Rejected" select_stream: "Select Stream" - shift_key: ⇧ - shortcuts: Shortcuts + shift_key: "⇧" + shortcuts: "Shortcuts" show_shortcuts: "Show Shortcuts" singleview: "Toggle single comment edit view" spam_ads: Spam/Ads diff --git a/locales/es.yml b/locales/es.yml index f80755b71..22a689cd0 100644 --- a/locales/es.yml +++ b/locales/es.yml @@ -4,8 +4,7 @@ es: ban_user: "¿Quieres suspender el Usuario?" banned_user: "Usuario Suspendido" cancel: Cancelar - note: "Nota: Suspender a este usuario también va a colocar este comentario en\ - \ la cola de Rechazados." + note: "Nota: Suspender a este usuario también va a colocar este comentario en la cola de Rechazados." yes_ban_user: "Si, Suspender al usuario" bio_offensive: "Esta biografia es ofensiva" cancel: Cancelar @@ -23,21 +22,15 @@ es: comment: "Publicar un comentario" name: "Nombre" comment_post_notif: "Tu comentario ha sido publicado." - comment_post_notif_premod: "Gracias por el comentario. Nuestro equipo de moderació\ - n va a revisarlo muy pronto." - comment_post_banned_word: "Tu comentario contiene una o más palabras que no está\ - n permitidas en nuestro espacio, por lo que no será publicado. Si crees que\ - \ es un error, por favor contacta a nuestro equipo de moderación." + comment_post_notif_premod: "Gracias por el comentario. Nuestro equipo de moderación va a revisarlo muy pronto." + comment_post_banned_word: "Tu comentario contiene una o más palabras que no están permitidas en nuestro espacio, por lo que no será publicado. Si crees que es un error, por favor contacta a nuestro equipo de moderación." characters_remaining: "carácteres restantes" comment_is_best: "Este comentario es uno de los mejores" comment_offensive: "Este comentario es ofensivo" comment_plural: Comentarios - comment_post_banned_word: "Tu comentario contiene una o más palabras que no está\ - n permitidas en nuestro espacio, por lo que no será publicado. Si crees que es\ - \ un error, por favor contacta a nuestro equipo de moderación." + comment_post_banned_word: "Tu comentario contiene una o más palabras que no están permitidas en nuestro espacio, por lo que no será publicado. Si crees que es un error, por favor contacta a nuestro equipo de moderación." comment_post_notif: "Tu comentario ha sido publicado." - comment_post_notif_premod: "Gracias por el comentario. Nuestro equipo de moderació\ - n va a revisarlo muy pronto." + comment_post_notif_premod: "Gracias por el comentario. Nuestro equipo de moderación va a revisarlo muy pronto." community: account_creation_date: "Fecha de creación de la cuenta" active: Activa @@ -56,8 +49,7 @@ es: newsroom_role: "Rol en la redacción" no_flagged_accounts: "No hay ninguna cuenta reportada en este momento." no_results: "No se encontraron usuarios con ese nombre o correo." - note: "Nota: Suspender a este usuario no le va a permitir (al usuario) borrar\ - \ ni editar ni comentar." + note: "Nota: Suspender a este usuario no le va a permitir (al usuario) borrar ni editar ni comentar." offensive: "Este comentario es ofensivo" other: Otro people: Gente @@ -70,21 +62,15 @@ es: yes_ban_user: "Si, Suspendan el usuario" configure: apply: Aplicar - banned_word_text: "Comentarios que contengan estas palabras o frases, en mayusculas\ - \ o minúsculas, serán automáticamente eliminados del hilo de comentario. Escribir\ - \ una palabra y apretar Enter o Tabulador para agregarla. O pueden pegar una\ - \ lista de palabras separadas por coma." + banned_word_text: "Comentarios que contengan estas palabras o frases, en mayusculas o minúsculas, serán automáticamente eliminados del hilo de comentario. Escribir una palabra y apretar Enter o Tabulador para agregarla. O pueden pegar una lista de palabras separadas por coma." banned_words_title: "Lista de palabras prohibidas" close: "Cerrar" close_after: "Cerrar comentarios luego de" close_stream: "Cerrar comentarios" - close_stream_configuration: "Este hilo de comentario está en este momento cerrado.\ - \ Al abrirlo, nuevos comentarios serán publicados y mostrados." - closed_comments_desc: "Escribe un mensaje que será mostrado cuando los comentarios\ - \ estén cerrados y no se acepten más comentarios." + close_stream_configuration: "Este hilo de comentario está en este momento cerrado. Al abrirlo, nuevos comentarios serán publicados y mostrados." + closed_comments_desc: "Escribe un mensaje que será mostrado cuando los comentarios estén cerrados y no se acepten más comentarios." closed_comments_label: "Escribe un mensaje..." - closed_stream_settings: "Mensaje que se muestra cuando no se aceptan más comentarios\ - \ en el articulo" + closed_stream_settings: "Mensaje que se muestra cuando no se aceptan más comentarios en el articulo" comment_count_error: "Por favor escribir un número válido" comment_count_header: "Limitar el largo del comentario" comment_count_text_post: carácteres @@ -94,64 +80,46 @@ es: comment_stream_will_close: "El hilo de comentarios se cerrara" community: Comunidad configure: Configurar - copy_and_paste: "Copiar y pegar el código de más abajo en tu CMS para colocar\ - \ la caja de comentarios en tus artículos" + copy_and_paste: "Copiar y pegar el código de más abajo en tu CMS para colocar la caja de comentarios en tus artículos" custom_css_url: "URL CSS a medida" - custom_css_url_desc: "URL de una hoja de estilo que va a sobrescribir los estilos\ - \ por defecto del hilo de comentarios. Puede ser interna o externa." + custom_css_url_desc: "URL de una hoja de estilo que va a sobrescribir los estilos por defecto del hilo de comentarios. Puede ser interna o externa." dashboard: Panel days: Días - description: "Como Administrador/a puedes modificar la configuración de los comentarios\ - \ en este artículo" - domain_list_text: "Agrega dominios permitidos a Talk, por ejemplo tu localhost,\ - \ staging y ambientes de producción (ej. localhost:3000, staging.domain.com,\ - \ domain.com)." + description: "Como Administrador/a puedes modificar la configuración de los comentarios en este artículo" + domain_list_text: "Agrega dominios permitidos a Talk, por ejemplo tu localhost, staging y ambientes de producción (ej. localhost:3000, staging.domain.com, domain.com)." domain_list_title: "Dominios Permitidos" edit_comment_timeframe_heading: "Periodo de Tiempo para Edición del Comentario" edit_comment_timeframe_text_pre: "Los comentaristas tendrán" edit_comment_timeframe_text_post: "segundos para editar sus comentarios." embed_comment_stream: "Colocar Hilo de Comentarios" - enable_premod_links_text: "Los moderadores deben aprobar todo comentario que contenga\ - \ un enlace antes de que sea publicado." + enable_premod_links_text: "Los moderadores deben aprobar todo comentario que contenga un enlace antes de que sea publicado." enable_pre_moderation: "Permitir pre-moderación" - enable_pre_moderation_text: "Los moderadores deben aprobar todo comentario antes\ - \ que sea publicado." + enable_pre_moderation_text: "Los moderadores deben aprobar todo comentario antes que sea publicado." enable_premod_links: "Pre-Moderar Comentarios que contienen Enlaces" enable_premod: "Activar Pre Moderación" - enable_premod_description: "Los y las moderadoras deben aprobar cualquier comentario\ - \ antes de su publicación" - enable_premod_links_description: "Los y las moderadoras deben aprobar cualquier\ - \ comentario que contengan enlaces antes de su publicación." + enable_premod_description: "Los y las moderadoras deben aprobar cualquier comentario antes de su publicación" + enable_premod_links_description: "Los y las moderadoras deben aprobar cualquier comentario que contengan enlaces antes de su publicación." enable_questionbox: "Hacer una pregunta a los y las lectoras." - enable_questionbox_description: "Esta pregunta aparecerá en la parte de arriba\ - \ del hilo de comentarios." + enable_questionbox_description: "Esta pregunta aparecerá en la parte de arriba del hilo de comentarios." hours: Horas include_comment_stream: "Incluir Descripción de Hilo de Comentarios para Lectores" - include_comment_stream_desc: "Escribir un mensaje para ser incluido al principio\ - \ del hilo de comentarios. Un tema planteado podría ser la guía de comunidad,\ - \ etc." + include_comment_stream_desc: "Escribir un mensaje para ser incluido al principio del hilo de comentarios. Un tema planteado podría ser la guía de comunidad, etc." include_text: "Agregar tu texto aquí." include_question_here: "Escribir la pregunta aquí." moderate: Moderar moderation_settings: "Configuración de la Moderación" open: "Abrir" open_stream: "Abrir Hilo de Comentarios" - open_stream_configuration: "Este hilo de comentarios está abierto. Al cerrarlo\ - \ no se podrán publicar nuevos comentarios pero todos los comentarios anteriores\ - \ aún serán mostrados." + open_stream_configuration: "Este hilo de comentarios está abierto. Al cerrarlo no se podrán publicar nuevos comentarios pero todos los comentarios anteriores aún serán mostrados." require_email_verification: "Necesita confirmación su correo" - require_email_verification_text: "Nuevos usuarios deben confirmar sus correos\ - \ antes de comentar" + require_email_verification_text: "Nuevos usuarios deben confirmar sus correos antes de comentar" save_changes: "Guardar Cambios" shortcuts: Atajos sign_out: "Desconectar" stories: Artículos stream_settings: "Configuración de Comentarios" suspect_word_title: "Lista de palabras sospechosas" - suspect_word_text: "Comentarios que contengan estas palabras o frases, considerando\ - \ mayusculas y minúsculas, serán automáticamente destacadas en los comentarios\ - \ publicados. Escribir una palabra y apretar Enter o Tabulador para agregarla.\ - \ O pegar una lista de palabras separadas por coma." + suspect_word_text: "Comentarios que contengan estas palabras o frases, considerando mayusculas y minúsculas, serán automáticamente destacadas en los comentarios publicados. Escribir una palabra y apretar Enter o Tabulador para agregarla. O pegar una lista de palabras separadas por coma." tech_settings: "Configuración Técnica" title: "Configurar los comentarios" weeks: Semanas @@ -161,11 +129,9 @@ es: check_the_form: "Formulario Inválido. Por favor verifica los campos" continue: "Continuar con el mismo nombre que aparece en Facebook" error_create: "Hubo un error al cambiar el nombre de usuario" - fake_comment_body: "Este es un comentario de ejemplo. Las lectoras pueden compartir\ - \ sus ideas y opiniones con los periodistas en la sección de comentarios." + fake_comment_body: "Este es un comentario de ejemplo. Las lectoras pueden compartir sus ideas y opiniones con los periodistas en la sección de comentarios." fake_comment_date: "hace un minuto" - if_you_dont_change_your_name: "Si no modificas tu nombre de usuario en este paso\ - \ tu nombre de Facebook aparecerá al lado de cada comentario que publiques." + if_you_dont_change_your_name: "Si no modificas tu nombre de usuario en este paso tu nombre de Facebook aparecerá al lado de cada comentario que publiques." required_field: "Campo requerido" save: Guardar special_characters: "Los nombres sólo pueden contener letras números y _" @@ -173,8 +139,7 @@ es: write_your_username: "Edita tu nombre" your_username: "Tu nombre aparece en cada comentario que publiques." dashboard: - auto_update: "Los datos se actualizan automáticamente cada cinco minutos o cuando\ - \ refresca el navegador." + auto_update: "Los datos se actualizan automáticamente cada cinco minutos o cuando refresca el navegador." comment_count: comentarios flags: Reportes most_flags: "Artículos con la mayor cantidad de reportes" @@ -187,8 +152,7 @@ es: edit_comment: bodyInputLabel: "Editar este comentario" save_button: "Guardar cambios" - editWindowExpired: "No se puede editar este comentario. El periodo de edición\ - \ ya ha concluido. Podrías publicar uno nuevo :-)" + editWindowExpired: "No se puede editar este comentario. El periodo de edición ya ha concluido. Podrías publicar uno nuevo :-)" editWindowExpiredClose: "Cerrar" editWindowTimerPrefix: "Ventana Edición:" second: "segundo" @@ -201,24 +165,20 @@ es: NOT_AUTHORIZED: "Acción no autorizada." NO_SPECIAL_CHARACTERS: "Los nombres pueden contener letras números y _" PASSWORD_LENGTH: "Contraseña es muy corta" - PROFANITY_ERROR: "Los nombres no pueden contener blasfemias. Por favor contacte\ - \ al o la administradora si cree que esto es un error" + PROFANITY_ERROR: "Los nombres no pueden contener blasfemias. Por favor contacte al o la administradora si cree que esto es un error" USERNAME_IN_USE: "Este nombre ya está siendo usado." USERNAME_REQUIRED: "Debe ingresar un nombre" confirm_password: "Las contraseñas no coinciden. Inténtelo nuevamente" - edit_window_ended: "No puedes editar este comentario. El tiempo de edición ha\ - \ expirado." + edit_window_ended: "No puedes editar este comentario. El tiempo de edición ha expirado." edit_username_not_authorized: "No tiene permiso para editar el nombre de usuario." email: "No es un correo válido" - network_error: "Error al conectar con el servidor. Compruebe su conexión a Internet\ - \ y vuelva a intentarlo." + network_error: "Error al conectar con el servidor. Compruebe su conexión a Internet y vuelva a intentarlo." email_in_use: "Este correo se encuentra en uso" email_not_verified: "Correo {0} no confirmado." email_password: "Correo y/o contraseña incorrecta." email_required: "Se requiere un correo" email_username_in_use: "Correo o nombre en uso." - login_maximum_exceeded: "Ha realizado demasiados intentos fallidos de usar la\ - \ contraseña. Por favor espere." + login_maximum_exceeded: "Ha realizado demasiados intentos fallidos de usar la contraseña. Por favor espere." organization_name: "El nombre de la organización debe contener letras y/o números." password: "La contraseña debe tener por lo menos 8 caracteres" password_required: "Debe ingresar la contraseña" @@ -227,8 +187,7 @@ es: flag_reason: "Razón por la que hacer este reporte (Opcional)" flag_username: "Reportar el nombre de usuario" framework: - banned_account_msg: "Tu cuenta se encuentra suspendida. Esto significa que no\ - \ puedes gustar, marcar o escribir comentarios." + banned_account_msg: "Tu cuenta se encuentra suspendida. Esto significa que no puedes gustar, marcar o escribir comentarios." comment: comentario comment_is_ignored: "Este comentario está escondido porque has ignorado al usuario." comments: comentarios @@ -238,9 +197,7 @@ es: button: Enviar error: "Nombres de usuarios pueden solamente incluir letras, números y _" label: "Nuevo Nombre" - msg: "Tu cuenta está suspendida porque tu nombre de usuario ha sido considerado\ - \ no apropiado para el espacio. Para recuperar la cuenta, por favor ingresar\ - \ un nuevo nombre de usuario. Contáctanos si tienes alguna pregunta." + msg: "Tu cuenta está suspendida porque tu nombre de usuario ha sido considerado no apropiado para el espacio. Para recuperar la cuenta, por favor ingresar un nuevo nombre de usuario. Contáctanos si tienes alguna pregunta." ignored_users: "Usuarios ignorados" my_comments: "Mis Comentarios" my_profile: "Mi perfil" @@ -254,8 +211,7 @@ es: view_all_replies_initial: "ver todas las 0 respuestas" view_more_comments: "Ver más comentarios" view_reply: "ver respuesta" - from_settings_page: "Desde la página de configuración puedes ver tu historia de\ - \ comentarios." + from_settings_page: "Desde la página de configuración puedes ver tu historia de comentarios." like: Me gusta loading_results: "Cargando Resultados" marketing: "Esto parece una propaganda" @@ -312,27 +268,23 @@ es: profile_settings: "Configuración del Perfil" reply: Responder report: Reportar - report_notif: "Gracias por reportar este comentario. Nuestro equipo de moderació\ - n ha sido notificado y muy pronto lo va a revisar." + report_notif: "Gracias por reportar este comentario. Nuestro equipo de moderación ha sido notificado y muy pronto lo va a revisar." report_notif_remove: "Tu reporte ha sido eliminado." reported: Reportado set_best: "Etiquetar como el mejor" settings: all_comments: "Todos los comentarios" - from_settings_page: "Desde la página de configuración puedes ver tu historial\ - \ de comentarios." + from_settings_page: "Desde la página de configuración puedes ver tu historial de comentarios." my_comment_history: "Mi historial de comentarios" profile: Perfil profile_settings: "Configuración del perfil" sign_in: "Entrar" to_access: "para acceder al perfil" - user_no_comment: "No has dejado aún ningún comentario. ¡Únete a la conversació\ - n!" + user_no_comment: "No has dejado aún ningún comentario. ¡Únete a la conversación!" sign_in: email_verify_cta: "Por favor confirme su correo." request_new_verify_email: "Enviar otro correo:" - verify_email: "¡Gracias por crear una cuenta! Le enviamos un correo a la direcció\ - n que dio para confirmar su cuenta." + verify_email: "¡Gracias por crear una cuenta! Le enviamos un correo a la dirección que dio para confirmar su cuenta." verify_email2: "Debe confirmarla antes de poder involucrarse en la comunidad." not_you: "¿No eres tu?" logged_in_as: "Entraste como" @@ -358,8 +310,7 @@ es: passwords_dont_match: "Las contraseñas no coinciden." special_characters: "Los nombres pueden contener letras, números y _" sign_in_to_comment: "Entrar para comentar" - temporarily_suspended: "De acuerdo con la guía de la comunidad de {0}, su cuenta\ - \ ha sido temporalmente suspendida. Por favor unirse a la conversación {1}." + temporarily_suspended: "De acuerdo con la guía de la comunidad de {0}, su cuenta ha sido temporalmente suspendida. Por favor unirse a la conversación {1}." check_the_form: "Formulario Inválido. Por favor, completa los campos" step_1_header: "Reportar un problema" step_2_header: "Ayúdanos a comprender" @@ -368,8 +319,7 @@ es: all: Todos article: Artículo closed: Cerrado - empty_result: "Ningún articulo coincide con esta búsqueda. Intente expandir su\ - \ búsqueda." + empty_result: "Ningún articulo coincide con esta búsqueda. Intente expandir su búsqueda." filter_streams: "Filtrar Hilos" newest: Más nuevo oldest: Más antiguo @@ -383,35 +333,19 @@ es: bio: bio cancel: "Cancelar" days: "{0} días" - description_0: "¿Quiere suspender temporalmente a este usuario por su {0}? Hacerlo\ - \ va a ocultar temporalmente todos sus comentarios hasta que edite su {0}." - description_1: "Suspender a este usuario va a deshabilitar temporalmente su cuenta\ - \ y ocultar todos sus comentarios en el sitio." - description_notify: "Suspender a este usuario va a deshabilitar temporalmente\ - \ su cuenta y ocultar todos sus comentarios en el sitio." - description_reject: "¿Quiere suspender temporalmente a este usuario por su {0}?\ - \ Hacerlo va a ocultar temporalmente sus comentarios hasta que edite su {0}." - description_suspend: "Esta suspendiendo a {0}. Este comentario va a ir a la fila\ - \ de Rechazados, y a {0} no se le va a permitir gustar, marcar, responder o\ - \ publicar hasta que el tiempo de suspendido halla concluido." - email: "Otro miembro de la comunidad recientemente marco su nombre de usuario\ - \ para revisarlo. Por su contenido su nombre de usuario ha sido rechazado. Esto\ - \ significa que no puede comentar o marcar contenido hasta que edite su nombre\ - \ de usuario. Envíenos un correo si tiene preguntas o comentarios." + description_0: "¿Quiere suspender temporalmente a este usuario por su {0}? Hacerlo va a ocultar temporalmente todos sus comentarios hasta que edite su {0}." + description_1: "Suspender a este usuario va a deshabilitar temporalmente su cuenta y ocultar todos sus comentarios en el sitio." + description_notify: "Suspender a este usuario va a deshabilitar temporalmente su cuenta y ocultar todos sus comentarios en el sitio." + description_reject: "¿Quiere suspender temporalmente a este usuario por su {0}? Hacerlo va a ocultar temporalmente sus comentarios hasta que edite su {0}." + description_suspend: "Esta suspendiendo a {0}. Este comentario va a ir a la fila de Rechazados, y a {0} no se le va a permitir gustar, marcar, responder o publicar hasta que el tiempo de suspendido halla concluido." + email: "Otro miembro de la comunidad recientemente marco su nombre de usuario para revisarlo. Por su contenido su nombre de usuario ha sido rechazado. Esto significa que no puede comentar o marcar contenido hasta que edite su nombre de usuario. Envíenos un correo si tiene preguntas o comentarios." email_subject: "Su cuenta ha sido suspendida" - email_message_reject: "Otro miembro de la comunidad hace poco ha marcado su nombre\ - \ de usuario para revisar. Y este ha sido rechazado por su contenido. Esto significa\ - \ que no puede comentar, gustar o marcar contenido hasta que edite su nombre\ - \ de usuario. Envíenos un correo si tiene alguna preocupación o pregunta." - email_message_suspend: "Querida {0},\n\nDe acuerdo a la guía comunitaria de {1},\ - \ su cuenta ha sido temporalmente suspendida. Durante este tiempo, no podrá\ - \ comentar, marcar o involucrarse con otros comentaristas. Por favor unirse\ - \ a la conversación {2}." + email_message_reject: "Otro miembro de la comunidad hace poco ha marcado su nombre de usuario para revisar. Y este ha sido rechazado por su contenido. Esto significa que no puede comentar, gustar o marcar contenido hasta que edite su nombre de usuario. Envíenos un correo si tiene alguna preocupación o pregunta." + email_message_suspend: "Querida {0}, De acuerdo a la guía comunitaria de {1}, su cuenta ha sido temporalmente suspendida. Durante este tiempo, no podrá comentar, marcar o involucrarse con otros comentaristas. Por favor unirse a la conversación {2}." error_email_message_empty: "Debe especificar un mensaje de correo." hours: "{0} horas" no_cancel: "No cancelar" - notify_suspend_until: "Usuario {0} ha sido temporalmente suspendido. Esta suspension\ - \ va a terminar automáticamente en {1}." + notify_suspend_until: "Usuario {0} ha sido temporalmente suspendido. Esta suspension va a terminar automáticamente en {1}." one_hour: "1 hora" send: Enviar select_duration: "Seleccionar la duración de la suspensión" @@ -425,8 +359,7 @@ es: username: nombre de usuario write_message: "Escribir un mensaje" yes_suspend: "Si, suspender" - thank_you: "Valoramos tanto su seguridad en este espacio como sus comentarios. Un\ - \ o una moderadora va a leer su reporte." + thank_you: "Valoramos tanto su seguridad en este espacio como sus comentarios. Un o una moderadora va a leer su reporte." unset_best: "Des-etiquetar como el mejor" user: bio_flags: "reportes para este bio" @@ -441,8 +374,7 @@ es: DESCRIPTION: "Vamos a crear su comunidad Talk en unos pocos pasos." SUBMIT: "Empecemos" ADD_ORGANIZATION: - DESCRIPTION: "Por favor díganos el nombre de su organización. Esta aparecerá\ - \ en correos cuando se inviten a nuevos miembros del equipo." + DESCRIPTION: "Por favor díganos el nombre de su organización. Esta aparecerá en correos cuando se inviten a nuevos miembros del equipo." LABEL: "Nombre de la Organización" SAVE: "Guardar" CREATE: @@ -453,13 +385,9 @@ es: SAVE: "Guardar" PERMITTED_DOMAINS: TITLE: "Dominios permitidos" - DESCRIPTION: "Ingresar los dominios en donde estará Talk, por ejemplo sus ambientes\ - \ locales, de staging y producción (ej. localhost:3000, staging.domain.com,\ - \ domain.com)." + DESCRIPTION: "Ingresar los dominios en donde estará Talk, por ejemplo sus ambientes locales, de staging y producción (ej. localhost:3000, staging.domain.com, domain.com)." SUBMIT: "Terminar la Instalación" FINAL: - DESCRIPTION: "¡Gracias por instalar Talk! Enviamos un correo para verificar\ - \ su dirección de correo. Mientras esta terminando de configurar su cuenta,\ - \ ya puede comenzar a involucrarse con sus lectores." + DESCRIPTION: "¡Gracias por instalar Talk! Enviamos un correo para verificar su dirección de correo. Mientras esta terminando de configurar su cuenta, ya puede comenzar a involucrarse con sus lectores." LAUNCH: "Iniciar Talk" CLOSE: "Cerrar este instalador" diff --git a/package.json b/package.json index 05d6f873b..a2112bc85 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,8 @@ "subscriptions-transport-ws": "^0.5.5-alpha.0", "timekeeper": "^1.0.0", "uuid": "^3.0.1", - "yaml-loader": "^0.4.0" + "yaml-loader": "^0.4.0", + "yamljs": "^0.2.10" }, "devDependencies": { "apollo-client": "^1.0.4", diff --git a/routes/api/users/index.js b/routes/api/users/index.js index e7cc7d742..57532b1f9 100644 --- a/routes/api/users/index.js +++ b/routes/api/users/index.js @@ -109,12 +109,12 @@ const SendEmailConfirmation = (app, userID, email, referer) => UsersService .then((token) => { return mailer.sendSimple({ template: 'email-confirm', // needed to know which template to render! - locals: { // specifies the template locals. + locals: { // specifies the template locals. token, rootURL: ROOT_URL, email }, - subject: 'Email Confirmation', + subject: 'email.confirm.subject', to: email }); }); diff --git a/services/email/email-confirm.html.ejs b/services/email/email-confirm.html.ejs index dd2397edf..08a505521 100644 --- a/services/email/email-confirm.html.ejs +++ b/services/email/email-confirm.html.ejs @@ -1,3 +1,3 @@ -

A email confirmation has been requested for the following account: <%= email %>.

-

To confirm the account, please visit the following link: Confirm Email

-

If you did not request this, you can safely ignore this email.

+

<%= t('email.confirm.has_been_requested') %> <%= email %>.

+

<%= t('email.confirm.to_confirm') %> Confirm Email

+

<%= t('email.confirm.if_you_did_not') %>

diff --git a/services/email/email-confirm.txt.ejs b/services/email/email-confirm.txt.ejs index 4c7d7d312..6d3cb219c 100644 --- a/services/email/email-confirm.txt.ejs +++ b/services/email/email-confirm.txt.ejs @@ -1,9 +1,9 @@ -A email confirmation has been requested for the following account: +<%= t('email.confirm.has_been_requested') %> <%= email %> -To confirm the account, please visit the following link: +<%= t('email.confirm.to_confirm') %> <%= rootURL %>/confirm/endpoint#<%= token %> -If you did not request this, you can safely ignore this email. +<%= t('email.confirm.if_you_did_not') %> diff --git a/services/i18n.js b/services/i18n.js new file mode 100644 index 000000000..44eb51a0f --- /dev/null +++ b/services/i18n.js @@ -0,0 +1,50 @@ +const has = require('lodash/has'); +const get = require('lodash/get'); + +const yaml = require('yamljs'); +const es = yaml.load('./locales/es.yml'); +const en = yaml.load('./locales/en.yml'); + +// default language +const language = 'en'; +const translations = Object.assign(en, es); + +/** + * Exposes a service object to allow translations. + * @type {Object} + */ +const i18n = { + + /** + * Create the new Task kue. + */ + init() { + + // To Do - set language and retrieve it + return 'set it'; + }, + + /** + * Translates a key. + */ + t(key, ...replacements) { + + if (has(translations[language], key)) { + + let translation = get(translations, key); + + // replace any {n} with the arguments passed to this method + replacements.forEach((str, i) => { + translation = translation.replace(new RegExp(`\\{${i}\\}`, 'g'), str); + }); + + return translation; + } else { + console.warn(`${key} language key not set`); + return key; + } + }, + +}; + +module.exports = i18n; diff --git a/services/mailer.js b/services/mailer.js index 5d70fcf50..3b3c262cc 100644 --- a/services/mailer.js +++ b/services/mailer.js @@ -5,6 +5,8 @@ const path = require('path'); const fs = require('fs'); const _ = require('lodash'); +const i18n = require('./i18n'); + const { SMTP_HOST, SMTP_USERNAME, @@ -87,7 +89,9 @@ const mailer = module.exports = { } // Prefix the subject with `[Talk]`. - subject = `[Talk] ${subject}`; + subject = `[Talk] {t(${subject})}`; + + locals['t'] = i18n.t; return Promise.all([ diff --git a/yarn.lock b/yarn.lock index e1a5d1123..79ffe68b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8509,6 +8509,13 @@ yaml-loader@^0.4.0: dependencies: js-yaml "^3.5.2" +yamljs@^0.2.10: + version "0.2.10" + resolved "https://registry.yarnpkg.com/yamljs/-/yamljs-0.2.10.tgz#481cc7c25ca73af59f591f0c96e3ce56c757a40f" + dependencies: + argparse "^1.0.7" + glob "^7.0.5" + yargs-parser@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" From 555d54425a81f63c18aae56016434f97d2429cae Mon Sep 17 00:00:00 2001 From: Riley Davis Date: Thu, 1 Jun 2017 15:34:05 -0600 Subject: [PATCH 06/19] implement kiwi's pagination changes --- .../src/routes/Moderation/components/Comment.js | 10 +++++++--- .../routes/Moderation/components/UserDetail.js | 4 ++-- .../src/routes/Moderation/components/styles.css | 2 +- .../routes/Moderation/containers/UserDetail.js | 15 ++++++++++++++- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/client/coral-admin/src/routes/Moderation/components/Comment.js b/client/coral-admin/src/routes/Moderation/components/Comment.js index 46f6a40c8..f902848ec 100644 --- a/client/coral-admin/src/routes/Moderation/components/Comment.js +++ b/client/coral-admin/src/routes/Moderation/components/Comment.js @@ -56,9 +56,13 @@ const Comment = ({
- viewUserDetail(comment.user.id)}> - {comment.user.name} - + { + !minimal && ( + viewUserDetail(comment.user.id)}> + {comment.user.name} + + ) + } {timeago(comment.created_at || Date.now() - props.index * 60 * 1000)} diff --git a/client/coral-admin/src/routes/Moderation/components/UserDetail.js b/client/coral-admin/src/routes/Moderation/components/UserDetail.js index 2fe9730b9..d8587bd7b 100644 --- a/client/coral-admin/src/routes/Moderation/components/UserDetail.js +++ b/client/coral-admin/src/routes/Moderation/components/UserDetail.js @@ -34,7 +34,7 @@ export default class UserDetail extends React.Component { user, totalComments, rejectedComments, - comments + comments: {nodes} }, bannedWords, suspectWords, @@ -87,7 +87,7 @@ export default class UserDetail extends React.Component {
{ - comments.map((comment, i) => { + nodes.map((comment, i) => { const status = comment.action_summaries ? 'FLAGGED' : comment.status; return { return { From 686dc96c5fb8c341aa54acad7644365f7902d9f8 Mon Sep 17 00:00:00 2001 From: gaba Date: Thu, 1 Jun 2017 15:44:44 -0700 Subject: [PATCH 07/19] An attempt to guess language. In process. --- app.js | 3 +++ services/i18n.js | 26 ++++++++++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/app.js b/app.js index d0f0f316b..959aed0a3 100644 --- a/app.js +++ b/app.js @@ -6,6 +6,7 @@ const helmet = require('helmet'); const authentication = require('./middleware/authentication'); const {passport} = require('./services/passport'); const plugins = require('./services/plugins'); +const i18n = require('./services/i18n'); const enabled = require('debug').enabled; const errors = require('./errors'); const {createGraphOptions} = require('./graph'); @@ -157,6 +158,8 @@ app.use('/', (err, req, res, next) => { console.error(err); } + i18n.init(req); + if (err instanceof errors.APIError) { res.status(err.status); res.render('error', { diff --git a/services/i18n.js b/services/i18n.js index 44eb51a0f..897d234be 100644 --- a/services/i18n.js +++ b/services/i18n.js @@ -6,9 +6,26 @@ const es = yaml.load('./locales/es.yml'); const en = yaml.load('./locales/en.yml'); // default language -const language = 'en'; +let language = 'en'; const translations = Object.assign(en, es); +/** +* guess language setting based on http headers +*/ +const guessLanguage = (request) => { + + if (typeof request === 'object') { + language = 'en'; + + // console.log('debug 1', request.headers['accept-language']); + // console.log('debug 2', request.language); + // let languageHeader = request.headers? request.headers['accept-language'] : undefined; + + } + + return 'en'; +}; + /** * Exposes a service object to allow translations. * @type {Object} @@ -18,10 +35,8 @@ const i18n = { /** * Create the new Task kue. */ - init() { - - // To Do - set language and retrieve it - return 'set it'; + init(req) { + language = guessLanguage(req); }, /** @@ -44,7 +59,6 @@ const i18n = { return key; } }, - }; module.exports = i18n; From 27e6372fe208ee9672149756335e6d7150df7279 Mon Sep 17 00:00:00 2001 From: gaba Date: Thu, 1 Jun 2017 16:24:15 -0700 Subject: [PATCH 08/19] Get language from the header. --- services/i18n.js | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/services/i18n.js b/services/i18n.js index 897d234be..d302303ec 100644 --- a/services/i18n.js +++ b/services/i18n.js @@ -6,7 +6,8 @@ const es = yaml.load('./locales/es.yml'); const en = yaml.load('./locales/en.yml'); // default language -let language = 'en'; +let defaultLanguage = 'en'; +let language = defaultLanguage; const translations = Object.assign(en, es); /** @@ -15,15 +16,44 @@ const translations = Object.assign(en, es); const guessLanguage = (request) => { if (typeof request === 'object') { - language = 'en'; - - // console.log('debug 1', request.headers['accept-language']); - // console.log('debug 2', request.language); - // let languageHeader = request.headers? request.headers['accept-language'] : undefined; + let languageHeader = request.headers ? request.headers['accept-language'] : undefined; + const acceptedLanguages = getAcceptedLanguagesFromHeader(languageHeader); + + let lang; + for (let i = 0; i < acceptedLanguages.length; i++) { + lang = acceptedLanguages[i].split('-', 2)[0]; + } + return lang; } - return 'en'; + return defaultLanguage; +}; + +/** + * Get a sorted list of accepted languages from the HTTP Accept-Language header + */ +const getAcceptedLanguagesFromHeader = (header) => { + let languages = header.split(','); + let preferences = {}; + return languages.map((item) => { + let preferenceParts = item.trim().split(';q='); + if (preferenceParts.length < 2) { + preferenceParts[1] = 1.0; + } else { + let quality = parseFloat(preferenceParts[1]); + preferenceParts[1] = quality ? quality : 0.0; + } + preferences[preferenceParts[0]] = preferenceParts[1]; + + return preferenceParts[0]; + }) + .filter(function(lang) { + return preferences[lang] > 0; + }) + .sort(function sortLanguages(a, b) { + return preferences[b] - preferences[a]; + }); }; /** From dcbd0fc167b44d1c80b6bd2aa8f2971f11eb6896 Mon Sep 17 00:00:00 2001 From: gaba Date: Thu, 1 Jun 2017 17:13:55 -0700 Subject: [PATCH 09/19] Change signed in for logged in. --- plugins/coral-plugin-auth/client/components/UserBox.js | 2 +- plugins/coral-plugin-auth/client/components/styles.css | 4 ++++ plugins/coral-plugin-auth/client/translations.yml | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/plugins/coral-plugin-auth/client/components/UserBox.js b/plugins/coral-plugin-auth/client/components/UserBox.js index 91959a35b..47608c0e3 100644 --- a/plugins/coral-plugin-auth/client/components/UserBox.js +++ b/plugins/coral-plugin-auth/client/components/UserBox.js @@ -10,7 +10,7 @@ const UserBox = ({loggedIn, user, logout, onShowProfile}) => ( { loggedIn ? (
- {t('sign_in.logged_in_as')} + {t('sign_in.logged_in_as')} {user.username}. {t('sign_in.not_you')} logout()}> {t('sign_in.logout')} diff --git a/plugins/coral-plugin-auth/client/components/styles.css b/plugins/coral-plugin-auth/client/components/styles.css index d3cd47b87..c8fbf9a30 100644 --- a/plugins/coral-plugin-auth/client/components/styles.css +++ b/plugins/coral-plugin-auth/client/components/styles.css @@ -70,6 +70,10 @@ input.error{ letter-spacing: 0.1px; } +.userBoxLoggedIn { + font-weight: bold; +} + .userBox a { color: black; font-weight: bold; diff --git a/plugins/coral-plugin-auth/client/translations.yml b/plugins/coral-plugin-auth/client/translations.yml index 488f505d6..bc7f06759 100644 --- a/plugins/coral-plugin-auth/client/translations.yml +++ b/plugins/coral-plugin-auth/client/translations.yml @@ -5,10 +5,10 @@ en: verify_email: "Thank you for creating an account! We sent an email to the address you provided to verify your account." verify_email2: "You must verify your account before engaging with the community." not_you: "Not you?" - logged_in_as: "Logged in as" + logged_in_as: "Signed in as" facebook_sign_in: "Sign in with Facebook" facebook_sign_up: "Sign up with Facebook" - logout: "Logout" + logout: "Sign out" sign_in: "Sign in" sign_in_to_join: "Sign in to join the conversation" or: "Or" From fd1cf8121e465f52cc47a6188041a6e69da66931 Mon Sep 17 00:00:00 2001 From: gaba Date: Thu, 1 Jun 2017 17:21:55 -0700 Subject: [PATCH 10/19] Move start to the left. --- .../src/components/Comment.js | 18 +++++++++--------- locales/en.yml | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/client/coral-embed-stream/src/components/Comment.js b/client/coral-embed-stream/src/components/Comment.js index e3f0137b4..48392cc51 100644 --- a/client/coral-embed-stream/src/components/Comment.js +++ b/client/coral-embed-stream/src/components/Comment.js @@ -308,15 +308,6 @@ class Comment extends React.Component { commentId={comment.id} inline /> - {!disableReply && - - setActiveReplyBox(comment.id)} - parentCommentId={parentId || comment.id} - currentUserId={currentUser && currentUser.id} - banned={false} - /> - } + {!disableReply && + + setActiveReplyBox(comment.id)} + parentCommentId={parentId || comment.id} + currentUserId={currentUser && currentUser.id} + banned={false} + /> + }
{ users.length - ?

Because you ignored these, you do not see their comments.

+ ?

{t('framework.because_you_ignored')}

: null }
@@ -29,7 +29,7 @@ export class IgnoredUsers extends Component {
stopIgnoring({id})} - className={styles.link}>Stop ignoring + className={styles.link}>{t('framwork.stop_ignoring')}
)) diff --git a/locales/en.yml b/locales/en.yml index add0275f4..e8e3ba2e9 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -179,6 +179,7 @@ en: flag_username: "Report username" framework: banned_account_msg: "Your account is currently suspended. This means that you cannot Like Report or write comments. Please contact us if you have any questions." + because_you_ignored: "Because you ignored the following commenters, their comments are hidden." comment: comment comment_is_ignored: "This comment is hidden because you ignored this user." comments: comments @@ -195,6 +196,7 @@ en: new_count: "View {0} new {1}" profile: Profile show_all_comments: "Show all comments" + stop_ignoring: "Stop ignoring" success_bio_update: "Your biography has been updated" success_name_update: "Your username has been updated" success_update_settings: "The changes you have made have been applied to the comment stream on this article" diff --git a/locales/es.yml b/locales/es.yml index d658bcfcf..9e49d8d25 100644 --- a/locales/es.yml +++ b/locales/es.yml @@ -217,6 +217,7 @@ es: framework: banned_account_msg: "Tu cuenta se encuentra suspendida. Esto significa que no\ \ puedes gustar, marcar o escribir comentarios." + because_you_ignored: "Porque has ignorado a los siguientes comentadores, sus comentarios estan escondidos." comment: comentario comment_is_ignored: "Este comentario está escondido porque has ignorado al usuario." comments: comentarios @@ -235,6 +236,7 @@ es: new_count: "Ver {0} {1} nuevo" profile: Perfil show_all_comments: "Mostrar todos los comentarios" + stop_ignoring: "No ignorar más" success_bio_update: "Tu biografia fue actualizada" success_name_update: "Tu nombre de usuario ha sido actualizado" success_update_settings: "La configuración de este articulo fue actualizada" From eadbb03c15afacdfcdfaf1b12ba9f28d38fd7ec3 Mon Sep 17 00:00:00 2001 From: gaba Date: Fri, 2 Jun 2017 06:54:01 -0700 Subject: [PATCH 12/19] Fix typo. --- client/coral-settings/components/IgnoredUsers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/coral-settings/components/IgnoredUsers.js b/client/coral-settings/components/IgnoredUsers.js index fd00d2860..32e485e4c 100644 --- a/client/coral-settings/components/IgnoredUsers.js +++ b/client/coral-settings/components/IgnoredUsers.js @@ -29,7 +29,7 @@ export class IgnoredUsers extends Component {
stopIgnoring({id})} - className={styles.link}>{t('framwork.stop_ignoring')} + className={styles.link}>{t('framework.stop_ignoring')}
)) From b9b62e576438134f88dd4fc8c1c3206e2c83be4b Mon Sep 17 00:00:00 2001 From: gaba Date: Fri, 2 Jun 2017 08:24:21 -0700 Subject: [PATCH 13/19] Use accepts library. --- routes/api/users/index.js | 3 ++- services/i18n.js | 55 +++++---------------------------------- services/mailer.js | 3 ++- 3 files changed, 11 insertions(+), 50 deletions(-) diff --git a/routes/api/users/index.js b/routes/api/users/index.js index 57532b1f9..10d72fe3a 100644 --- a/routes/api/users/index.js +++ b/routes/api/users/index.js @@ -5,6 +5,7 @@ const CommentsService = require('../../../services/comments'); const mailer = require('../../../services/mailer'); const errors = require('../../../errors'); const authorization = require('../../../middleware/authorization'); +const i18n = require('../../../services/i18n'); const { ROOT_URL } = require('../../../config'); @@ -114,7 +115,7 @@ const SendEmailConfirmation = (app, userID, email, referer) => UsersService rootURL: ROOT_URL, email }, - subject: 'email.confirm.subject', + subject: i18n.t('email.confirm.subject'), to: email }); }); diff --git a/services/i18n.js b/services/i18n.js index d302303ec..eff827cac 100644 --- a/services/i18n.js +++ b/services/i18n.js @@ -5,57 +5,15 @@ const yaml = require('yamljs'); const es = yaml.load('./locales/es.yml'); const en = yaml.load('./locales/en.yml'); +const accepts = require('accepts'); + // default language let defaultLanguage = 'en'; let language = defaultLanguage; +const languages = ['en', 'es']; + const translations = Object.assign(en, es); -/** -* guess language setting based on http headers -*/ -const guessLanguage = (request) => { - - if (typeof request === 'object') { - - let languageHeader = request.headers ? request.headers['accept-language'] : undefined; - const acceptedLanguages = getAcceptedLanguagesFromHeader(languageHeader); - - let lang; - for (let i = 0; i < acceptedLanguages.length; i++) { - lang = acceptedLanguages[i].split('-', 2)[0]; - } - return lang; - } - - return defaultLanguage; -}; - -/** - * Get a sorted list of accepted languages from the HTTP Accept-Language header - */ -const getAcceptedLanguagesFromHeader = (header) => { - let languages = header.split(','); - let preferences = {}; - return languages.map((item) => { - let preferenceParts = item.trim().split(';q='); - if (preferenceParts.length < 2) { - preferenceParts[1] = 1.0; - } else { - let quality = parseFloat(preferenceParts[1]); - preferenceParts[1] = quality ? quality : 0.0; - } - preferences[preferenceParts[0]] = preferenceParts[1]; - - return preferenceParts[0]; - }) - .filter(function(lang) { - return preferences[lang] > 0; - }) - .sort(function sortLanguages(a, b) { - return preferences[b] - preferences[a]; - }); -}; - /** * Exposes a service object to allow translations. * @type {Object} @@ -66,7 +24,8 @@ const i18n = { * Create the new Task kue. */ init(req) { - language = guessLanguage(req); + const lang = accepts(req).language(languages); + language = lang ? lang : defaultLanguage; }, /** @@ -76,7 +35,7 @@ const i18n = { if (has(translations[language], key)) { - let translation = get(translations, key); + let translation = get(translations[language], key); // replace any {n} with the arguments passed to this method replacements.forEach((str, i) => { diff --git a/services/mailer.js b/services/mailer.js index 3b3c262cc..27672a35c 100644 --- a/services/mailer.js +++ b/services/mailer.js @@ -80,6 +80,7 @@ const mailer = module.exports = { }), sendSimple({template, locals, to, subject}) { + if (!to) { return Promise.reject('sendSimple requires a comma-separated list of "to" addresses'); } @@ -89,7 +90,7 @@ const mailer = module.exports = { } // Prefix the subject with `[Talk]`. - subject = `[Talk] {t(${subject})}`; + subject = `[Talk] ${subject}`; locals['t'] = i18n.t; From cf50a0e85c820106758300233a736450a872bc79 Mon Sep 17 00:00:00 2001 From: gaba Date: Fri, 2 Jun 2017 08:30:36 -0700 Subject: [PATCH 14/19] Translations missing. --- locales/es.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/locales/es.yml b/locales/es.yml index 33993a914..7ac1e6ad5 100644 --- a/locales/es.yml +++ b/locales/es.yml @@ -159,6 +159,13 @@ es: second: "segundo" seconds_plural: "segundos" unexpected_error: "Lo siento. Ha habido un error no previsto al guardar los cambios." + email: + confirm: + has_been_requested: "Un correo de confirmación ha sido pedido para la siguiente cuenta:" + to_confirm: "Para confirmar la cuenta, por favor visitar el siguiente enlace:" + confirm_email: "Confirmar Correo" + if_you_did_not: "Si no has pedido esto, puedes ignorar el correo." + subject: "Confirmación de Correo" embedlink: copy: "Copiar al portapapeles" error: From d8cb560755db1eb396194bd3d39acfbdfb2f9527 Mon Sep 17 00:00:00 2001 From: Riley Davis Date: Fri, 2 Jun 2017 13:02:22 -0600 Subject: [PATCH 15/19] add a tab for All/Rejected user detail comments --- client/coral-admin/src/actions/moderation.js | 9 ++++++++ .../src/components/ModerationList.css | 2 +- .../coral-admin/src/constants/moderation.js | 1 + client/coral-admin/src/reducers/moderation.js | 6 +++++ .../Moderation/components/UserDetail.css | 17 ++++++++++++++ .../Moderation/components/UserDetail.js | 13 +++++++++++ .../Moderation/containers/UserDetail.js | 22 ++++++++++++++----- 7 files changed, 64 insertions(+), 6 deletions(-) diff --git a/client/coral-admin/src/actions/moderation.js b/client/coral-admin/src/actions/moderation.js index 4b0b0538a..3f8d975df 100644 --- a/client/coral-admin/src/actions/moderation.js +++ b/client/coral-admin/src/actions/moderation.js @@ -33,3 +33,12 @@ export const setSortOrder = (order) => ({ order }); +export const changeUserDetailStatuses = (tab) => { + let statuses; + if (tab === 'all') { + statuses = ['NONE', 'ACCEPTED', 'REJECTED', 'PREMOD']; + } else if (tab === 'rejected') { + statuses = ['REJECTED']; + } + return {type: actions.CHANGE_USER_DETAIL_STATUSES, tab, statuses}; +}; diff --git a/client/coral-admin/src/components/ModerationList.css b/client/coral-admin/src/components/ModerationList.css index 99927e7ad..2b5989191 100644 --- a/client/coral-admin/src/components/ModerationList.css +++ b/client/coral-admin/src/components/ModerationList.css @@ -192,7 +192,7 @@ .minimal { width: 45px; min-width: 0; - float: right; + float: left; } .approve__active { diff --git a/client/coral-admin/src/constants/moderation.js b/client/coral-admin/src/constants/moderation.js index 3586b1a75..aa8a51a24 100644 --- a/client/coral-admin/src/constants/moderation.js +++ b/client/coral-admin/src/constants/moderation.js @@ -8,3 +8,4 @@ export const HIDE_SUSPEND_USER_DIALOG = 'HIDE_SUSPEND_USER_DIALOG'; export const VIEW_USER_DETAIL = 'VIEW_USER_DETAIL'; export const HIDE_USER_DETAIL = 'HIDE_USER_DETAIL'; export const SET_SORT_ORDER = 'MODERATION_SET_SORT_ORDER'; +export const CHANGE_USER_DETAIL_STATUSES = 'CHANGE_USER_DETAIL_STATUSES'; diff --git a/client/coral-admin/src/reducers/moderation.js b/client/coral-admin/src/reducers/moderation.js index 10cbe0eca..4201ffb06 100644 --- a/client/coral-admin/src/reducers/moderation.js +++ b/client/coral-admin/src/reducers/moderation.js @@ -8,6 +8,8 @@ const initialState = fromJS({ commentId: null, commentStatus: null, userDetailId: null, + userDetailActiveTab: 'all', + userDetailStatuses: ['NONE', 'ACCEPTED', 'REJECTED', 'PREMOD'], banDialog: false, shortcutsNoteVisible: window.localStorage.getItem('coral:shortcutsNote') || 'show', sortOrder: 'REVERSE_CHRONOLOGICAL', @@ -65,6 +67,10 @@ export default function moderation (state = initialState, action) { return state.set('userDetailId', action.userId); case actions.HIDE_USER_DETAIL: return state.set('userDetailId', null); + case actions.CHANGE_USER_DETAIL_STATUSES: + return state + .set('userDetailActiveTab', action.tab) + .set('userDetailStatuses', action.statuses); case actions.SET_SORT_ORDER: return state.set('sortOrder', action.order); default : diff --git a/client/coral-admin/src/routes/Moderation/components/UserDetail.css b/client/coral-admin/src/routes/Moderation/components/UserDetail.css index 7c84f62fa..1119be8c4 100644 --- a/client/coral-admin/src/routes/Moderation/components/UserDetail.css +++ b/client/coral-admin/src/routes/Moderation/components/UserDetail.css @@ -39,3 +39,20 @@ width: 90%; outline: none; } + +.commentStatuses { + padding: 0; + list-style: none; + + li { + display: inline-block; + margin: 0 10px; + cursor: pointer; + padding: 0 10px; + } +} + +.active { + font-weight: bold; + border-bottom: 3px solid #F36451; +} diff --git a/client/coral-admin/src/routes/Moderation/components/UserDetail.js b/client/coral-admin/src/routes/Moderation/components/UserDetail.js index d8587bd7b..c461220c8 100644 --- a/client/coral-admin/src/routes/Moderation/components/UserDetail.js +++ b/client/coral-admin/src/routes/Moderation/components/UserDetail.js @@ -28,6 +28,14 @@ export default class UserDetail extends React.Component { } } + changeStatus = (tab) => { + if (tab === 'all') { + this.props.changeStatus('all'); + } else if (tab === 'rejected') { + this.props.changeStatus('rejected'); + } + } + render () { const { root: { @@ -36,6 +44,7 @@ export default class UserDetail extends React.Component { rejectedComments, comments: {nodes} }, + moderation: {userDetailActiveTab: tab}, bannedWords, suspectWords, showBanUserDialog, @@ -85,6 +94,10 @@ export default class UserDetail extends React.Component {

{`${(rejectedPercent).toFixed(1)}%`}

+
    +
  • All
  • +
  • Rejected
  • +
{ nodes.map((comment, i) => { diff --git a/client/coral-admin/src/routes/Moderation/containers/UserDetail.js b/client/coral-admin/src/routes/Moderation/containers/UserDetail.js index d28d35481..9afd10efb 100644 --- a/client/coral-admin/src/routes/Moderation/containers/UserDetail.js +++ b/client/coral-admin/src/routes/Moderation/containers/UserDetail.js @@ -1,9 +1,12 @@ import React, {PropTypes} from 'react'; import {compose, gql} from 'react-apollo'; +import {connect} from 'react-redux'; +import {bindActionCreators} from 'redux'; import UserDetail from '../components/UserDetail'; import withQuery from 'coral-framework/hocs/withQuery'; import {getSlotsFragments} from 'coral-framework/helpers/plugins'; import {getDefinitionName} from 'coral-framework/utils'; +import {changeUserDetailStatuses} from 'coral-admin/src/actions/moderation'; import Comment from './Comment'; const commentConnectionFragment = gql` @@ -33,12 +36,12 @@ class UserDetailContainer extends React.Component { return null; } - return ; + return ; } } export const withUserDetailQuery = withQuery(gql` - query CoralAdmin_UserDetail($author_id: ID!) { + query CoralAdmin_UserDetail($author_id: ID!, $statuses: [COMMENT_STATUS!]) { user(id: $author_id) { id username @@ -53,7 +56,7 @@ export const withUserDetailQuery = withQuery(gql` rejectedComments: commentCount(query: {author_id: $author_id, statuses: [REJECTED]}) comments: comments(query: { author_id: $author_id, - statuses: [NONE, PREMOD, ACCEPTED, REJECTED] + statuses: $statuses }) { ...CoralAdmin_Moderation_CommentConnection } @@ -64,13 +67,22 @@ export const withUserDetailQuery = withQuery(gql` ${pluginFragments.definitions('root')} ${commentConnectionFragment} `, { - options: ({id}) => { + options: ({id, moderation: {userDetailStatuses: statuses}}) => { return { - variables: {author_id: id} + variables: {author_id: id, statuses} }; } }); +const mapStateToProps = (state) => ({ + moderation: state.moderation.toJS() +}); + +const mapDispatchToProps = (dispatch) => ({ + ...bindActionCreators({changeUserDetailStatuses}, dispatch) +}); + export default compose( + connect(mapStateToProps, mapDispatchToProps), withUserDetailQuery, )(UserDetailContainer); From 22c2843ae59a1f5ecddc771722b91cd092df9131 Mon Sep 17 00:00:00 2001 From: Riley Davis Date: Fri, 2 Jun 2017 13:12:59 -0600 Subject: [PATCH 16/19] remove moderate link per designs --- client/coral-admin/src/routes/Moderation/components/Comment.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/coral-admin/src/routes/Moderation/components/Comment.js b/client/coral-admin/src/routes/Moderation/components/Comment.js index f902848ec..d8275975a 100644 --- a/client/coral-admin/src/routes/Moderation/components/Comment.js +++ b/client/coral-admin/src/routes/Moderation/components/Comment.js @@ -96,7 +96,7 @@ const Comment = ({
Story: {comment.asset.title} - {!props.currentAsset && + {!props.currentAsset && !minimal && {t('modqueue.moderate')}}
From e097b8eb21c2f8e74d82e795b6706c7497a08dcb Mon Sep 17 00:00:00 2001 From: Riley Davis Date: Fri, 2 Jun 2017 13:50:00 -0600 Subject: [PATCH 17/19] design pass --- .../src/routes/Moderation/components/Comment.js | 16 +++++++--------- .../src/routes/Moderation/components/styles.css | 5 ++--- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/client/coral-admin/src/routes/Moderation/components/Comment.js b/client/coral-admin/src/routes/Moderation/components/Comment.js index d8275975a..1bc2b50d7 100644 --- a/client/coral-admin/src/routes/Moderation/components/Comment.js +++ b/client/coral-admin/src/routes/Moderation/components/Comment.js @@ -96,7 +96,7 @@ const Comment = ({
Story: {comment.asset.title} - {!props.currentAsset && !minimal && + {!props.currentAsset && {t('modqueue.moderate')}}
@@ -160,14 +160,12 @@ const Comment = ({
-
- -
+ {flagActions && flagActions.length ? Date: Fri, 2 Jun 2017 13:49:17 -0700 Subject: [PATCH 18/19] Some translations missing and a folder that should not be there. --- locales/en.yml | 4 ++++ locales/es.yml | 4 ++++ services/email/password-reset.html.ejs | 4 ++-- services/email/password-reset.txt.ejs | 4 +--- services/templates/email_confirm/es/html.ejs | 3 --- services/templates/email_confirm/es/text.ejs | 9 --------- services/templates/email_confirm/html.ejs | 3 --- services/templates/email_confirm/text.ejs | 9 --------- services/templates/notification/es/html.ejs | 1 - services/templates/notification/es/text.ejs | 1 - services/templates/notification/html.ejs | 1 - services/templates/notification/text.ejs | 1 - services/templates/password-reset/es/html.ejs | 2 -- services/templates/password-reset/es/text.ejs | 5 ----- services/templates/password-reset/html.ejs | 2 -- services/templates/password-reset/text.ejs | 5 ----- services/templates/suspension/es/html.ejs | 1 - services/templates/suspension/es/text.ejs | 1 - services/templates/suspension/html.ejs | 1 - services/templates/suspension/text.ejs | 1 - 20 files changed, 11 insertions(+), 51 deletions(-) delete mode 100644 services/templates/email_confirm/es/html.ejs delete mode 100644 services/templates/email_confirm/es/text.ejs delete mode 100644 services/templates/email_confirm/html.ejs delete mode 100644 services/templates/email_confirm/text.ejs delete mode 100644 services/templates/notification/es/html.ejs delete mode 100644 services/templates/notification/es/text.ejs delete mode 100644 services/templates/notification/html.ejs delete mode 100644 services/templates/notification/text.ejs delete mode 100644 services/templates/password-reset/es/html.ejs delete mode 100644 services/templates/password-reset/es/text.ejs delete mode 100644 services/templates/password-reset/html.ejs delete mode 100644 services/templates/password-reset/text.ejs delete mode 100644 services/templates/suspension/es/html.ejs delete mode 100644 services/templates/suspension/es/text.ejs delete mode 100644 services/templates/suspension/html.ejs delete mode 100644 services/templates/suspension/text.ejs diff --git a/locales/en.yml b/locales/en.yml index 5ff20f033..c99192ed5 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -167,6 +167,10 @@ en: confirm_email: "Confirm Email" if_you_did_not: "If you did not request this, you can safely ignore this email." subject: "Email Confirmation" + password_reset: + we_received_a_request: "We received a request to reset your password. If you did not request this change, you can ignore this email." + if_you_did: "If you did," + please_click: "please click here to reset password" embedlink: copy: "Copy to Clipboard" error: diff --git a/locales/es.yml b/locales/es.yml index 1f57c4861..9e7a8bcba 100644 --- a/locales/es.yml +++ b/locales/es.yml @@ -166,6 +166,10 @@ es: confirm_email: "Confirmar Correo" if_you_did_not: "Si no has pedido esto, puedes ignorar el correo." subject: "Confirmación de Correo" + password_reset: + we_received_a_request: "Recibimos un pedido para resetear su contraseña. Si no ha pedido ese cambio, por favor ignorar el correo. " + if_you_did: "Si lo hizo," + please_click: "por favor cliquea aqui para resetear la contraseña." embedlink: copy: "Copiar al portapapeles" error: diff --git a/services/email/password-reset.html.ejs b/services/email/password-reset.html.ejs index e478ceeba..258f0d079 100644 --- a/services/email/password-reset.html.ejs +++ b/services/email/password-reset.html.ejs @@ -1,2 +1,2 @@ -

We received a request to reset your password. If you did not request this change, you can ignore this email.
-If you did, please click here to reset password.

+

<%= t('email.password_reset.we_received_a_request') %>
+<%= t('email.password_reset.if_you_did') %> <%= t('email.password_reset.please_click') %>.

diff --git a/services/email/password-reset.txt.ejs b/services/email/password-reset.txt.ejs index 1e44a6629..a8387925d 100644 --- a/services/email/password-reset.txt.ejs +++ b/services/email/password-reset.txt.ejs @@ -1,5 +1,3 @@ -We received a request to reset your password, click here to reset your password: +<%= t('email.password_reset.we_received_a_request') %>. <%= t('email.password_reset.if_you_did') %> <%= t('email.password_reset.please_click') %>: <%= rootURL %>/admin/password-reset#<%= token %> - -If you did not request this change, you can ignore this email. diff --git a/services/templates/email_confirm/es/html.ejs b/services/templates/email_confirm/es/html.ejs deleted file mode 100644 index 1da7a1e9d..000000000 --- a/services/templates/email_confirm/es/html.ejs +++ /dev/null @@ -1,3 +0,0 @@ -

Un correo de confirmación ha sido pedido para esta cuenta: <%= email %>.

-

To confirm the account, please visit the following link: Confirm Email

-

If you did not request this, you can safely ignore this email.

diff --git a/services/templates/email_confirm/es/text.ejs b/services/templates/email_confirm/es/text.ejs deleted file mode 100644 index 4c7d7d312..000000000 --- a/services/templates/email_confirm/es/text.ejs +++ /dev/null @@ -1,9 +0,0 @@ -A email confirmation has been requested for the following account: - - <%= email %> - -To confirm the account, please visit the following link: - - <%= rootURL %>/confirm/endpoint#<%= token %> - -If you did not request this, you can safely ignore this email. diff --git a/services/templates/email_confirm/html.ejs b/services/templates/email_confirm/html.ejs deleted file mode 100644 index dd2397edf..000000000 --- a/services/templates/email_confirm/html.ejs +++ /dev/null @@ -1,3 +0,0 @@ -

A email confirmation has been requested for the following account: <%= email %>.

-

To confirm the account, please visit the following link: Confirm Email

-

If you did not request this, you can safely ignore this email.

diff --git a/services/templates/email_confirm/text.ejs b/services/templates/email_confirm/text.ejs deleted file mode 100644 index 4c7d7d312..000000000 --- a/services/templates/email_confirm/text.ejs +++ /dev/null @@ -1,9 +0,0 @@ -A email confirmation has been requested for the following account: - - <%= email %> - -To confirm the account, please visit the following link: - - <%= rootURL %>/confirm/endpoint#<%= token %> - -If you did not request this, you can safely ignore this email. diff --git a/services/templates/notification/es/html.ejs b/services/templates/notification/es/html.ejs deleted file mode 100644 index b36560ec5..000000000 --- a/services/templates/notification/es/html.ejs +++ /dev/null @@ -1 +0,0 @@ -<%= body %> diff --git a/services/templates/notification/es/text.ejs b/services/templates/notification/es/text.ejs deleted file mode 100644 index b36560ec5..000000000 --- a/services/templates/notification/es/text.ejs +++ /dev/null @@ -1 +0,0 @@ -<%= body %> diff --git a/services/templates/notification/html.ejs b/services/templates/notification/html.ejs deleted file mode 100644 index b36560ec5..000000000 --- a/services/templates/notification/html.ejs +++ /dev/null @@ -1 +0,0 @@ -<%= body %> diff --git a/services/templates/notification/text.ejs b/services/templates/notification/text.ejs deleted file mode 100644 index b36560ec5..000000000 --- a/services/templates/notification/text.ejs +++ /dev/null @@ -1 +0,0 @@ -<%= body %> diff --git a/services/templates/password-reset/es/html.ejs b/services/templates/password-reset/es/html.ejs deleted file mode 100644 index e478ceeba..000000000 --- a/services/templates/password-reset/es/html.ejs +++ /dev/null @@ -1,2 +0,0 @@ -

We received a request to reset your password. If you did not request this change, you can ignore this email.
-If you did, please click here to reset password.

diff --git a/services/templates/password-reset/es/text.ejs b/services/templates/password-reset/es/text.ejs deleted file mode 100644 index 1e44a6629..000000000 --- a/services/templates/password-reset/es/text.ejs +++ /dev/null @@ -1,5 +0,0 @@ -We received a request to reset your password, click here to reset your password: - -<%= rootURL %>/admin/password-reset#<%= token %> - -If you did not request this change, you can ignore this email. diff --git a/services/templates/password-reset/html.ejs b/services/templates/password-reset/html.ejs deleted file mode 100644 index e478ceeba..000000000 --- a/services/templates/password-reset/html.ejs +++ /dev/null @@ -1,2 +0,0 @@ -

We received a request to reset your password. If you did not request this change, you can ignore this email.
-If you did, please click here to reset password.

diff --git a/services/templates/password-reset/text.ejs b/services/templates/password-reset/text.ejs deleted file mode 100644 index 1e44a6629..000000000 --- a/services/templates/password-reset/text.ejs +++ /dev/null @@ -1,5 +0,0 @@ -We received a request to reset your password, click here to reset your password: - -<%= rootURL %>/admin/password-reset#<%= token %> - -If you did not request this change, you can ignore this email. diff --git a/services/templates/suspension/es/html.ejs b/services/templates/suspension/es/html.ejs deleted file mode 100644 index 4fd8f191c..000000000 --- a/services/templates/suspension/es/html.ejs +++ /dev/null @@ -1 +0,0 @@ -<%= body.replace(/\n/g, '
') %> diff --git a/services/templates/suspension/es/text.ejs b/services/templates/suspension/es/text.ejs deleted file mode 100644 index b36560ec5..000000000 --- a/services/templates/suspension/es/text.ejs +++ /dev/null @@ -1 +0,0 @@ -<%= body %> diff --git a/services/templates/suspension/html.ejs b/services/templates/suspension/html.ejs deleted file mode 100644 index 4fd8f191c..000000000 --- a/services/templates/suspension/html.ejs +++ /dev/null @@ -1 +0,0 @@ -<%= body.replace(/\n/g, '
') %> diff --git a/services/templates/suspension/text.ejs b/services/templates/suspension/text.ejs deleted file mode 100644 index b36560ec5..000000000 --- a/services/templates/suspension/text.ejs +++ /dev/null @@ -1 +0,0 @@ -<%= body %> From 6de9c696688fd60c9f80b701add65cd8a1d5ab67 Mon Sep 17 00:00:00 2001 From: gaba Date: Fri, 2 Jun 2017 14:02:45 -0700 Subject: [PATCH 19/19] Missing key translation. --- plugins/coral-plugin-auth/client/components/SignInButton.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/coral-plugin-auth/client/components/SignInButton.js b/plugins/coral-plugin-auth/client/components/SignInButton.js index 881233c83..1789a6496 100644 --- a/plugins/coral-plugin-auth/client/components/SignInButton.js +++ b/plugins/coral-plugin-auth/client/components/SignInButton.js @@ -3,12 +3,13 @@ import {Button} from 'coral-ui'; import {connect} from 'react-redux'; import {bindActionCreators} from 'redux'; import {showSignInDialog} from 'coral-framework/actions/auth'; +import t from 'coral-framework/services/i18n'; const SignInButton = ({loggedIn, showSignInDialog}) => (
{!loggedIn ? : null}