Move i18n into a service

This commit is contained in:
gaba
2017-05-17 12:53:36 -07:00
parent 35c941d4d0
commit 5bd9bc992b
99 changed files with 1151 additions and 2013 deletions
@@ -2,9 +2,8 @@ import React, {PropTypes} from 'react';
import Layout from 'coral-admin/src/components/ui/Layout';
import styles from './NotFound.css';
import {Button, TextField, Alert, Success} from 'coral-ui';
import I18n from 'coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
import Recaptcha from 'react-recaptcha';
const lang = new I18n();
class AdminLogin extends React.Component {
@@ -36,7 +35,7 @@ class AdminLogin extends React.Component {
const {errorMessage, loginMaxExceeded, recaptchaPublic} = this.props;
const signInForm = (
<form onSubmit={this.handleSignIn}>
{errorMessage && <Alert>{lang.t(`errors.${errorMessage}`)}</Alert>}
{errorMessage && <Alert>{t(`errors.${errorMessage}`)}</Alert>}
<TextField
label='Email Address'
value={this.state.email}
@@ -2,8 +2,7 @@ import React, {PropTypes} from 'react';
import {Button, Icon} from 'coral-ui';
import styles from './BanUserButton.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const BanUserButton = ({user, ...props}) => (
<div className={styles.ban}>
@@ -13,7 +12,7 @@ const BanUserButton = ({user, ...props}) => (
onClick={props.onClick}
raised>
<Icon name='not_interested' />
{lang.t('comment.ban_user')}
{t('comment.ban_user')}
</Button>
</div>
);
@@ -4,8 +4,7 @@ import styles from './BanUserDialog.css';
import Button from 'coral-ui/components/Button';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const onBanClick = (userId, commentId, commentStatus, handleBanUser, rejectComment, handleClose) => (e) => {
e.preventDefault();
@@ -21,22 +20,22 @@ const BanUserDialog = ({open, handleClose, handleBanUser, rejectComment, user, c
open={open}
onClose={handleClose}
onCancel={handleClose}
title={lang.t('bandialog.ban_user')}>
title={t('bandialog.ban_user')}>
<span className={styles.close} onClick={handleClose}>×</span>
<div>
<div className={styles.header}>
<h2>{lang.t('bandialog.ban_user')}</h2>
<h2>{t('bandialog.ban_user')}</h2>
</div>
<div className={styles.separator}>
<h3>{lang.t('bandialog.are_you_sure', user.name)}</h3>
<i>{showRejectedNote && lang.t('bandialog.note')}</i>
<h3>{t('bandialog.are_you_sure', user.name)}</h3>
<i>{showRejectedNote && t('bandialog.note')}</i>
</div>
<div className={styles.buttons}>
<Button cStyle="cancel" className={styles.cancel} onClick={handleClose} raised>
{lang.t('bandialog.cancel')}
{t('bandialog.cancel')}
</Button>
<Button cStyle="black" className={styles.ban} onClick={onBanClick(user.id, commentId, commentStatus, handleBanUser, rejectComment, handleClose)} raised>
{lang.t('bandialog.yes_ban_user')}
{t('bandialog.yes_ban_user')}
</Button>
</div>
</div>
@@ -1,9 +1,8 @@
import React, {PropTypes} from 'react';
import I18n from 'coral-i18n/modules/i18n/i18n';
import styles from 'coral-admin/src/containers/Dashboard/Dashboard.css';
import {Icon} from 'coral-ui';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const refreshIntervalSeconds = 60 * 5;
class CountdownTimer extends React.Component {
@@ -73,7 +72,7 @@ class CountdownTimer extends React.Component {
className={styles.autoUpdate}
onClick={this.dismissNote}>
<b>×</b>
<Icon name='timer' /> <strong>{lang.t('dashboard.next_update', this.formatTime())}</strong> {lang.t('dashboard.auto_update')}
<Icon name='timer' /> <strong>{t('dashboard.next_update', this.formatTime())}</strong> {t('dashboard.auto_update')}
</p>
);
}
@@ -1,9 +1,7 @@
import I18n from 'coral-i18n/modules/i18n/i18n';
import React, {PropTypes} from 'react';
import Modal from 'components/Modal';
import styles from './ModerationKeysModal.css';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const shortcuts = [
{
@@ -39,29 +37,29 @@ export default class ModerationKeysModal extends React.Component {
<div>
<div className={styles.callToAction} style={{display: shortcutsNoteVisible === 'show' ? 'block' : 'none'}}>
<div onClick={hideShortcutsNote} className={styles.closeButton}>×</div>
<p className={styles.ctaHeader}>{lang.t('modqueue.mod_faster')}</p>
<p><strong>{lang.t('modqueue.try_these')}:</strong></p>
<p className={styles.ctaHeader}>{t('modqueue.mod_faster')}</p>
<p><strong>{t('modqueue.try_these')}:</strong></p>
<ul>
<li><span>{lang.t('modqueue.approve')}</span> <span className={styles.smallKey}>t</span></li>
<li><span>{lang.t('modqueue.reject')}</span> <span className={styles.smallKey}>r</span></li>
<li><span>{t('modqueue.approve')}</span> <span className={styles.smallKey}>t</span></li>
<li><span>{t('modqueue.reject')}</span> <span className={styles.smallKey}>r</span></li>
</ul>
<p><span>{lang.t('modqueue.view_more_shortcuts')}</span> <span className={styles.smallKey}>{lang.t('modqueue.shift_key')}</span> + <span className={styles.smallKey}>/</span></p>
<p><span>{t('modqueue.view_more_shortcuts')}</span> <span className={styles.smallKey}>{t('modqueue.shift_key')}</span> + <span className={styles.smallKey}>/</span></p>
</div>
<Modal open={open} onClose={onClose}>
<h3>{lang.t('modqueue.shortcuts')}</h3>
<h3>{t('modqueue.shortcuts')}</h3>
<div className={styles.container}>
{shortcuts.map((shortcut, i) => (
<table className={styles.table} key={i}>
<thead>
<tr>
<th>{lang.t(shortcut.title)}</th>
<th>{t(shortcut.title)}</th>
</tr>
</thead>
<tbody>
{Object.keys(shortcut.shortcuts).map((key) => (
<tr key={`${key}tr`}>
<td className={styles.shortcut}><span className={styles.key}>{key}</span></td>
<td>{lang.t(shortcut.shortcuts[key])}</td>
<td>{t(shortcut.shortcuts[key])}</td>
</tr>
))}
</tbody>
@@ -2,7 +2,7 @@ import React, {PropTypes} from 'react';
import {Navigation, Drawer} from 'react-mdl';
import {IndexLink, Link} from 'react-router';
import styles from './Drawer.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
const CoralDrawer = ({handleLogout, restricted = false}) => (
<Drawer className={styles.header}>
@@ -13,29 +13,29 @@ const CoralDrawer = ({handleLogout, restricted = false}) => (
className={styles.navLink}
to="/admin/dashboard"
activeClassName={styles.active}>
{lang.t('configure.dashboard')}
{t('configure.dashboard')}
</IndexLink>
<Link
className={styles.navLink}
to="/admin/moderate"
activeClassName={styles.active}>
{lang.t('configure.moderate')}
{t('configure.moderate')}
</Link>
<Link className={styles.navLink}
to="/admin/stories"
activeClassName={styles.active}>
{lang.t('configure.stories')}
{t('configure.stories')}
</Link>
<Link className={styles.navLink}
to="/admin/community"
activeClassName={styles.active}>
{lang.t('configure.community')}
{t('configure.community')}
</Link>
<Link
className={styles.navLink}
to="/admin/configure"
activeClassName={styles.active}>
{lang.t('configure.configure')}
{t('configure.configure')}
</Link>
<a onClick={handleLogout}>Sign Out</a>
<span>{`v${process.env.VERSION}`}</span>
@@ -49,6 +49,4 @@ CoralDrawer.propTypes = {
restricted: PropTypes.bool // hide app elements from a logged out user
};
const lang = new I18n();
export default CoralDrawer;
+8 -10
View File
@@ -2,7 +2,7 @@ import React, {PropTypes} from 'react';
import {Navigation, Header, IconButton, MenuItem, Menu} from 'react-mdl';
import {Link, IndexLink} from 'react-router';
import styles from './Header.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
import {Logo} from './Logo';
const CoralHeader = ({handleLogout, showShortcuts = () => {}, restricted = false}) => (
@@ -17,35 +17,35 @@ const CoralHeader = ({handleLogout, showShortcuts = () => {}, restricted = false
className={styles.navLink}
to="/admin/dashboard"
activeClassName={styles.active}>
{lang.t('configure.dashboard')}
{t('configure.dashboard')}
</IndexLink>
<Link
id='moderateNav'
className={styles.navLink}
to="/admin/moderate"
activeClassName={styles.active}>
{lang.t('configure.moderate')}
{t('configure.moderate')}
</Link>
<Link
id='streamsNav'
className={styles.navLink}
to="/admin/stories"
activeClassName={styles.active}>
{lang.t('configure.stories')}
{t('configure.stories')}
</Link>
<Link
id='communityNav'
className={styles.navLink}
to="/admin/community"
activeClassName={styles.active}>
{lang.t('configure.community')}
{t('configure.community')}
</Link>
<Link
id='configureNav'
className={styles.navLink}
to="/admin/configure"
activeClassName={styles.active}>
{lang.t('configure.configure')}
{t('configure.configure')}
</Link>
</Navigation>
<div className={styles.rightPanel}>
@@ -54,8 +54,8 @@ const CoralHeader = ({handleLogout, showShortcuts = () => {}, restricted = false
<div>
<IconButton name="settings" id="menu-settings"/>
<Menu target="menu-settings" align="right">
<MenuItem onClick={() => showShortcuts(true)}>{lang.t('configure.shortcuts')}</MenuItem>
<MenuItem onClick={handleLogout}>{lang.t('configure.sign_out')}</MenuItem>
<MenuItem onClick={() => showShortcuts(true)}>{t('configure.shortcuts')}</MenuItem>
<MenuItem onClick={handleLogout}>{t('configure.sign_out')}</MenuItem>
</Menu>
</div>
</li>
@@ -77,6 +77,4 @@ CoralHeader.propTypes = {
restricted: PropTypes.bool // hide elemnts from a user that's logged out
};
const lang = new I18n();
export default CoralHeader;
@@ -1,10 +1,7 @@
import React from 'react';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
import styles from './Community.css';
import Loading from './Loading';
import EmptyCard from 'coral-admin/src/components/EmptyCard';
import User from './components/User';
@@ -33,7 +30,7 @@ const FlaggedAccounts = ({...props}) => {
suspendUser={props.suspendUser}
/>;
})
: <EmptyCard>{lang.t('community.no-flagged-accounts')}</EmptyCard>
: <EmptyCard>{t('community.no-flagged-accounts')}</EmptyCard>
}
</div>
</div>
@@ -1,7 +1,9 @@
import React from 'react';
import t from 'coral-i18n/services/i18n';
const Loading = () => (
<h1> Loading results </h1>
<h1> {t('loading_results')}</h1>
);
export default Loading;
@@ -1,28 +1,26 @@
import React from 'react';
import I18n from 'coral-i18n/modules/i18n/i18n';
import styles from './Community.css';
import Table from './Table';
import {Pager, Icon} from 'coral-ui';
import EmptyCard from '../../components/EmptyCard';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const tableHeaders = [
{
title: lang.t('community.username_and_email'),
title: t('community.username_and_email'),
field: 'username'
},
{
title: lang.t('community.account_creation_date'),
title: t('community.account_creation_date'),
field: 'created_at'
},
{
title: lang.t('community.status'),
title: t('community.status'),
field: 'status'
},
{
title: lang.t('community.newsroom_role'),
title: t('community.newsroom_role'),
field: 'role'
}
];
@@ -40,7 +38,7 @@ const People = ({commenters, searchValue, onSearchChange, ...props}) => {
className={styles.searchBoxInput}
value={searchValue}
onChange={onSearchChange}
placeholder={lang.t('streams.search')}
placeholder={t('streams.search')}
/>
</div>
</div>
@@ -52,7 +50,7 @@ const People = ({commenters, searchValue, onSearchChange, ...props}) => {
commenters={commenters}
onHeaderClickHandler={props.onHeaderClickHandler}
/>
: <EmptyCard>{lang.t('community.no-results')}</EmptyCard>
: <EmptyCard>{t('community.no-results')}</EmptyCard>
}
<Pager
totalPages={props.totalPages}
@@ -2,10 +2,9 @@ import React, {Component} from 'react';
import {connect} from 'react-redux';
import {SelectField, Option} from 'react-mdl-selectfield';
import styles from './Community.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
import {setRole, setCommenterStatus} from '../../actions/community';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
class Table extends Component {
@@ -52,20 +51,20 @@ class Table extends Component {
<td className="mdl-data-table__cell--non-numeric">
<SelectField label={'Select me'} value={row.status || ''}
className={styles.selectField}
label={lang.t('community.status')}
label={t('community.status')}
onChange={(status) => this.onCommenterStatusChange(row.id, status)}>
<Option value={'ACTIVE'}>{lang.t('community.active')}</Option>
<Option value={'BANNED'}>{lang.t('community.banned')}</Option>
<Option value={'ACTIVE'}>{t('community.active')}</Option>
<Option value={'BANNED'}>{t('community.banned')}</Option>
</SelectField>
</td>
<td className="mdl-data-table__cell--non-numeric">
<SelectField label={'Select me'} value={row.roles[0] || ''}
className={styles.selectField}
label={lang.t('community.role')}
label={t('community.role')}
onChange={(role) => this.onRoleChange(row.id, role)}>
<Option value={''}>.</Option>
<Option value={'MODERATOR'}>{lang.t('community.moderator')}</Option>
<Option value={'ADMIN'}>{lang.t('community.admin')}</Option>
<Option value={'MODERATOR'}>{t('community.moderator')}</Option>
<Option value={'ADMIN'}>{t('community.admin')}</Option>
</SelectField>
</td>
</tr>
@@ -4,9 +4,7 @@ import styles from './BanUserDialog.css';
import Button from 'coral-ui/components/Button';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const BanUserDialog = ({open, handleClose, handleBanUser, user}) => (
<Dialog
@@ -15,19 +13,19 @@ const BanUserDialog = ({open, handleClose, handleBanUser, user}) => (
open={open}
onClose={handleClose}
onCancel={handleClose}
title={lang.t('community.ban_user')}>
title={t('community.ban_user')}>
<span className={styles.close} onClick={handleClose}>×</span>
<div>
<div className={styles.header}>
<h2>{lang.t('community.ban_user')}</h2>
<h2>{t('community.ban_user')}</h2>
</div>
<div className={styles.separator}>
<h3>{lang.t('community.are_you_sure', user.username)}</h3>
<i>{lang.t('community.note')}</i>
<h3>{t('community.are_you_sure', user.username)}</h3>
<i>{t('community.note')}</i>
</div>
<div className={styles.buttons}>
<Button cStyle="cancel" className={styles.cancel} onClick={handleClose} raised>
{lang.t('community.cancel')}
{t('community.cancel')}
</Button>
<Button
cStyle="black" className={styles.ban}
@@ -37,7 +35,7 @@ const BanUserDialog = ({open, handleClose, handleBanUser, user}) => (
});
}}
raised>
{lang.t('community.yes_ban_user')}
{t('community.yes_ban_user')}
</Button>
</div>
</div>
@@ -1,13 +1,9 @@
import React from 'react';
import styles from './styles.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
import {Link} from 'react-router';
const lang = new I18n();
const CommunityMenu = () => {
const flaggedPath = '/admin/community/flagged';
const peoplePath = '/admin/community/people';
@@ -16,10 +12,10 @@ const CommunityMenu = () => {
<div className={`mdl-tabs__tab-bar ${styles.tabBar}`}>
<div>
<Link to={flaggedPath} className={`mdl-tabs__tab ${styles.tab}`} activeClassName={styles.active}>
{lang.t('community.flaggedaccounts')}
{t('community.flaggedaccounts')}
</Link>
<Link to={peoplePath} className={`mdl-tabs__tab ${styles.tab}`} activeClassName={styles.active}>
{lang.t('community.people')}
{t('community.people')}
</Link>
</div>
</div>
@@ -3,8 +3,7 @@ import React, {Component, PropTypes} from 'react';
import {Dialog, Button} from 'coral-ui';
import styles from './SuspendUserDialog.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const stages = [
{
@@ -36,7 +35,7 @@ class SuspendUserDialog extends Component {
}
componentDidMount() {
this.setState({email: lang.t('suspenduser.email'), about: lang.t('suspenduser.username')});
this.setState({email: t('suspenduser.email'), about: t('suspenduser.username')});
}
/*
@@ -77,18 +76,18 @@ class SuspendUserDialog extends Component {
open={open}
onClose={handleClose}
onCancel={handleClose}
title={lang.t('suspenduser.title')}>
title={t('suspenduser.title')}>
<div className={styles.title}>
{lang.t(stages[stage].title, lang.t('suspenduser.username'))}
{t(stages[stage].title, t('suspenduser.username'))}
</div>
<div className={styles.container}>
<div className={styles.description}>
{lang.t(stages[stage].description, lang.t('suspenduser.username'))}
{t(stages[stage].description, t('suspenduser.username'))}
</div>
{
stage === 1 &&
<div className={styles.writeContainer}>
<div className={styles.emailMessage}>{lang.t('suspenduser.write_message')}</div>
<div className={styles.emailMessage}>{t('suspenduser.write_message')}</div>
<div className={styles.emailContainer}>
<textarea
rows={5}
@@ -101,7 +100,7 @@ class SuspendUserDialog extends Component {
<div className={styles.modalButtons}>
{Object.keys(stages[stage].options).map((key, i) => (
<Button key={i} onClick={this.onActionClick(stage, i)}>
{lang.t(stages[stage].options[key], lang.t('suspenduser.username'))}
{t(stages[stage].options[key], t('suspenduser.username'))}
</Button>
))}
</div>
@@ -3,8 +3,7 @@ import styles from '../Community.css';
import ActionButton from './ActionButton';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
// Render a single user for the list
const User = (props) => {
@@ -33,11 +32,11 @@ const User = (props) => {
<div className={styles.itemBody}>
<div className={styles.body}>
<div className={styles.flaggedByCount}>
<i className="material-icons">flag</i><span className={styles.flaggedByLabel}>{lang.t('community.flags')}({ user.actions.length })</span>:
<i className="material-icons">flag</i><span className={styles.flaggedByLabel}>{t('community.flags')}({ user.actions.length })</span>:
{ user.action_summaries.map(
(action, i) => {
return <span className={styles.flaggedBy} key={i}>
{lang.t(`community.${action.reason}`)} ({action.count})
{t(`community.${action.reason}`)} ({action.count})
</span>;
}
)}
@@ -47,7 +46,7 @@ const User = (props) => {
(action_sum, i) => {
return <div key={i}>
<span className={styles.flaggedByLabel}>
{lang.t(`community.${action_sum.reason}`)} ({action_sum.count})
{t(`community.${action_sum.reason}`)} ({action_sum.count})
</span>
{user.actions.map(
@@ -10,10 +10,10 @@ import {
import {Button, List, Item, Card, Spinner} from 'coral-ui';
import styles from './Configure.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
import StreamSettings from './StreamSettings';
import ModerationSettings from './ModerationSettings';
import TechSettings from './TechSettings';
import t from 'coral-i18n/services/i18n';
class Configure extends Component {
constructor (props) {
@@ -104,11 +104,11 @@ class Configure extends Component {
getPageTitle (section) {
switch(section) {
case 'stream':
return lang.t('configure.stream_settings');
return t('configure.stream_settings');
case 'moderation':
return lang.t('configure.moderation_settings');
return t('configure.moderation_settings');
case 'tech':
return lang.t('configure.tech_settings');
return t('configure.tech_settings');
default:
return '';
}
@@ -126,13 +126,13 @@ class Configure extends Component {
<div className={styles.leftColumn}>
<List onChange={this.changeSection} activeItem={activeSection}>
<Item itemId='stream' icon='speaker_notes'>
{lang.t('configure.stream_settings')}
{t('configure.stream_settings')}
</Item>
<Item itemId='moderation' icon='thumbs_up_down'>
{lang.t('configure.moderation_settings')}
{t('configure.moderation_settings')}
</Item>
<Item itemId='tech' icon='code'>
{lang.t('configure.tech_settings')}
{t('configure.tech_settings')}
</Item>
</List>
<div className={styles.saveBox}>
@@ -145,7 +145,7 @@ class Configure extends Component {
icon='check'
full
>
{lang.t('configure.save_changes')}
{t('configure.save_changes')}
</Button>
:
<Button
@@ -154,7 +154,7 @@ class Configure extends Component {
icon='check'
full
>
{lang.t('configure.save_changes')}
{t('configure.save_changes')}
</Button>
}
</div>
@@ -174,5 +174,3 @@ const mapStateToProps = (state) => ({
settings: state.settings.toJS()
});
export default connect(mapStateToProps)(Configure);
const lang = new I18n();
@@ -2,16 +2,14 @@ import React from 'react';
import {Card} from 'coral-ui';
import styles from './Configure.css';
import TagsInput from 'react-tagsinput';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const Domainlist = ({domains, onChangeDomainlist}) => {
return (
<Card id={styles.domainlist} className={styles.configSetting}>
<div className={styles.wrapper}>
<div className={styles.settingsHeader}>{lang.t('configure.domain_list_title')}</div>
<p className={styles.domainlistDesc}>{lang.t('configure.domain_list_text')}</p>
<div className={styles.settingsHeader}>{t('configure.domain_list_title')}</div>
<p className={styles.domainlistDesc}>{t('configure.domain_list_text')}</p>
<div className={styles.wrapper}>
<TagsInput
value={domains}
@@ -1,6 +1,6 @@
import React, {Component} from 'react';
import I18n from 'coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
import styles from './Configure.css';
import {Button, Card} from 'coral-ui';
@@ -47,11 +47,11 @@ class EmbedLink extends Component {
<Card shadow="2" className={styles.configSetting}>
<div className={styles.wrapper}>
<div className={styles.settingsHeader}>Embed Comment Stream</div>
<p>{lang.t('configure.copy_and_paste')}</p>
<p>{t('configure.copy_and_paste')}</p>
<textarea rows={5} type='text' className={styles.embedInput} value={embedText} readOnly={true}/>
<div className={styles.actions}>
<Button raised className={styles.copyButton} onClick={this.copyToClipBoard} cStyle="black">
{lang.t('embedlink.copy')}
{t('embedlink.copy')}
</Button>
<div className={styles.copiedText}>
{this.state.copied && 'Copied!'}
@@ -64,5 +64,3 @@ class EmbedLink extends Component {
}
export default EmbedLink;
const lang = new I18n();
@@ -3,9 +3,7 @@ import styles from './Configure.css';
import {Card} from 'coral-ui';
import {Checkbox} from 'react-mdl';
import Wordlist from './Wordlist';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const updateModeration = (updateSettings, mod) => () => {
const moderation = mod === 'PRE' ? 'POST' : 'PRE';
@@ -36,9 +34,9 @@ const ModerationSettings = ({settings, updateSettings, onChangeWordlist}) => {
checked={settings.requireEmailConfirmation} />
</div>
<div className={styles.content}>
<div className={styles.settingsHeader}>{lang.t('configure.require_email_verification')}</div>
<div className={styles.settingsHeader}>{t('configure.require_email_verification')}</div>
<p className={settings.requireEmailConfirmation ? '' : styles.disabledSettingText}>
{lang.t('configure.require_email_verification_text')}
{t('configure.require_email_verification_text')}
</p>
</div>
</Card>
@@ -49,9 +47,9 @@ const ModerationSettings = ({settings, updateSettings, onChangeWordlist}) => {
checked={settings.moderation === 'PRE'} />
</div>
<div className={styles.content}>
<div className={styles.settingsHeader}>{lang.t('configure.enable_pre_moderation')}</div>
<div className={styles.settingsHeader}>{t('configure.enable_pre_moderation')}</div>
<p className={settings.moderation === 'PRE' ? '' : styles.disabledSettingText}>
{lang.t('configure.enable_pre_moderation_text')}
{t('configure.enable_pre_moderation_text')}
</p>
</div>
</Card>
@@ -62,9 +60,9 @@ const ModerationSettings = ({settings, updateSettings, onChangeWordlist}) => {
checked={settings.premodLinksEnable} />
</div>
<div className={styles.content}>
<div className={styles.settingsHeader}>{lang.t('configure.enable_premod_links')}</div>
<div className={styles.settingsHeader}>{t('configure.enable_premod_links')}</div>
<p>
{lang.t('configure.enable_premod_links_text')}
{t('configure.enable_premod_links_text')}
</p>
</div>
</Card>
@@ -1,7 +1,6 @@
import React from 'react';
import {SelectField, Option} from 'react-mdl-selectfield';
import I18n from 'coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
import styles from './Configure.css';
import {Checkbox, Textfield} from 'react-mdl';
import {Card, Icon, TextArea} from 'coral-ui';
@@ -77,9 +76,9 @@ const StreamSettings = ({updateSettings, settingsError, settings, errors}) => {
checked={settings.charCountEnable} />
</div>
<div className={styles.content}>
<div className={styles.settingsHeader}>{lang.t('configure.comment_count_header')}</div>
<div className={styles.settingsHeader}>{t('configure.comment_count_header')}</div>
<p className={settings.charCountEnable ? '' : styles.disabledSettingText}>
<span>{lang.t('configure.comment_count_text_pre')}</span>
<span>{t('configure.comment_count_text_pre')}</span>
<input type='text'
className={`${styles.charCountTexfield} ${settings.charCountEnable && styles.charCountTexfieldEnabled}`}
htmlFor='charCount'
@@ -87,13 +86,13 @@ const StreamSettings = ({updateSettings, settingsError, settings, errors}) => {
value={settings.charCount}
disabled={settings.charCountEnable ? '' : 'disabled'}
/>
<span>{lang.t('configure.comment_count_text_post')}</span>
<span>{t('configure.comment_count_text_post')}</span>
{
errors.charCount &&
<span className={styles.settingsError}>
<br/>
<Icon name="error_outline"/>
{lang.t('configure.comment_count_error')}
{t('configure.comment_count_error')}
</span>
}
</p>
@@ -107,10 +106,10 @@ const StreamSettings = ({updateSettings, settingsError, settings, errors}) => {
</div>
<div className={styles.content}>
<div className={styles.settingsHeader}>
{lang.t('configure.include_comment_stream')}
{t('configure.include_comment_stream')}
</div>
<p className={settings.infoBoxEnable ? '' : styles.disabledSettingText}>
{lang.t('configure.include_comment_stream_desc')}
{t('configure.include_comment_stream_desc')}
</p>
<div className={`${styles.configSettingInfoBox} ${settings.infoBoxEnable ? null : styles.hidden}`} >
<MarkdownEditor
@@ -123,8 +122,8 @@ const StreamSettings = ({updateSettings, settingsError, settings, errors}) => {
</Card>
<Card className={`${styles.configSetting} ${styles.configSettingInfoBox}`}>
<div className={styles.wrapper}>
<div className={styles.settingsHeader}>{lang.t('configure.closed_stream_settings')}</div>
<p>{lang.t('configure.closed_comments_desc')}</p>
<div className={styles.settingsHeader}>{t('configure.closed_stream_settings')}</div>
<p>{t('configure.closed_comments_desc')}</p>
<div>
<TextArea className={styles.descriptionBox}
onChange={updateClosedMessage(updateSettings)}
@@ -140,7 +139,7 @@ const StreamSettings = ({updateSettings, settingsError, settings, errors}) => {
checked={settings.autoCloseStream} />
</div>
<div className={styles.content}>
{lang.t('configure.close_after')}
{t('configure.close_after')}
<br />
<Textfield
type='number'
@@ -148,15 +147,15 @@ const StreamSettings = ({updateSettings, settingsError, settings, errors}) => {
style={{width: 50}}
onChange={updateClosedTimeout(updateSettings, settings.closedTimeout)}
value={getTimeoutAmount(settings.closedTimeout)}
label={lang.t('configure.closed_comments_label')} />
label={t('configure.closed_comments_label')} />
<div className={styles.configTimeoutSelect}>
<SelectField
label="comments closed time window"
value={getTimeoutMeasure(settings.closedTimeout)}
onChange={updateClosedTimeout(updateSettings, settings.closedTimeout, true)}>
<Option value={'hours'}>{lang.t('configure.hours')}</Option>
<Option value={'days'}>{lang.t('configure.days')}</Option>
<Option value={'weeks'}>{lang.t('configure.weeks')}</Option>
<Option value={'hours'}>{t('configure.hours')}</Option>
<Option value={'days'}>{t('configure.days')}</Option>
<Option value={'weeks'}>{t('configure.weeks')}</Option>
</SelectField>
</div>
</div>
@@ -183,5 +182,3 @@ const getTimeoutMeasure = (ts) => {
// Dividing the amount by it's measure (hours, days, weeks) we
// obtain the amount of time
const getTimeoutAmount = (ts) => ts / TIMESTAMPS[getTimeoutMeasure(ts)];
const lang = new I18n();
@@ -3,9 +3,7 @@ import {Card} from 'coral-ui';
import Domainlist from './Domainlist';
import EmbedLink from './EmbedLink';
import styles from './Configure.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const updateCustomCssUrl = (updateSettings) => (event) => {
const customCssUrl = event.target.value;
@@ -21,8 +19,8 @@ const TechSettings = ({settings, onChangeDomainlist, updateSettings}) => {
<EmbedLink />
<Card className={styles.configSetting}>
<div className={styles.wrapper}>
<div className={styles.settingsHeader}>{lang.t('configure.custom_css_url')}</div>
<p>{lang.t('configure.custom_css_url_desc')}</p>
<div className={styles.settingsHeader}>{t('configure.custom_css_url')}</div>
<p>{t('configure.custom_css_url_desc')}</p>
<input
className={styles.customCSSInput}
value={settings.customCssUrl}
@@ -1,6 +1,5 @@
import React from 'react';
import I18n from 'coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
import TagsInput from 'react-tagsinput';
import styles from './Configure.css';
import {Card} from 'coral-ui';
@@ -8,8 +7,8 @@ import {Card} from 'coral-ui';
const Wordlist = ({suspectWords, bannedWords, onChangeWordlist}) => (
<div>
<Card id={styles.bannedWordlist} className={styles.configSetting}>
<div className={styles.settingsHeader}>{lang.t('configure.banned_words_title')}</div>
<p className={styles.wordlistDesc}>{lang.t('configure.banned_word_text')}</p>
<div className={styles.settingsHeader}>{t('configure.banned_words_title')}</div>
<p className={styles.wordlistDesc}>{t('configure.banned_word_text')}</p>
<div className={styles.wrapper}>
<TagsInput
value={bannedWords}
@@ -21,8 +20,8 @@ const Wordlist = ({suspectWords, bannedWords, onChangeWordlist}) => (
</div>
</Card>
<Card id={styles.suspectWordlist} className={styles.configSetting}>
<div className={styles.settingsHeader}>{lang.t('configure.suspect_words_title')}</div>
<p className={styles.wordlistDesc}>{lang.t('configure.suspect_word_text')}</p>
<div className={styles.settingsHeader}>{t('configure.suspect_words_title')}</div>
<p className={styles.wordlistDesc}>{t('configure.suspect_word_text')}</p>
<div className={styles.wrapper}>
<TagsInput
value={suspectWords}
@@ -36,5 +35,3 @@ const Wordlist = ({suspectWords, bannedWords, onChangeWordlist}) => (
);
export default Wordlist;
const lang = new I18n();
@@ -1,17 +1,15 @@
import React, {PropTypes} from 'react';
import {Link} from 'react-router';
import styles from './Widget.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const ActivityWidget = ({assets}) => {
return (
<div className={styles.widget}>
<h2 className={styles.heading}>Articles with the most conversations</h2>
<div className={styles.widgetHead}>
<p>{lang.t('streams.article')}</p>
<p>{lang.t('dashboard.comment_count')}</p>
<p>{t('streams.article')}</p>
<p>{t('dashboard.comment_count')}</p>
</div>
<div className={styles.widgetTable}>
{
@@ -28,7 +26,7 @@ const ActivityWidget = ({assets}) => {
</div>
);
})
: <div className={styles.rowLinkify}>{lang.t('dashboard.no_activity')}</div>
: <div className={styles.rowLinkify}>{t('dashboard.no_activity')}</div>
}
</div>
</div>
@@ -2,17 +2,16 @@ import React, {PropTypes} from 'react';
import {Link} from 'react-router';
import styles from './Widget.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const FlagWidget = ({assets}) => {
return (
<div className={styles.widget}>
<h2 className={styles.heading}>{lang.t('dashboard.most_flags')}</h2>
<h2 className={styles.heading}>{t('dashboard.most_flags')}</h2>
<div className={styles.widgetHead}>
<p>{lang.t('streams.article')}</p>
<p>{lang.t('dashboard.flags')}</p>
<p>{t('streams.article')}</p>
<p>{t('dashboard.flags')}</p>
</div>
<div className={styles.widgetTable}>
{
@@ -34,7 +33,7 @@ const FlagWidget = ({assets}) => {
</div>
);
})
: <div className={styles.rowLinkify}>{lang.t('dashboard.no_flags')}</div>
: <div className={styles.rowLinkify}>{t('dashboard.no_flags')}</div>
}
</div>
</div>
@@ -1,9 +1,7 @@
import React, {PropTypes} from 'react';
import {Link} from 'react-router';
import styles from './Widget.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const LikeWidget = ({assets}) => {
@@ -11,8 +9,8 @@ const LikeWidget = ({assets}) => {
<div className={styles.widget}>
<h2 className={styles.heading}>Articles with the most likes</h2>
<div className={styles.widgetHead}>
<p>{lang.t('streams.article')}</p>
<p>{lang.t('modqueue.likes')}</p>
<p>{t('streams.article')}</p>
<p>{t('modqueue.likes')}</p>
</div>
<div className={styles.widgetTable}>
{
@@ -30,7 +28,7 @@ const LikeWidget = ({assets}) => {
</div>
);
})
: <div className={styles.rowLinkify}>{lang.t('dashboard.no_likes')}</div>
: <div className={styles.rowLinkify}>{t('dashboard.no_likes')}</div>
}
</div>
</div>
@@ -1,11 +1,9 @@
import React from 'react';
import I18n from 'coral-i18n/modules/i18n/i18n';
import ModerationQueue from 'coral-admin/src/containers/ModerationQueue/ModerationQueue';
import styles from './Widget.css';
import BanUserDialog from 'coral-admin/src/components/BanUserDialog';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const MostLikedCommentsWidget = (props) => {
const {
@@ -21,7 +19,7 @@ const MostLikedCommentsWidget = (props) => {
return (
<div className={styles.widget}>
<h2 className={styles.heading}>{lang.t('most_liked_comments')}</h2>
<h2 className={styles.heading}>{t('most_liked_comments')}</h2>
<ModerationQueue
comments={comments}
suspectWords={settings.wordlist.suspect}
@@ -2,26 +2,24 @@ import React from 'react';
import styles from './style.css';
import {TextField, Button} from 'coral-ui';
const lang = new I18n();
import I18n from 'coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
const AddOrganizationName = (props) => {
const {handleSettingsChange, handleSettingsSubmit, install} = props;
return (
<div className={styles.step}>
<p>{lang.t('ADD_ORGANIZATION.DESCRIPTION')}</p>
<p>{t('ADD_ORGANIZATION.DESCRIPTION')}</p>
<div className={styles.form}>
<form onSubmit={handleSettingsSubmit}>
<TextField
className={styles.TextField}
id="organizationName"
type="text"
label={lang.t('ADD_ORGANIZATION.LABEL')}
label={t('ADD_ORGANIZATION.LABEL')}
onChange={handleSettingsChange}
showErrors={install.showErrors}
errorMsg={install.errors.organizationName} />
<Button type="submit" cStyle='black' full>{lang.t('ADD_ORGANIZATION.SAVE')}</Button>
<Button type="submit" cStyle='black' full>{t('ADD_ORGANIZATION.SAVE')}</Button>
</form>
</div>
</div>
@@ -2,9 +2,7 @@ import React from 'react';
import styles from './style.css';
import {TextField, Button, Spinner} from 'coral-ui';
const lang = new I18n();
import I18n from 'coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
const InitialStep = (props) => {
const {handleUserChange, handleUserSubmit, install} = props;
@@ -16,7 +14,7 @@ const InitialStep = (props) => {
className={styles.textField}
id="email"
type="email"
label={lang.t('CREATE.EMAIL')}
label={t('CREATE.EMAIL')}
onChange={handleUserChange}
showErrors={install.showErrors}
errorMsg={install.errors.email}
@@ -27,7 +25,7 @@ const InitialStep = (props) => {
className={styles.textField}
id="username"
type="text"
label={lang.t('CREATE.USERNAME')}
label={t('CREATE.USERNAME')}
onChange={handleUserChange}
showErrors={install.showErrors}
errorMsg={install.errors.username}
@@ -37,7 +35,7 @@ const InitialStep = (props) => {
className={styles.textField}
id="password"
type="password"
label={lang.t('CREATE.PASSWORD')}
label={t('CREATE.PASSWORD')}
onChange={handleUserChange}
showErrors={install.showErrors}
errorMsg={install.errors.password}
@@ -47,7 +45,7 @@ const InitialStep = (props) => {
className={styles.textField}
id="confirmPassword"
type="password"
label={lang.t('CREATE.CONFIRM_PASSWORD')}
label={t('CREATE.CONFIRM_PASSWORD')}
onChange={handleUserChange}
showErrors={install.showErrors}
errorMsg={install.errors.confirm_password}
@@ -55,7 +53,7 @@ const InitialStep = (props) => {
{
!props.install.isLoading ?
<Button cStyle='black' type="submit" full>{lang.t('CREATE.SAVE')}</Button>
<Button cStyle='black' type="submit" full>{t('CREATE.SAVE')}</Button>
:
<Spinner />
}
@@ -3,16 +3,14 @@ import styles from './style.css';
import {Button} from 'coral-ui';
import {Link} from 'react-router';
const lang = new I18n();
import I18n from 'coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
const InitialStep = () => {
return (
<div className={`${styles.step} ${styles.finalStep}`}>
<p>{lang.t('FINAL.DESCRIPTION')}</p>
<Button raised><Link to='/admin'>{lang.t('FINAL.LAUNCH')}</Link></Button>
<Button cStyle='black' raised><a href="http://coralproject.net">{lang.t('FINAL.CLOSE')}</a></Button>
<p>{t('FINAL.DESCRIPTION')}</p>
<Button raised><Link to='/admin'>{t('FINAL.LAUNCH')}</Link></Button>
<Button cStyle='black' raised><a href="http://coralproject.net">{t('FINAL.CLOSE')}</a></Button>
</div>
);
};
@@ -2,16 +2,14 @@ import React from 'react';
import styles from './style.css';
import {Button} from 'coral-ui';
const lang = new I18n();
import I18n from 'coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
const InitialStep = (props) => {
const {nextStep} = props;
return (
<div className={styles.step}>
<p>{lang.t('INITIAL.DESCRIPTION')}</p>
<Button cStyle='green' onClick={nextStep} raised>{lang.t('INITIAL.SUBMIT')}</Button>
<p>{t('INITIAL.DESCRIPTION')}</p>
<Button cStyle='green' onClick={nextStep} raised>{t('INITIAL.SUBMIT')}</Button>
</div>
);
};
@@ -3,18 +3,16 @@ import styles from './style.css';
import {Button, Card} from 'coral-ui';
import TagsInput from 'react-tagsinput';
const lang = new I18n();
import I18n from 'coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
const PermittedDomainsStep = (props) => {
const {finishInstall, install, handleDomainsChange} = props;
const domains = install.data.settings.domains.whitelist;
return (
<div className={styles.step}>
<h3>{lang.t('PERMITTED_DOMAINS.TITLE')}</h3>
<h3>{t('PERMITTED_DOMAINS.TITLE')}</h3>
<Card className={styles.card}>
<p>{lang.t('PERMITTED_DOMAINS.DESCRIPTION')}</p>
<p>{t('PERMITTED_DOMAINS.DESCRIPTION')}</p>
<TagsInput
value={domains}
inputProps={{placeholder: 'URL'}}
@@ -23,7 +21,7 @@ const PermittedDomainsStep = (props) => {
onChange={(tags) => handleDomainsChange(tags)}
/>
</Card>
<Button cStyle='green' onClick={finishInstall} raised>{lang.t('PERMITTED_DOMAINS.SUBMIT')}</Button>
<Button cStyle='green' onClick={finishInstall} raised>{t('PERMITTED_DOMAINS.SUBMIT')}</Button>
</div>
);
};
@@ -1,58 +0,0 @@
{
"en": {
"INITIAL" : {
"DESCRIPTION": "Let's set up your Talk community in just a few short steps.",
"SUBMIT": "Get Started"
},
"ADD_ORGANIZATION": {
"DESCRIPTION": "Please tell us the name of your organization. This will appear in emails when inviting new team members.",
"LABEL": "Organization Name",
"SAVE": "Save"
},
"CREATE": {
"EMAIL": "Email address",
"USERNAME": "Username",
"PASSWORD": "Password",
"CONFIRM_PASSWORD": "Confirm Password",
"SAVE": "Save"
},
"PERMITTED_DOMAINS": {
"TITLE": "Permitted domains",
"DESCRIPTION": "Enter the domains you would like to permit for Talk, e.g. your local, staging and production environments (ex. localhost:3000, staging.domain.com, domain.com).",
"SUBMIT": "Finish install"
},
"FINAL": {
"DESCRIPTION": "Thanks for installing Talk! We sent an email to verify your email address. While you finish setting up the account, you can start engaging with your readers now.",
"LAUNCH": "Launch Talk",
"CLOSE": "Close this Installer"
}
},
"es": {
"INITIAL" : {
"DESCRIPTION": "Configuremos tu comunidad de Talk en sólo algunos pasos.",
"SUBMIT": "Empezá!"
},
"ADD_ORGANIZATION": {
"DESCRIPTION": "Por favor, dinos el nombre de tu organización. Este aparecerá en los emails cuando invites nuevos miembros.",
"LABEL": "Nombre de la Organización",
"SAVE": "Guardar"
},
"CREATE": {
"EMAIL": "Dirección de E-Mail",
"USERNAME": "Usuario",
"PASSWORD": "Contraseña",
"CONFIRM_PASSWORD": "Confirmar contraseña",
"SAVE": "Guardar"
},
"PERMITTED_DOMAINS": {
"TITLE": "Dominios Permitidos",
"DESCRIPTION": "Agrega dominios permitidos a Talk, e.g. tu localhost, staging y ambientes de production (ex. localhost:3000, staging.domain.com, domain.com).",
"SUBMIT": "Finalizar instalación"
},
"FINAL": {
"DESCRIPTION": "Gracias por instalar Talk! Te enviamos un email para verificar tu identidad. Mientras se termina de configurar la cuenta, ya puedes empezar a interactuar con tus lectores",
"LAUNCH": "Lanzar Talk",
"CLOSE": "Cerrar este instalador"
}
}
}
@@ -4,11 +4,10 @@ import Comment from './components/Comment';
import styles from './components/styles.css';
import EmptyCard from '../../components/EmptyCard';
import {actionsMap} from './helpers/moderationQueueActionsMap';
import I18n from 'coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
import LoadMore from './components/LoadMore';
const lang = new I18n();
class ModerationQueue extends React.Component {
static propTypes = {
@@ -56,7 +55,7 @@ class ModerationQueue extends React.Component {
currentAsset={props.currentAsset}
/>;
})
: <EmptyCard>{lang.t('modqueue.empty_queue')}</EmptyCard>
: <EmptyCard>{t('modqueue.empty_queue')}</EmptyCard>
}
</ul>
<LoadMore
@@ -1,5 +1,4 @@
import React, {PropTypes} from 'react';
import timeago from 'timeago.js';
import {Link} from 'react-router';
import Linkify from 'react-linkify';
@@ -15,8 +14,7 @@ import BanUserButton from 'coral-admin/src/components/BanUserButton';
const linkify = new Linkify();
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import {t, timeago} from 'coral-i18n/services/i18n';
const Comment = ({
actions = [],
@@ -59,10 +57,7 @@ const Comment = ({
{comment.user.name}
</span>
<span className={styles.created}>
{timeago().format(
comment.created_at || Date.now() - props.index * 60 * 1000,
lang.getLocale().replace('-', '_')
)}
{timeago(comment.created_at || Date.now() - props.index * 60 * 1000)}
</span>
<BanUserButton
user={comment.user}
@@ -79,7 +74,7 @@ const Comment = ({
{comment.user.status === 'banned'
? <span className={styles.banned}>
<Icon name="error_outline" />
{lang.t('comment.banned_user')}
{t('comment.banned_user')}
</span>
: null}
<Slot fill="adminCommentInfoBar" comment={comment} />
@@ -101,7 +96,7 @@ const Comment = ({
href={`${comment.asset.url}#${comment.id}`}
target="_blank"
>
<Icon name="open_in_new" /> {lang.t('comment.view_context')}
<Icon name="open_in_new" /> {t('comment.view_context')}
</a>
</p>
<Slot fill="adminCommentContent" comment={comment} />
@@ -1,19 +1,18 @@
import React, {PropTypes} from 'react';
import styles from './CommentCount.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const CommentCount = ({count}) => {
let number = count;
// shorten large counts to abbreviations
if (number / 1e9 > 1) {
number = `${(number / 1e9).toFixed(1)}${lang.t('modqueue.billion')}`;
number = `${(number / 1e9).toFixed(1)}${t('modqueue.billion')}`;
} else if (number / 1e6 > 1) {
number = `${(number / 1e6).toFixed(1)}${lang.t('modqueue.million')}`;
number = `${(number / 1e6).toFixed(1)}${t('modqueue.million')}`;
} else if (number / 1e3 > 1) {
number = `${(number / 1e3).toFixed(1)}${lang.t('modqueue.thousand')}`;
number = `${(number / 1e3).toFixed(1)}${t('modqueue.thousand')}`;
}
return (
@@ -1,15 +1,14 @@
import React, {Component, PropTypes} from 'react';
import {Icon} from 'coral-ui';
import styles from './FlagBox.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const shortReasons = {
'This comment is offensive': lang.t('modqueue.offensive'),
'This looks like an ad/marketing': lang.t('modqueue.spam_ads'),
'This user is impersonating': lang.t('modqueue.impersonating'),
'I don\'t like this username': lang.t('modqueue.dont_like_username'),
'Other': lang.t('modqueue.other')
'This comment is offensive': t('modqueue.offensive'),
'This looks like an ad/marketing': t('modqueue.spam_ads'),
'This user is impersonating': t('modqueue.impersonating'),
'I don\'t like this username': t('modqueue.dont_like_username'),
'Other': t('modqueue.other')
};
class FlagBox extends Component {
@@ -47,7 +46,7 @@ class FlagBox extends Component {
<li key={i} className={styles.lessDetail}>{this.reasonMap(action.reason)} (<strong>{action.count}</strong>)</li>
)}
</ul>
<a onClick={this.toggleDetail} className={styles.moreDetail}>{showDetail ? lang.t('modqueue.less-detail') : lang.t('modqueue.more_detail')}</a>
<a onClick={this.toggleDetail} className={styles.moreDetail}>{showDetail ? t('modqueue.less-detail') : t('modqueue.more_detail')}</a>
</div>
{showDetail && (
<div className={styles.detail}>
@@ -2,11 +2,9 @@ import React, {PropTypes} from 'react';
import CommentCount from './CommentCount';
import styles from './styles.css';
import {SelectField, Option} from 'react-mdl-selectfield';
import I18n from 'coral-i18n/modules/i18n/i18n';
import {Icon} from 'coral-ui';
import {Link} from 'react-router';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const ModerationMenu = (
{asset, allCount, acceptedCount, premodCount, rejectedCount, flaggedCount, selectSort, sort}
@@ -25,31 +23,31 @@ const ModerationMenu = (
to={getPath('all')}
className={`mdl-tabs__tab ${styles.tab}`}
activeClassName={styles.active}>
<Icon name='question_answer' className={styles.tabIcon} /> {lang.t('modqueue.all')} <CommentCount count={allCount} />
<Icon name='question_answer' className={styles.tabIcon} /> {t('modqueue.all')} <CommentCount count={allCount} />
</Link>
<Link
to={getPath('premod')}
className={`mdl-tabs__tab ${styles.tab}`}
activeClassName={styles.active}>
<Icon name='access_time' className={styles.tabIcon} /> {lang.t('modqueue.premod')} <CommentCount count={premodCount} />
<Icon name='access_time' className={styles.tabIcon} /> {t('modqueue.premod')} <CommentCount count={premodCount} />
</Link>
<Link
to={getPath('flagged')}
className={`mdl-tabs__tab ${styles.tab}`}
activeClassName={styles.active}>
<Icon name='flag' className={styles.tabIcon} /> {lang.t('modqueue.flagged')} <CommentCount count={flaggedCount} />
<Icon name='flag' className={styles.tabIcon} /> {t('modqueue.flagged')} <CommentCount count={flaggedCount} />
</Link>
<Link
to={getPath('accepted')}
className={`mdl-tabs__tab ${styles.tab}`}
activeClassName={styles.active}>
<Icon name='check' className={styles.tabIcon} /> {lang.t('modqueue.approved')} <CommentCount count={acceptedCount} />
<Icon name='check' className={styles.tabIcon} /> {t('modqueue.approved')} <CommentCount count={acceptedCount} />
</Link>
<Link
to={getPath('rejected')}
className={`mdl-tabs__tab ${styles.tab}`}
activeClassName={styles.active}>
<Icon name='close' className={styles.tabIcon} /> {lang.t('modqueue.rejected')} <CommentCount count={rejectedCount} />
<Icon name='close' className={styles.tabIcon} /> {t('modqueue.rejected')} <CommentCount count={rejectedCount} />
</Link>
</div>
<SelectField
@@ -1,7 +1,7 @@
import React, {Component} from 'react';
import styles from './Stories.css';
import {connect} from 'react-redux';
import I18n from 'coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
import {fetchAssets, updateAssetState} from 'coral-admin/src/actions/assets';
import {Link} from 'react-router';
@@ -81,14 +81,14 @@ class Stories extends Component {
className={closed ? styles.statusMenuClosed : styles.statusMenuOpen}
onClick={this.onStatusClick(closed, id, statusMenuOpen)}>
{!statusMenuOpen && <Icon className={styles.statusMenuIcon} name='keyboard_arrow_down'/>}
{closed ? lang.t('streams.closed') : lang.t('streams.open')}
{closed ? t('streams.closed') : t('streams.open')}
</div>
{
statusMenuOpen &&
<div
className={!closed ? styles.statusMenuClosed : styles.statusMenuOpen}
onClick={this.onStatusClick(!closed, id, statusMenuOpen)}>
{!closed ? lang.t('streams.closed') : lang.t('streams.open')}
{!closed ? t('streams.closed') : t('streams.open')}
</div>
}
</div>;
@@ -120,10 +120,10 @@ class Stories extends Component {
value={search}
className={styles.searchBoxInput}
onChange={this.onSearchChange}
placeholder={lang.t('streams.search')}/>
placeholder={t('streams.search')}/>
</div>
<div className={styles.optionHeader}>{lang.t('streams.filter_streams')}</div>
<div className={styles.optionDetail}>{lang.t('streams.stream_status')}</div>
<div className={styles.optionHeader}>{t('streams.filter_streams')}</div>
<div className={styles.optionDetail}>{t('streams.stream_status')}</div>
<RadioGroup
name='status filter'
value={filter}
@@ -131,11 +131,11 @@ class Stories extends Component {
onChange={this.onSettingChange('filter')}
className={styles.radioGroup}
>
<Radio value='all'>{lang.t('streams.all')}</Radio>
<Radio value='open'>{lang.t('streams.open')}</Radio>
<Radio value='closed'>{lang.t('streams.closed')}</Radio>
<Radio value='all'>{t('streams.all')}</Radio>
<Radio value='open'>{t('streams.open')}</Radio>
<Radio value='closed'>{t('streams.closed')}</Radio>
</RadioGroup>
<div className={styles.optionHeader}>{lang.t('streams.sort_by')}</div>
<div className={styles.optionHeader}>{t('streams.sort_by')}</div>
<RadioGroup
name='sort by'
value={sort}
@@ -143,20 +143,20 @@ class Stories extends Component {
onChange={this.onSettingChange('sort')}
className={styles.radioGroup}
>
<Radio value='desc'>{lang.t('streams.newest')}</Radio>
<Radio value='asc'>{lang.t('streams.oldest')}</Radio>
<Radio value='desc'>{t('streams.newest')}</Radio>
<Radio value='asc'>{t('streams.oldest')}</Radio>
</RadioGroup>
</div>
{
assetsIds.length
? <div className={styles.mainContent}>
<DataTable className={styles.streamsTable} rows={assetsIds} onClick={this.goToModeration}>
<TableHeader name="title" cellFormatter={this.renderTitle}>{lang.t('streams.article')}</TableHeader>
<TableHeader name="title" cellFormatter={this.renderTitle}>{t('streams.article')}</TableHeader>
<TableHeader name="publication_date" cellFormatter={this.renderDate}>
{lang.t('streams.pubdate')}
{t('streams.pubdate')}
</TableHeader>
<TableHeader name="closedAt" cellFormatter={this.renderStatus} className={styles.status}>
{lang.t('streams.status')}
{t('streams.status')}
</TableHeader>
</DataTable>
<Pager
@@ -164,7 +164,7 @@ class Stories extends Component {
page={this.state.page}
onNewPageHandler={this.onPageClick} />
</div>
: <EmptyCard>{lang.t('streams.empty_result')}</EmptyCard>
: <EmptyCard>{t('streams.empty_result')}</EmptyCard>
}
</div>
);
@@ -187,5 +187,3 @@ const mapDispatchToProps = (dispatch) => {
};
export default connect(mapStateToProps, mapDispatchToProps)(Stories);
const lang = new I18n();
@@ -1,7 +1,7 @@
import React, {Component} from 'react';
import styles from './Stories.css';
import {connect} from 'react-redux';
import I18n from 'coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
import {fetchAssets, updateAssetState} from '../../actions/assets';
import {Link} from 'react-router';
@@ -81,14 +81,14 @@ class Stories extends Component {
className={closed ? styles.statusMenuClosed : styles.statusMenuOpen}
onClick={this.onStatusClick(closed, id, statusMenuOpen)}>
{!statusMenuOpen && <Icon className={styles.statusMenuIcon} name='keyboard_arrow_down'/>}
{closed ? lang.t('streams.closed') : lang.t('streams.open')}
{closed ? t('streams.closed') : t('streams.open')}
</div>
{
statusMenuOpen &&
<div
className={!closed ? styles.statusMenuClosed : styles.statusMenuOpen}
onClick={this.onStatusClick(!closed, id, statusMenuOpen)}>
{!closed ? lang.t('streams.closed') : lang.t('streams.open')}
{!closed ? t('streams.closed') : t('streams.open')}
</div>
}
</div>;
@@ -116,10 +116,10 @@ class Stories extends Component {
value={search}
className={styles.searchBoxInput}
onChange={this.onSearchChange}
placeholder={lang.t('streams.search')}/>
placeholder={t('streams.search')}/>
</div>
<div className={styles.optionHeader}>{lang.t('streams.filter_streams')}</div>
<div className={styles.optionDetail}>{lang.t('streams.stream_status')}</div>
<div className={styles.optionHeader}>{t('streams.filter_streams')}</div>
<div className={styles.optionDetail}>{t('streams.stream_status')}</div>
<RadioGroup
name='status filter'
value={filter}
@@ -127,11 +127,11 @@ class Stories extends Component {
onChange={this.onSettingChange('filter')}
className={styles.radioGroup}
>
<Radio value='all'>{lang.t('streams.all')}</Radio>
<Radio value='open'>{lang.t('streams.open')}</Radio>
<Radio value='closed'>{lang.t('streams.closed')}</Radio>
<Radio value='all'>{t('streams.all')}</Radio>
<Radio value='open'>{t('streams.open')}</Radio>
<Radio value='closed'>{t('streams.closed')}</Radio>
</RadioGroup>
<div className={styles.optionHeader}>{lang.t('streams.sort_by')}</div>
<div className={styles.optionHeader}>{t('streams.sort_by')}</div>
<RadioGroup
name='sort by'
value={sort}
@@ -139,20 +139,20 @@ class Stories extends Component {
onChange={this.onSettingChange('sort')}
className={styles.radioGroup}
>
<Radio value='desc'>{lang.t('streams.newest')}</Radio>
<Radio value='asc'>{lang.t('streams.oldest')}</Radio>
<Radio value='desc'>{t('streams.newest')}</Radio>
<Radio value='asc'>{t('streams.oldest')}</Radio>
</RadioGroup>
</div>
{
assetsIds.length
? <div className={styles.mainContent}>
<DataTable className={styles.streamsTable} rows={assetsIds} onClick={this.goToModeration}>
<TableHeader name="title" cellFormatter={this.renderTitle}>{lang.t('streams.article')}</TableHeader>
<TableHeader name="title" cellFormatter={this.renderTitle}>{t('streams.article')}</TableHeader>
<TableHeader name="publication_date" cellFormatter={this.renderDate}>
{lang.t('streams.pubdate')}
{t('streams.pubdate')}
</TableHeader>
<TableHeader name="closedAt" cellFormatter={this.renderStatus} className={styles.status}>
{lang.t('streams.status')}
{t('streams.status')}
</TableHeader>
</DataTable>
<Pager
@@ -160,7 +160,7 @@ class Stories extends Component {
page={this.state.page}
onNewPageHandler={this.onPageClick} />
</div>
: <EmptyCard>{lang.t('streams.empty_result')}</EmptyCard>
: <EmptyCard>{t('streams.empty_result')}</EmptyCard>
}
</div>
);
@@ -183,5 +183,3 @@ const mapDispatchToProps = (dispatch) => {
};
export default connect(mapStateToProps, mapDispatchToProps)(Stories);
const lang = new I18n();
-358
View File
@@ -1,358 +0,0 @@
{
"en": {
"errors": {
"NOT_AUTHORIZED": "Your username or password is not recognized by our system.",
"LOGIN_MAXIMUM_EXCEEDED": "You have made too many unsuccessful password attempts. Please wait."
},
"community": {
"username_and_email": "Username and Email",
"account_creation_date": "Account Creation Date",
"newsroom_role": "Newsroom Role",
"admin": "Administrator",
"moderator": "Moderator",
"role": "Select role...",
"no-results": "No users found with that user name or email address. They're hiding!",
"status": "Status",
"select-status": "Select status...",
"active": "Active",
"banned": "Banned",
"banned-user": "Banned User",
"loading": "Loading results",
"flags": "Flags",
"flaggedaccounts": "Flagged Usernames",
"people": "People",
"no-flagged-accounts": "The Account Flags queue is currently empty.",
"I don't like this username": "I don't like this username",
"This user is impersonating": "Impersonation",
"This looks like an ad/marketing": "Spam/Ads",
"This username is offensive": "Offensive",
"Other": "Other",
"ban_user": "Ban User?",
"are_you_sure": "Are you sure you would like to ban {0}?",
"note": "Note: Banning this user will not let them edit, comment or remove anything.",
"cancel": "Cancel",
"yes_ban_user": "Yes, Ban User"
},
"modqueue": {
"likes": "likes",
"all": "all",
"approved": "approved",
"premod": "pre-mod",
"rejected": "rejected",
"flagged": "flagged",
"account": "account flags",
"shortcuts": "Shortcuts",
"close": "Close",
"actions": "Actions",
"navigation": "Navigation",
"mod-faster": "Moderate faster with keyboard shortcuts",
"try-these": "Try these",
"view-more-shortcuts": "View more shortcuts",
"shift-key": "⇧",
"approve": "Approve comment",
"reject": "Reject comment",
"nextcomment": "Go to the next comment",
"prevcomment": "Go to the previous comment",
"singleview": "Toggle single comment edit view",
"thismenu": "Open this menu",
"emptyqueue": "No more comments to moderate! You're all caught up. Go have some ☕️",
"showshortcuts": "Show Shortcuts",
"more-detail": "More detail",
"less-detail": "Less detail",
"dont-like-username": "Don't like username",
"impersonating": "Impersonating",
"offensive": "Offensive",
"spam/ads": "Spam/Ads",
"other": "Other",
"thousand": "k",
"million": "M",
"billion": "B"
},
"comment": {
"flagged": "flagged",
"anon": "Anonymous",
"ban_user": "Ban User",
"view_context": "View context",
"banned_user": "Banned User"
},
"user": {
"user_bio": "User Bio",
"bio_flags": "flags for this bio",
"username_flags": "flags for this username"
},
"embedlink": {
"copy": "Copy to Clipboard"
},
"configure": {
"sign-out": "Sign Out",
"shortcuts": "Shortcuts",
"closed-stream-settings": "Closed Stream Message",
"open-stream-configuration": "This comment stream is currently open. By closing this comment stream, no new comments may be submitted and all previous comments will still be displayed.",
"close-stream-configuration": "This comment stream is currently closed. By opening this comment stream, new comments may be submitted and displayed",
"close-stream": "Close Stream",
"open-stream": "Open Stream",
"stream-settings": "Stream Settings",
"moderation-settings": "Moderation Settings",
"tech-settings": "Tech Settings",
"custom-css-url": "Custom CSS URL",
"custom-css-url-desc": "URL of a CSS stylesheet that will override default Embed Stream styles. Can be internal or external.",
"dashboard": "Dashboard",
"enable-pre-moderation": "Enable pre-moderation",
"enable-pre-moderation-text": "Moderators must approve any comment before it is published.",
"require-email-verification": "Require Email Verification",
"require-email-verification-text": "New Users must verify their email before commenting",
"include-comment-stream": "Include Comment Stream Description for Readers",
"include-comment-stream-desc": "Write a message to be added to the top of your comment stream. Pose a topic, include community guidelines, etc.",
"include-text": "Include your text here.",
"enable-premod-links": "Pre-Moderate Comments Containing Links",
"enable-premod-links-text": "Moderators must approve any comment containing a link before its published.",
"comment-settings": "Settings",
"embed-comment-stream": "Embed Stream",
"banned-word-text": "Comments which contain these words or phrases (not case-sensitive) will be automatically removed from the comment stream. Type a word and press Enter or Tab to add. Optionally paste a comma-separated list.",
"suspect-word-text": "Comments which contain these words or phrases (not case-sensitive) will be highlighted in the comment stream. Type a word and press Enter or Tab to add. Optionally paste a comma-separated list.",
"wordlist": "Banned Words",
"banned-words-title": "Banned words list",
"suspect-words-title": "Suspect words list",
"save-changes": "Save Changes",
"copy-and-paste": "Copy and paste code below into your CMS to embed your comment box in your articles",
"moderate": "Moderate",
"configure": "Configure",
"community": "Community",
"stories": "Stories",
"closed-comments-desc": "Write a message to be displayed when when your comment stream is closed and no longer accepting comments.",
"closed-comments-label": "Write a message...",
"hours": "Hours",
"days": "Days",
"weeks": "Weeks",
"close-after": "Close comments after",
"comment-count-header": "Limit Comment Length",
"comment-count-text-pre": "Comments will be limited to ",
"comment-count-text-post": " characters",
"comment-count-error": "Please enter a valid number.",
"domain-list-title": "Permitted Domains",
"domain-list-text": "Enter the domains you would like to permit for Talk, e.g. your local, staging and production environments (ex. localhost:3000, staging.domain.com, domain.com)."
},
"bandialog": {
"ban_user": "Ban User?",
"are_you_sure": "Are you sure you would like to ban {0}?",
"note": "Note: Banning this user will also place this comment in the Rejected queue.",
"cancel": "Cancel",
"yes_ban_user": "Yes, Ban User"
},
"suspenduser": {
"title": "Suspend a user",
"title_0": "We noticed you rejected a username",
"description_0": "Would you like to temporarily ban this user because of their {0}? Doing so will temporarily hide their comments until they rewrite their {0}.",
"title_1": "Notify the user of their temporary suspension",
"description_1": "Suspending this user will temporarily disable their account and hide all of their comments on the site.",
"no_cancel": "No, cancel",
"yes_suspend": "Yes, suspend",
"send": "Send",
"bio": "bio",
"username": "username",
"email_subject": "Your account has been suspended",
"email": "Another member of the community recently flagged your username for review. Because of its content your user was rejected. This means you can no longer comment, like, or flag content until you rewrite your username. Please e-mail us if you have any questions or concerns.",
"write_message": "Write a message"
},
"dashboard": {
"next-update": "{0} minutes until next update.",
"auto-update": "Data automatically updates every five minutes or when you Reload.",
"no_flags": "There have been no flags in the last 5 minutes! Hooray!",
"no_likes": "There have been no likes in the last 5 minutes. All quiet.",
"flags": "Flags",
"no_activity": "There haven't been any comments anywhere in the last five minutes.",
"comment_count": "comments",
"most_flags": "Articles with the most flags"
},
"streams": {
"empty_result": "No assets match this search. Maybe try widening your search?",
"search": "Search",
"filter-streams": "Filter Streams",
"stream-status": "Stream Status",
"all": "All",
"open": "Open",
"closed": "Closed",
"newest": "Newest",
"oldest": "Oldest",
"sort-by": "Sort By",
"open": "Open",
"closed": "Closed",
"article": "Story",
"pubdate": "Publication Date",
"status": "Stream Status"
}
},
"es": {
"errors": {
"NOT_AUTHORIZED": "Acción no autorizada.",
"LOGIN_MAXIMUM_EXCEEDED": "Ha realizado demasiados intentos fallidos de colocar la contraseña. Por favor espere."
},
"community": {
"username_and_email": "Usuario y E-mail",
"account_creation_date": "Fecha de creación de la cuenta",
"newsroom_role": "Rol en la redacción",
"admin": "Administradora",
"moderator": "Moderadora",
"role": "Seleccionar rol...",
"no-results": "No se encontraron usuarixs con ese nombre de usuario o e-mail.",
"status": "Estado",
"select-status": "Seleccionar estado...",
"active": "Activa",
"banned": "Suspendido",
"banned-user": "Usuario Suspendido",
"loading": "Cargando resultados",
"flags": "Reporte",
"flaggedaccounts": "Nombres de Usuario Reportados",
"people": "Gente",
"no-flagged-accounts": "No hay ninguna cuenta reportada.",
"I don't like this username": "No me gusta ese nombre de usuario",
"This user is impersonating": "Suplantación",
"This looks like an ad/marketing": "Spam/Propaganda",
"This username is offensive": "Ofensivo",
"Other": "Otros",
"ban_user": "Quieres suspender al Usuario?",
"are_you_sure": "Estas segura que quieres suspender a {0}?",
"note": "Nota: Suspender a este usuario no le va a permitir (al usuario) borrar ni editar ni comentar.",
"cancel": "Cancelar",
"yes_ban_user": "Si, Suspendan el usuario"
},
"suspenduser": {
"title": "Suspendiendo un usuario",
"title_0": "Esta queriendo suspender un usuario?",
"description_0": "Le gustaria suspender a esta usuaria temporarianmente por su nombre de usuario? Si lo hace sus comentarios serán escondidos temporariamente hasta que puedan reescribir su nombre de usuario.",
"title_1": "Enviarle una nota al usuario sobre su cuenta suspendida",
"description_1": "Si suspende a este usuario, su cuenta va a ser deshabilitada y todos sus comentarios escondidos del sitio.",
"no_cancel": "No, cancelar",
"yes_suspend": "Si, suspender",
"send": "Enviar",
"username": "nombre de usuario",
"email_subject": "Su cuenta ha sido suspendida temporariamente",
"email": "Otra persona de la comunidad recientemente marcó su nombre de usuario para ser revisado. Por su contenido, el nombre de usuario ha sido rechazado. Esto quiere decir que no puede comentar, gustar o marcar contenido hasta que modifique su nombre de usuario. Por favor, envienos un correo a moderator@newsorg.com si tiene alguna pregunta o preocupación",
"write_message": "Escribir un mensaje",
"loading": "Cargando resultados"
},
"modqueue": {
"all": "todos",
"approved": "aprobado",
"likes": "gustos",
"premod": "pre-mod",
"rejected": "rechazado",
"flagged": "marcado",
"shortcuts": "Atajos de teclado",
"mod-faster": "Moderar más rápido con atajos del teclado",
"try-these": "Intenta estos",
"view-more-shortcuts": "Ver más atajos",
"shift-key": "⇧",
"close": "Cerrar",
"emptyqueue": "No se encontro ningún usuario. Están escondidos.",
"showshortcuts": "Mostrar atajos",
"more-detail": "Mas detalle",
"less-detail": "Menos detalle",
"dont-like-username": "No me gusta ese nombre de usuario",
"impersonating": "Suplantación",
"offensive": "Ofensivo",
"spam/ads": "Spam/Propaganda",
"other": "Otros",
"thousand": "m",
"million": "M",
"billion": "B"
},
"comment": {
"flagged": "marcado",
"anon": "Anónimo",
"view_context": "Ver contexto",
"ban_user": "Suspender Usuario",
"banned_user": "Usuario Suspendido"
},
"user": {
"user_bio": "marcas para este usuario",
"bio_flags": "marcas para esta biografia",
"username_flags": "marcas para este nombre de usuario"
},
"configure": {
"sign-out": "Desconectar",
"shortcuts": "Atajos",
"closed-stream-settings": "Mensaje a enviar cuando los comentarios están cerrados en el artículo",
"open-stream-configuration": "Este hilo de comentarios esta abierto. Al cerrarlo, ningún nuevo comentario será publicado y todos los comentarios anteriores serán mostrados.",
"close-stream-configuration": "Este hilo de comentario está en este momento cerrado. Al abrirlo, nuevos comentarios serán publicaods y mostrados.",
"close-stream": "Cerrar Comentarios",
"open-stream": "Abrir Comentarios",
"stream-settings": "Configuración de Comentarios",
"moderation-settings": "Configuración de Moderación",
"tech-settings": "Configuración Técnica",
"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.",
"dashboard": "Panel",
"enable-pre-moderation": "Habilitar pre-moderación",
"enable-pre-moderation-text": "Los moderadores deben aprobar cada comentario antes de que sea publicado.",
"require-email-verification": "Necesita confirmación de e-mail",
"require-email-verification-text": "Nuevos usuarios deben verificar sus e-mails antes de comentar",
"include-comment-stream": "Incluir la Descripción a un Hilo de Comentario para los y las Lectoras.",
"include-comment-stream-desc": "Escribir un mensaje que será agregado a la parte de arriba del tu hilo de comentarios. Por ejemplo, un tema, guias de comunidad, etc.",
"include-text": "Incluir tu texto aqui.",
"comment-settings": "Configuración de Comentarios",
"embed-comment-stream": "Colocar Hilo de Comentarios",
"enable-premod-links": "Pre-Moderar Commentarios que contienen Enlaces",
"enable-premod-links-text": "Los y las Moderadoras deben aprobar cualquier comentario que contengan links antes de su publicación.",
"wordlist": "Palabras Suspendidas y Sospechosas",
"banned-word-text": "Comentarios que contengan estas palabras o frases, no separadas por comas y en mayusculas o minusuculas, serán automaticamente marcadas para separar los comentarios publicados.",
"suspect-word-text": "Comentarios que contengan estas palabras o frases, considerando mayusculas y minusculas, serán automaticamente destacadas en los comentarios publicados. Escribir una palabra y apretar Enter o Tabulador para agergarla. Opcionalmente pegar una lista separada por coma.",
"banned-words-title": "Lista de palabras prohibidas",
"suspect-words-title": "Lista de palabras sospechosas",
"save-changes": "Guardar Cambios",
"copy-and-paste": "Copiar y pegar el código de más abajo en tu CMS para colocar la caja de comentarios en tus articulos",
"moderate": "Moderar",
"configure": "Configurar",
"community": "Comunidad",
"stories": "Artículos",
"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...",
"never": "Nunca",
"hours": "Horas",
"days": "Días",
"weeks": "Semanas",
"close-after": "Cerrar comentarios luego de",
"comment-count-header": "Limitar el largo del comentario",
"comment-count-text-pre": "El largo de comentarios será ",
"comment-count-text-post": " caracteres",
"comment-count-error": "Por favor escribe un número válido.",
"domain-list-title": "Lista de Dominios Permitidos",
"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)."
},
"embedlink": {
"copy": "Copiar"
},
"bandialog": {
"ban_user": "¿Quieres suspender el Usuario?",
"are_you_sure": "¿Estás segura que quieres suspender a {0}?",
"note": "Nota: Suspender a este usuario también va a colocar este comentario en la cola de Rechazados.",
"cancel": "Cancelar",
"yes_ban_user": "Si, Suspendan el usuario"
},
"dashboard": {
"next-update": "{0} minutos hasta la siguiente actualización.",
"auto-update": "Los datos se actualizan automaticamente cada 5 minutos o cuando recargas.",
"no_flags": "¡Nadie ha marcado nada en los últimos 5 minutos! ¡Bravo!",
"no_likes": "A nadie le ha gustado algún comentario en los últimos 5 minutos. Todo tranquilo.",
"flags": "Marcados",
"no_activity": "No hubo comentarios en los ultimos 5 minutos",
"comment_count": "comentarios",
"most_flags": "Articulos con más reportes"
},
"streams": {
"empty_result": "No se encuentro articulo con esta busqueda. ¿Tal vez puedas extender la busqueda?",
"search": "buscar",
"filter-streams": "Filtrar Hilos de Comentarios",
"stream-status": "Estado del Hilo de Comentarios",
"all": "todxs",
"open": "abrir",
"closed": "cerrado",
"newest": "más nuevoß",
"oldest": "más viejo",
"sort-by": "ordenar por",
"article": "artículo",
"pubdate": "Fecha de Pblicación",
"status": "Estado"
}
}
}
@@ -1,23 +1,22 @@
import React from 'react';
import {Button} from 'coral-ui';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
export default ({status, onClick}) => (
status === 'open' ? (
<div className="close-comments-intro-wrapper">
<p>
{lang.t('configure.open_stream_configuration')}
{t('configure.open_stream_configuration')}
</p>
<Button onClick={onClick}>{lang.t('configure.close_stream')}</Button>
<Button onClick={onClick}>{t('configure.close_stream')}</Button>
</div>
) : (
<div className="close-comments-intro-wrapper">
<p>
{lang.t('configure.close_stream_configuration')}
{t('configure.close_stream_configuration')}
</p>
<Button onClick={onClick}>{lang.t('configure.open_stream')}</Button>
<Button onClick={onClick}>{t('configure.open_stream')}</Button>
</div>
)
);
@@ -3,22 +3,21 @@ import {Button, Checkbox, TextField} from 'coral-ui';
import styles from './ConfigureCommentStream.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
export default ({handleChange, handleApply, changed, ...props}) => (
<form onSubmit={handleApply}>
<div className={styles.wrapper}>
<div className={styles.container}>
<h3>{lang.t('configure.title')}</h3>
<h3>{t('configure.title')}</h3>
<Button
type="submit"
className={styles.apply}
onChange={handleChange}
cStyle={changed ? 'green' : 'darkGrey'} >
{lang.t('configure.apply')}
{t('configure.apply')}
</Button>
<p>{lang.t('configure.description')}</p>
<p>{t('configure.description')}</p>
</div>
<ul>
<li>
@@ -29,8 +28,8 @@ export default ({handleChange, handleApply, changed, ...props}) => (
onChange={handleChange}
defaultChecked={props.premod}
info={{
title: lang.t('configure.enable_premod'),
description: lang.t('configure.enable_premod_description')
title: t('configure.enable_premod'),
description: t('configure.enable_premod_description')
}} />
</li>
<li>
@@ -41,8 +40,8 @@ export default ({handleChange, handleApply, changed, ...props}) => (
onChange={handleChange}
defaultChecked={props.premodLinksEnable}
info={{
title: lang.t('configure.enable_premod_links'),
description: lang.t('configure.enable_premod_links_description')
title: t('configure.enable_premod_links'),
description: t('configure.enable_premod_links_description')
}} />
</li>
<li>
@@ -53,8 +52,8 @@ export default ({handleChange, handleApply, changed, ...props}) => (
onChange={handleChange}
defaultChecked={props.questionBoxEnable}
info={{
title: lang.t('configure.enable_questionbox'),
description: lang.t('configure.enable_questionbox_description')
title: t('configure.enable_questionbox'),
description: t('configure.enable_questionbox_description')
}} />
<div className={`${props.questionBoxEnable ? null : styles.hidden}`} >
<TextField
@@ -62,7 +61,7 @@ export default ({handleChange, handleApply, changed, ...props}) => (
onChange={handleChange}
rows={3}
value={props.questionBoxContent}
label={lang.t('configure.include_question_here')}
label={t('configure.include_question_here')}
/>
</div>
</li>
@@ -2,15 +2,12 @@ import React, {Component} from 'react';
import {connect} from 'react-redux';
import {compose} from 'react-apollo';
import {I18n} from 'coral-framework';
import {updateOpenStatus, updateConfiguration} from 'coral-framework/actions/asset';
import timeago from 'timeago.js';
import CloseCommentsInfo from '../components/CloseCommentsInfo';
import ConfigureCommentStream from '../components/ConfigureCommentStream';
const lang = new I18n();
import {t, timeago} from 'coral-i18n/services/i18n';
class ConfigureStreamContainer extends Component {
constructor (props) {
@@ -89,7 +86,7 @@ class ConfigureStreamContainer extends Component {
const {closedTimeout} = this.props.asset.settings;
const {created_at} = this.props.asset;
return timeago().format(new Date(created_at).getTime() + (1000 * closedTimeout), lang.getLocale().replace('-', '_'));
return timeago(new Date(created_at).getTime() + (1000 * closedTimeout));
}
render () {
@@ -110,8 +107,8 @@ class ConfigureStreamContainer extends Component {
questionBoxContent={dirtySettings.questionBoxContent}
/>
<hr />
<h3>{closedAt === 'open' ? 'Close' : 'Open'} Comment Stream</h3>
{(closedAt === 'open' && closedTimeout) ? <p>The comment stream will close in {this.getClosedIn()}.</p> : ''}
<h3>{closedAt === 'open' ? 'Close' : 'Open'} {t('configure.comment_stream')}</h3>
{(closedAt === 'open' && closedTimeout) ? <p>{t('configure.comment_stream_will_close')} {this.getClosedIn()}.</p> : ''}
<CloseCommentsInfo
onClick={this.toggleStatus}
status={closedAt}
@@ -1,7 +1,5 @@
import React, {PropTypes} from 'react';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
/**
* Countdown the number of seconds until a given Date
@@ -38,7 +36,7 @@ export class CountdownSeconds extends React.Component {
const secRemaining = msRemaining / 1000;
const wholeSecRemaining = Math.floor(secRemaining);
const plural = secRemaining !== 1;
const units = lang.t(plural ? 'editComment.secondsPlural' : 'editComment.second');
const units = t(plural ? 'editComment.secondsPlural' : 'editComment.second');
let classFromProp;
if (typeof classNameForMsRemaining === 'function') {
classFromProp = classNameForMsRemaining(msRemaining);
@@ -6,8 +6,7 @@ import {CountdownSeconds} from './CountdownSeconds';
import {getEditableUntilDate} from './util';
import {Icon} from 'coral-ui';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
/**
* Renders a Comment's body in such a way that the end-user can edit it and save changes
@@ -82,11 +81,11 @@ export class EditableCommentContent extends React.Component {
successfullyEdited = true;
} catch (error) {
if (error.translation_key) {
addNotification('error', lang.t(`error.${error.translation_key}`));
addNotification('error', t(`error.${error.translation_key}`));
} else if (error.networkError) {
addNotification('error', lang.t('error.networkError'));
addNotification('error', t('error.networkError'));
} else {
addNotification('error', lang.t('editComment.unexpectedError'));
addNotification('error', t('editComment.unexpectedError'));
throw error;
}
}
@@ -115,9 +114,9 @@ export class EditableCommentContent extends React.Component {
return (comment.body !== originalBody) && !editWindowExpired;
}}
saveComment={this.editComment}
bodyLabel={lang.t('editComment.bodyInputLabel')}
bodyLabel={t('editComment.bodyInputLabel')}
bodyPlaceholder=""
submitText={<span>{lang.t('editComment.saveButton')}</span>}
submitText={<span>{t('editComment.saveButton')}</span>}
saveButtonCStyle="green"
cancelButtonClicked={this.props.stopEditing}
buttonClass={styles.button}
@@ -127,15 +126,15 @@ export class EditableCommentContent extends React.Component {
{
editWindowExpired
? <span>
{lang.t('editComment.editWindowExpired')}
{t('editComment.editWindowExpired')}
{
typeof this.props.stopEditing === 'function'
? <span>&nbsp;<a className={styles.link} onClick={this.props.stopEditing}>{lang.t('editComment.editWindowExpiredClose')}</a></span>
? <span>&nbsp;<a className={styles.link} onClick={this.props.stopEditing}>{t('editComment.editWindowExpiredClose')}</a></span>
: null
}
</span>
: <span>
<Icon name="timer"/> {lang.t('editComment.editWindowTimerPrefix')}
<Icon name="timer"/> {t('editComment.editWindowTimerPrefix')}
<CountdownSeconds
until={editableUntil}
classNameForMsRemaining={(remainingMs) => (remainingMs <= 10 * 1000) ? styles.editWindowAlmostOver : '' }
@@ -1,7 +1,5 @@
import React from 'react';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
import {TabBar, Tab, TabContent, Button} from 'coral-ui';
@@ -47,7 +45,7 @@ export default class Embed extends React.Component {
<div className="commentStream">
<TabBar onChange={this.changeTab} activeTab={activeTab}>
<Tab><Count count={totalCommentCount}/></Tab>
<Tab>{lang.t('framework.my_profile')}</Tab>
<Tab>{t('framework.my_profile')}</Tab>
<Tab restricted={!isAdmin}>Configure Stream</Tab>
</TabBar>
{
@@ -57,7 +55,7 @@ export default class Embed extends React.Component {
style={{float: 'right'}}
onClick={viewAllComments}
>
{lang.t('framework.show_all_comments')}
{t('framework.show_all_comments')}
</Button>
}
<TabContent show={activeTab === 'stream'}>
@@ -1,7 +1,6 @@
import React from 'react';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
// Render in place of a Comment when the author of the comment is ignored
const IgnoredCommentTombstone = () => (
@@ -13,7 +12,7 @@ const IgnoredCommentTombstone = () => (
padding: '1em',
color: '#3E4F71',
}}>
{lang.t('framework.comment_is_ignored')}
{t('framework.comment_is_ignored')}
</p>
</div>
);
@@ -1,9 +1,7 @@
import React, {PropTypes} from 'react';
import I18n from 'coral-i18n/modules/i18n/i18n';
import {ADDTL_COMMENTS_ON_LOAD_MORE} from '../constants/stream';
import {Button} from 'coral-ui';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const loadMoreComments = (assetId, comments, loadMore, parentId, replyCount) => {
@@ -31,13 +29,13 @@ class LoadMore extends React.Component {
replyCountFormat = (count) => {
if (count === 1) {
return lang.t('framework.view_reply');
return t('framework.view_reply');
}
if (this.initialState) {
return lang.t('framework.view_all_repliesInitial', count);
return t('framework.view_all_repliesInitial', count);
} else {
return lang.t('framework.view_all_replies', count);
return t('framework.view_all_replies', count);
}
}
@@ -50,7 +48,7 @@ class LoadMore extends React.Component {
this.initialState = false;
loadMoreComments(assetId, comments, loadMore, parentId, replyCount);
}}>
{topLevel ? lang.t('framework.view_more_comments') : this.replyCountFormat(replyCount)}
{topLevel ? t('framework.view_more_comments') : this.replyCountFormat(replyCount)}
</Button>
</div>
: null;
@@ -1,7 +1,6 @@
import React, {PropTypes} from 'react';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const onLoadMoreClick = ({loadMore, commentCount, firstCommentDate, assetId, setCommentCountCache}) => (e) => {
e.preventDefault();
@@ -22,8 +21,8 @@ const NewCount = (props) => {
props.commentCountCache && newComments > 0 ?
<button onClick={onLoadMoreClick(props)}>
{newComments === 1
? lang.t('framework.new_count', newComments, lang.t('comment'))
: lang.t('framework.new_count', newComments, lang.t('comments'))}
? t('framework.new_count', newComments, t('comment'))
: t('framework.new_count', newComments, t('comments'))}
</button>
: null
}
+4
View File
@@ -12,6 +12,10 @@ import localStore, {injectReducers} from 'coral-framework/services/store';
import AppRouter from './AppRouter';
import {pym} from 'coral-framework';
import {loadTranslations} from 'coral-i18n/services/i18n';
Promise.all([loadTranslations()]);
injectReducers(reducers);
const store = (window.opener && window.opener.coralStore) ? window.opener.coralStore : localStore;
+3 -4
View File
@@ -2,8 +2,7 @@ import * as actions from '../constants/asset';
import coralApi from '../helpers/response';
import {addNotification} from '../actions/notification';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
export const fetchAssetRequest = () => ({type: actions.FETCH_ASSET_REQUEST});
export const fetchAssetSuccess = (asset) => ({type: actions.FETCH_ASSET_SUCCESS, asset});
@@ -18,7 +17,7 @@ export const updateConfiguration = (newConfig) => (dispatch, getState) => {
dispatch(updateAssetSettingsRequest());
coralApi(`/assets/${assetId}/settings`, {method: 'PUT', body: newConfig})
.then(() => {
dispatch(addNotification('success', lang.t('framework.success_update_settings')));
dispatch(addNotification('success', t('framework.success_update_settings')));
dispatch(updateAssetSettingsSuccess(newConfig));
})
.catch((error) => dispatch(updateAssetSettingsFailure(error)));
@@ -29,7 +28,7 @@ export const updateOpenStream = (closedBody) => (dispatch, getState) => {
dispatch(fetchAssetRequest());
coralApi(`/assets/${assetId}/status`, {method: 'PUT', body: closedBody})
.then(() => {
dispatch(addNotification('success', lang.t('framework.success_update_settings')));
dispatch(addNotification('success', t('framework.success_update_settings')));
dispatch(fetchAssetSuccess(closedBody));
})
.catch((error) => dispatch(fetchAssetFailure(error)));
+5 -6
View File
@@ -4,8 +4,7 @@ import * as actions from '../constants/auth';
import coralApi, {base} from '../helpers/response';
import jwtDecode from 'jwt-decode';
const lang = new I18n();
import I18n from '../../coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
// Dialog Actions
export const showSignInDialog = () => (dispatch) => {
@@ -69,7 +68,7 @@ export const createUsername = (userId, formData) => (dispatch) => {
dispatch(updateUsername(formData));
})
.catch((error) => {
dispatch(createUsernameFailure(lang.t(`error.${error.translation_key}`)));
dispatch(createUsernameFailure(t(`error.${error.translation_key}`)));
});
};
@@ -132,12 +131,12 @@ export const fetchSignIn = (formData) => (dispatch) => {
// the user might not have a valid email. prompt the user user re-request the confirmation email
dispatch(
signInFailure(lang.t('error.email_not_verified', error.metadata))
signInFailure(t('error.email_not_verified', error.metadata))
);
} else {
// invalid credentials
dispatch(signInFailure(lang.t('error.email_password')));
dispatch(signInFailure(t('error.email_password')));
}
});
};
@@ -221,7 +220,7 @@ export const fetchSignUp = (formData, redirectUri) => (dispatch) => {
dispatch(signUpSuccess(user));
})
.catch((error) => {
let errorMessage = lang.t(`error.${error.message}`);
let errorMessage = t(`error.${error.message}`);
// if there is no translation defined, just show the error string
if (errorMessage === `error.${error.message}`) {
+3 -4
View File
@@ -2,8 +2,7 @@ import {addNotification} from '../actions/notification';
import coralApi from '../helpers/response';
import * as actions from '../constants/auth';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const editUsernameFailure = (error) => ({type: actions.EDIT_USERNAME_FAILURE, error});
const editUsernameSuccess = () => ({type: actions.EDIT_USERNAME_SUCCESS});
@@ -12,9 +11,9 @@ export const editName = (username) => (dispatch) => {
return coralApi('/account/username', {method: 'PUT', body: {username}})
.then(() => {
dispatch(editUsernameSuccess());
dispatch(addNotification('success', lang.t('framework.success_name_update')));
dispatch(addNotification('success', t('framework.success_name_update')));
})
.catch((error) => {
dispatch(editUsernameFailure(lang.t(`error.${error.translation_key}`)));
dispatch(editUsernameFailure(t(`error.${error.translation_key}`)));
});
};
@@ -1,10 +1,9 @@
import React from 'react';
import styles from './RestrictedContent.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
export default ({children, restricted, message = lang.t('framework.content_not_available'), restrictedComp}) => {
export default ({children, restricted, message = t('framework.content_not_available'), restrictedComp}) => {
if (restricted) {
return restrictedComp ? restrictedComp : messageBox(message);
} else {
@@ -1,7 +1,6 @@
import React, {Component, PropTypes} from 'react';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
import styles from './RestrictedContent.css';
import {Button} from 'coral-ui';
@@ -28,10 +27,10 @@ class SuspendedAccount extends Component {
editName(username)
.then(() => location.reload())
.catch((error) => {
this.setState({alert: lang.t(`error.${error.translation_key}`)});
this.setState({alert: t(`error.${error.translation_key}`)});
});
} else {
this.setState({alert: lang.t('framework.edit_name.error')});
this.setState({alert: t('framework.edit_name.error')});
}
}
@@ -43,8 +42,8 @@ class SuspendedAccount extends Component {
return <div className={styles.message}>
<span>{
canEditName ?
lang.t('framework.edit_name.msg')
: lang.t('framework.banned_account_msg')
t('framework.edit_name.msg')
: t('framework.banned_account_msg')
}</span>
{
canEditName ?
@@ -56,20 +55,20 @@ class SuspendedAccount extends Component {
htmlFor='username'
className="screen-reader-text"
aria-hidden={true}>
{lang.t('framework.edit_name.label')}
{t('framework.edit_name.label')}
</label>
<input
type='text'
className={styles.editNameInput}
value={username}
placeholder={lang.t('framework.edit_name.label')}
placeholder={t('framework.edit_name.label')}
id='username'
onChange={(e) => this.setState({username: e.target.value})}
rows={3}/><br/>
<Button
onClick={this.onSubmitClick}>
{
lang.t('framework.edit_name.button')
t('framework.edit_name.button')
}
</Button>
</div> : null
+6 -7
View File
@@ -1,10 +1,9 @@
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
export default {
email: lang.t('error.email'),
password: lang.t('error.password'),
username: lang.t('error.username'),
confirmPassword: lang.t('error.confirm_password'),
organizationName: lang.t('error.organization_name'),
email: t('error.email'),
password: t('error.password'),
username: t('error.username'),
confirmPassword: t('error.confirm_password'),
organizationName: t('error.organization_name'),
};
+3 -2
View File
@@ -1,12 +1,13 @@
import pym from './services/PymConnection';
import I18n from '../coral-i18n/modules/i18n/i18n';
import actions from './actions';
import {loadTranslations} from '../coral-i18n/services/i18n';
// TODO (bc): Deprecate old actions. Spreading actions is now needed.
Promise.all([loadTranslations()]);
export default {
pym,
I18n,
actions,
...actions
};
-110
View File
@@ -1,110 +0,0 @@
{
"en": {
"MY_COMMENTS": "My Comments",
"profile": "Profile",
"myProfile": "My 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",
"bannedAccountMsg": "Your account is currently suspended. This means that you cannot Like, Report, or write comments. Please contact us if you have any questions.",
"editName": {
"msg": "Your account is currently suspended because your username has been deemed inappropriate. To restore your account, please enter a new username. Please contact us if you have any questions.",
"label": "New Username",
"button": "Submit",
"error": "Usernames can contain letters, numbers and _ only"
},
"viewMoreComments": "view more comments",
"showAllComments": "Show all comments",
"viewReply": "view reply",
"viewAllRepliesInitial": "view all {0} replies",
"viewAllReplies": "view {0} replies",
"newCount": "View {0} new {1}",
"comment": "comment",
"comments": "comments",
"commentIsIgnored": "This comment is hidden because you ignored this user.",
"editComment": {
"bodyInputLabel": "Edit this comment",
"saveButton": "Save changes",
"editWindowExpired": "You can no longer edit this comment. The time window to do so has expired. Why not post another one?",
"editWindowExpiredClose": "Close",
"editWindowTimerPrefix": "Edit Window: ",
"second": "second",
"secondsPlural": "seconds",
"unexpectedError": "Unexpected error while saving changes. Sorry!"
},
"error": {
"COMMENT_TOO_SHORT": "Your comment must have something in it",
"EDIT_WINDOW_ENDED": "You can no longer edit this comment. The time window to do so has expired.",
"emailNotVerified": "Email address {0} not verified.",
"email": "Not a valid E-Mail",
"networkError": "Failed to connect to server. Check your internet connection and try again.",
"password": "Password must be at least 8 characters",
"username": "Usernames can contain letters, numbers and _ only",
"confirmPassword": "Passwords don't match. Please, check again",
"organizationName": "Organization name must only contain letters or numbers.",
"emailPasswordError": "Email and/or password combination incorrect.",
"EMAIL_REQUIRED": "An email address is required",
"PASSWORD_REQUIRED": "Must input a password",
"PASSWORD_LENGTH": "Password is too short",
"EMAIL_IN_USE": "Email address already in use",
"EMAIL_USERNAME_IN_USE": "Email address or username already in use",
"USERNAME_IN_USE": "Username already in use",
"USERNAME_REQUIRED": "Must input a username",
"NO_SPECIAL_CHARACTERS": "Usernames can contain letters, numbers and _ only",
"PROFANITY_ERROR": "Usernames must not contain profanity. Please contact the administrator if you believe this to be in error.",
"NOT_AUTHORIZED": "Not authorized.",
"EDIT_USERNAME_NOT_AUTHORIZED": "You do not have permission to update your username."
}
},
"es": {
"profile": "Pérfil",
"MY_COMMENTS": "Mis Comentarios",
"myProfile": "Mi pérfil",
"successUpdateSettings": "La configuración de este articulo fue actualizada",
"successBioUpdate": "Tu biografia fue actualizada",
"contentNotAvailable": "El contenido no se encuentra disponible",
"bannedAccountMsg": "Tu cuenta se encuentra suspendida. Esto significa que no puedes gustar, marcar o escribir commentarios.",
"editNameMsg": "",
"viewMoreComments": "Ver commentarios más",
"viewReply": "ver respuesta",
"viewAllRepliesInitial": "ver todas las {0} respuestas",
"viewAllReplies": "ver {0} respuestas",
"newCount": "Ver {0} {1} más",
"comment": "commentario",
"comments": "commentarios",
"commentIsIgnored": "Este comentario está escondido porque has ignorado al usuario.",
"showAllComments": "Mostrar todos los comentarios",
"editComment": {
"bodyInputLabel": "Editar este comentario",
"saveButton": "Guardar cambios",
"editWindowExpired": "Ya no puedes editar este comentario. La ventana de tiempo para hacerlo ha caducado. ¿Por qué no publicar otro?",
"editWindowExpiredClose": "Cerca",
"editWindowTimerPrefix": "Ventana de edición: ",
"second": "segundo",
"secondsPlural": "segundos",
"unexpectedError": "Unexpected error while saving changes. Sorry!"
},
"error": {
"editWindowExpired": "Ya no puedes editar este comentario. La ventana de tiempo para hacerlo ha caducado.",
"emailNotVerified": "E-mail {0} no verificado.",
"email": "No es un e-mail válido",
"networkError": "Error al conectar con el servidor. Compruebe su conexión a Internet y vuelva a intentarlo.",
"password": "La contraseña debe tener por lo menos 8 caracteres",
"username": "Los nombres pueden contener letras, números y _",
"organizationName": "El nombre de la organización debe contener letras y/o números.",
"confirmPassword": "Las contraseñas no coinciden",
"emailPasswordError": "E-mail y/o contraseña incorrecta.",
"EMAIL_REQUIRED": "Se requiere un e-mail",
"PASSWORD_REQUIRED": "Debe ingresar una contraseña",
"PASSWORD_LENGTH": "La contraseña es muy corta",
"EMAIL_IN_USE": "El e-mail se encuentra en uso",
"EMAIL_USERNAME_IN_USE": "E-mail o Nombre en uso.",
"USERNAME_IN_USE": "Nombre en uso.",
"USERNAME_REQUIRED": "Debe ingresar un nombre",
"NO_SPECIAL_CHARACTERS": "Los nombres pueden contener letras, números y _",
"PROFANITY_ERROR": "Los nombres no pueden contener blasfemias. Por favor contacte al o la administradora si cree que esto es un error",
"NOT_AUTHORIZED": "Acción no autorizada.",
"EDIT_USERNAME_NOT_AUTHORIZED": "No tiene permiso para editar el nombre de usuario."
}
}
}
+339 -313
View File
@@ -1,321 +1,347 @@
---
bandialog:
are_you_sure: "Are you sure you would like to ban {0}?"
ban_user: "Ban User?"
banned_user: "Banned User"
en:
bandialog:
are_you_sure: "Are you sure you would like to ban {0}?"
ban_user: "Ban User?"
banned_user: "Banned User"
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
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
characters_remaining: "characters remaining"
comment:
anon: Anonymous
ban_user: "Ban User"
comment: "Post a comment"
flagged: flagged
comment_box:
post: "Post"
cancel: "Cancel"
reply: "Reply"
comment: "Post a comment"
name: "Name"
characters_remaining: "characters remaining"
comment:
anon: Anonymous
ban_user: "Ban User"
comment: "Post a comment"
flagged: flagged
view_context: "View context"
comment_box:
post: "Post"
cancel: "Cancel"
reply: "Reply"
comment: "Post a comment"
name: "Name"
comment_post_notif: "Your comment has been posted."
comment_post_notif_premod: "Thank you for posting. Our moderation team will review your comment shortly."
comment_post_banned_word: "Your comment contains one or more words that are not permitted, so it will not be published. If you think this message is incorrect, please contact our moderation team."
characters_remaining: "characters remaining"
comment_is_best: "This comment is one of the best"
comment_offensive: "This comment is offensive"
comment_plural: Comments
comment_post_banned_word: "Your comment contains one or more words that are not permitted, so it will not be published. If you think this message is incorrect, please contact our moderation team."
comment_post_notif: "Your comment has been posted."
comment_post_notif_premod: "Thank you for posting. Our moderation team will review your comment shortly."
comment_post_banned_word: "Your comment contains one or more words that are not permitted, so it will not be published. If you think this message is incorrect, please contact our moderation team."
characters_remaining: "characters remaining"
comment_is_best: "This comment is one of the best"
comment_offensive: "This comment is offensive"
comment_plural: Comments
comment_post_banned_word: "Your comment contains one or more words that are not permitted, so it will not be published. If you think this message is incorrect, please contact our moderation team."
comment_post_notif: "Your comment has been posted."
comment_post_notif_premod: "Thank you for posting. Our moderation team will review your comment shortly."
community:
account_creation_date: "Account Creation Date"
active: Active
admin: Administrator
are_you_sure: "Are you sure you would like to ban {0}?"
ban_user: "Ban User?"
banned: Banned
banned-user: "Banned User"
cancel: Cancel
flaggedaccounts: "Flagged Usernames"
flags: Flags
loading: "Loading results"
moderator: Moderator
newsroom_role: "Newsroom Role"
no-flagged-accounts: "The Account Flags queue is currently empty."
no-results: "No users found with that user name or email address. They're hiding!"
note: "Note: Banning this user will not let them edit comment or remove anything."
other: Other
people: People
role: "Select role..."
select-status: "Select status..."
status: Status
username_and_email: "Username and Email"
yes_ban_user: "Yes Ban User"
configure:
apply: Apply
banned_word_text: "Comments which contain these words or phrases (not case-sensitive) will be automatically removed from the comment stream. Type a word and press Enter or Tab to add. Optionally paste a comma-separated list."
banned_words_title: "Banned words list"
close_after: "Close comments after"
close_stream: "Close Stream"
close_stream_configuration: "This comment stream is currently closed. By opening this comment stream new comments may be submitted and displayed"
closed_comments_desc: "Write a message to be displayed when when your comment stream is closed and no longer accepting comments."
closed_comments_label: "Write a message..."
closed_stream_settings: "Closed Stream Message"
comment_count_error: "Please enter a valid number."
comment_count_header: "Limit Comment Length"
comment_count_text_post: characters
comment_count_text_pre: "Comments will be limited to"
comment_settings: Settings
community: Community
configure: Configure
copy_and_paste: "Copy and paste code below into your CMS to embed your comment box in your articles"
custom_css_url: "Custom CSS URL"
custom_css_url_desc: "URL of a CSS stylesheet that will override default Embed Stream styles. Can be internal or external."
dashboard: Dashboard
days: Days
description: "As an admin you may customize the settings for the comment stream for this asset"
domain_list_text: "Enter the domains you would like to permit for Talk e.g. your local staging and production environments (ex. localhost:3000 staging.domain.com domain.com)."
domain_list_title: "Permitted Domains"
embed_comment_stream: "Embed Stream"
enable-premod-links-text: "Moderators must approve any comment containing a link before its published."
enable_pre_moderation: "Enable pre-moderation"
enable_pre_moderation_text: "Moderators must approve any comment before it is published."
enable_premod_links: "Pre-Moderate Comments Containing Links"
enable_premod: "Enable Premoderation"
enable_premod_description: "Moderators must approve any comment before its published."
enable_premod_links_description: "Moderators must approve any comment containing a link before its published."
enable_questionbox: "Ask readers a question"
enable_questionbox_description: "This question will appear at the top of this comment stream. Ask readers about a certain issue in the article or pose discussion questions etc."
hours: Hours
include_comment_stream: "Include Comment Stream Description for Readers"
include_comment_stream-desc: "Write a message to be added to the top of your comment stream. Pose a topic include community guidelines etc."
include_text: "Include your text here."
include_question_here: "Write your question here."
moderate: Moderate
moderation_settings: "Moderation Settings"
open_stream: "Open Stream"
open_stream_configuration: "This comment stream is currently open. By closing this comment stream no new comments may be submitted and all previous comments will still be displayed."
require_email_verification: "Require Email Verification"
require_email_verification_text: "New Users must verify their email before commenting"
save_changes: "Save Changes"
shortcuts: Shortcuts
sign_out: "Sign Out"
stories: Stories
stream_settings: "Stream Settings"
suspect-words-title: "Suspect words list"
suspect_words_title: "Comments which contain these words or phrases (not case-sensitive) will be highlighted in the comment stream. Type a word and press Enter or Tab to add. Optionally paste a comma-separated list."
tech_settings: "Tech Settings"
title: "Configure Comment Stream"
weeks: Weeks
wordlist: "Banned Words"
continue: Continue
createdisplay:
check_the_form: "Invalid Form. Please check the fields"
continue: "Continue with the same Facebook username"
error_create: "Error when changing username"
fake_comment_body: "This is an example comment. Readers can share their thoughts and opinions with newsrooms in the comments section."
fake_comment_date: "1 minute ago"
if_you_dont_change_your_name: "If you don't change your username at this step your Facebook display name will appear alongside of all your comments."
required_field: "Required field"
save: Save
special_characters: "Usernames can contain letters numbers and _ only"
username: Username
write_your_username: "Edit your username"
your_username: "Your username appears on every comment you post."
dashboard:
auto_update: "Data automatically updates every five minutes or when you Reload."
comment_count: comments
flags: Flags
most_flags: "Articles with the most flags"
next_update: "{0} minutes until next update."
no_activity: "There haven't been any comments anywhere in the last five minutes."
no_flags: "There have been no flags in the last 5 minutes! Hooray!"
no_likes: "There have been no likes in the last 5 minutes. All quiet."
done: Done
embedlink:
copy: "Copy to Clipboard"
error:
comment_too_short: "Your comment must have something in it"
NOT_AUTHORIZED: "Your username or password is not recognized by our system."
NO_SPECIAL_CHARACTERS: "Usernames can contain letters numbers and _ only"
PASSWORD_LENGTH: "Password is too short"
PROFANITY_ERROR: "Usernames must not contain profanity. Please contact the administrator if you believe this to be in error."
USERNAME_IN_USE: "Username already in use"
USERNAME_REQUIRED: "Must input a username"
confirm_password: "Passwords don't match. Please check again"
edit_window_ended: "You can no longer edit this comment. The time window to do so has expired."
edit_username_not_authorized: "You do not have permission to update your username."
email: "Not a valid E-Mail"
network_error: "Failed to connect to server. Check your internet connection and try again."
email_in_use: "Email address already in use"
email_not_verified: "E-mail address {0} not verified."
email_password: "E-mail and/or password combination incorrect."
email_required: "An email address is required"
email_username_in_use: "Email address or username already in use"
login_maximum_exceeded: "You have made too many unsuccessful password attempts. Please wait."
organization_name: "Organization name must only contain letters or numbers."
password: "Password must be at least 8 characters"
password_required: "Must input a password"
username: "Usernames can contain letters numbers and _ only"
flag_comment: "Report comment"
flag_reason: "Reason for reporting (Optional)"
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."
comment: comment
comment_is_ignored: "This comment is hidden because you ignored this user."
comments: comments
content_not_available: "This content is not available"
edit_name:
button: Submit
error: "Usernames can contain letters numbers and _ only"
label: "New Username"
msg: "Your account is currently suspended because your username has been deemed inappropriate. To restore your account please enter a new username. Please contact us if you have any questions."
my_comments: "My Comments"
my_profile: "My profile"
new_count: "View 0 new 1"
profile: Profile
show_all_comments: "Show all comments"
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"
view_all_replies: "view 0 replies"
view_all_replies_initial: "view all 0 replies"
view_more_comments: "view more comments"
view_reply: "view reply"
from_settings_page: "From the Profile Page you can see your comment history."
like: Like
marketing: "This looks like an ad/marketing"
moderate_this_stream: "Moderate this stream"
modqueue:
account: "account flags"
actions: Actions
all: all
approve: "Approve comment"
approved: approved
billion: B
close: Close
dont_like_username: "Don't like username"
empty_queue: "No more comments to moderate! You're all caught up. Go have some ☕️"
flagged: flagged
impersonating: Impersonating
less_detail: "Less detail"
likes: likes
million: M
mod_faster: "Moderate faster with keyboard shortcuts"
more_detail: "More detail"
navigation: Navigation
next_comment: "Go to the next comment"
offensive: Offensive
other: Other
premod: pre-mod
prev_comment: "Go to the previous comment"
reject: "Reject comment"
rejected: rejected
shift_key:
shortcuts: Shortcuts
show_shortcuts: "Show Shortcuts"
singleview: "Toggle single comment edit view"
spam_ads: Spam/Ads
thismenu: "Open this menu"
thousand: k
try_these: "Try these"
view_more_shortcuts: "View more shortcuts"
my_comment_history: "My comment History"
name: Name
no_agree_comment: "I don't agree with this comment"
no_like_bio: "I don't like this bio"
no_like_username: "I don't like this username"
other: Other
permalink: Link
personal_info: "This comment reveals personally identifiable information"
post: Post
profile: Profile
profile_settings: "Profile Settings"
reply: Reply
report: Report
report_notif: "Thank you for reporting this comment. Our moderation team has been notified and will review it shortly."
report_notif_remove: "Your report has been removed."
reported: Reported
set_best: "Tag as Best"
settings:
all_comments: "All Comments"
community:
account_creation_date: "Account Creation Date"
active: Active
admin: Administrator
are_you_sure: "Are you sure you would like to ban {0}?"
ban_user: "Ban User?"
banned: Banned
banned-user: "Banned User"
cancel: Cancel
flaggedaccounts: "Flagged Usernames"
flags: Flags
loading: "Loading results"
moderator: Moderator
newsroom_role: "Newsroom Role"
no-flagged-accounts: "The Account Flags queue is currently empty."
no-results: "No users found with that user name or email address. They're hiding!"
note: "Note: Banning this user will not let them edit comment or remove anything."
other: Other
people: People
role: "Select role..."
select-status: "Select status..."
status: Status
username_and_email: "Username and Email"
yes_ban_user: "Yes Ban User"
configure:
apply: Apply
banned_word_text: "Comments which contain these words or phrases (not case-sensitive) will be automatically removed from the comment stream. Type a word and press Enter or Tab to add. Optionally paste a comma-separated list."
banned_words_title: "Banned words list"
close_after: "Close comments after"
close_stream: "Close Stream"
close_stream_configuration: "This comment stream is currently closed. By opening this comment stream new comments may be submitted and displayed"
closed_comments_desc: "Write a message to be displayed when when your comment stream is closed and no longer accepting comments."
closed_comments_label: "Write a message..."
closed_stream_settings: "Closed Stream Message"
comment_count_error: "Please enter a valid number."
comment_count_header: "Limit Comment Length"
comment_count_text_post: characters
comment_count_text_pre: "Comments will be limited to"
comment_settings: Settings
comment_stream: "Comment Stream"
comment_stream_will_close: "The comment stream will close in"
community: Community
configure: Configure
copy_and_paste: "Copy and paste code below into your CMS to embed your comment box in your articles"
custom_css_url: "Custom CSS URL"
custom_css_url_desc: "URL of a CSS stylesheet that will override default Embed Stream styles. Can be internal or external."
dashboard: Dashboard
days: Days
description: "As an admin you may customize the settings for the comment stream for this asset"
domain_list_text: "Enter the domains you would like to permit for Talk e.g. your local staging and production environments (ex. localhost:3000 staging.domain.com domain.com)."
domain_list_title: "Permitted Domains"
embed_comment_stream: "Embed Stream"
enable-premod-links-text: "Moderators must approve any comment containing a link before its published."
enable_pre_moderation: "Enable pre-moderation"
enable_pre_moderation_text: "Moderators must approve any comment before it is published."
enable_premod_links: "Pre-Moderate Comments Containing Links"
enable_premod: "Enable Premoderation"
enable_premod_description: "Moderators must approve any comment before its published."
enable_premod_links_description: "Moderators must approve any comment containing a link before its published."
enable_questionbox: "Ask readers a question"
enable_questionbox_description: "This question will appear at the top of this comment stream. Ask readers about a certain issue in the article or pose discussion questions etc."
hours: Hours
include_comment_stream: "Include Comment Stream Description for Readers"
include_comment_stream_desc: "Write a message to be added to the top of your comment stream. Pose a topic include community guidelines etc."
include_text: "Include your text here."
include_question_here: "Write your question here."
moderate: Moderate
moderation_settings: "Moderation Settings"
open_stream: "Open Stream"
open_stream_configuration: "This comment stream is currently open. By closing this comment stream no new comments may be submitted and all previous comments will still be displayed."
require_email_verification: "Require Email Verification"
require_email_verification_text: "New Users must verify their email before commenting"
save_changes: "Save Changes"
shortcuts: Shortcuts
sign_out: "Sign Out"
stories: Stories
stream_settings: "Stream Settings"
suspect_word_title: "Suspect wåords list"
suspect_word_text: "Comments which contain these words or phrases (not case-sensitive) will be highlighted in the comment stream. Type a word and press Enter or Tab to add. Optionally paste a comma-separated list."
tech_settings: "Tech Settings"
title: "Configure Comment Stream"
weeks: Weeks
wordlist: "Banned Words"
continue: Continue
createdisplay:
check_the_form: "Invalid Form. Please check the fields"
continue: "Continue with the same Facebook username"
error_create: "Error when changing username"
fake_comment_body: "This is an example comment. Readers can share their thoughts and opinions with newsrooms in the comments section."
fake_comment_date: "1 minute ago"
if_you_dont_change_your_name: "If you don't change your username at this step your Facebook display name will appear alongside of all your comments."
required_field: "Required field"
save: Save
special_characters: "Usernames can contain letters numbers and _ only"
username: Username
write_your_username: "Edit your username"
your_username: "Your username appears on every comment you post."
dashboard:
auto_update: "Data automatically updates every five minutes or when you Reload."
comment_count: comments
flags: Flags
most_flags: "Articles with the most flags"
next_update: "{0} minutes until next update."
no_activity: "There haven't been any comments anywhere in the last five minutes."
no_flags: "There have been no flags in the last 5 minutes! Hooray!"
no_likes: "There have been no likes in the last 5 minutes. All quiet."
done: Done
embedlink:
copy: "Copy to Clipboard"
error:
comment_too_short: "Your comment must have something in it"
NOT_AUTHORIZED: "Your username or password is not recognized by our system."
NO_SPECIAL_CHARACTERS: "Usernames can contain letters numbers and _ only"
PASSWORD_LENGTH: "Password is too short"
PROFANITY_ERROR: "Usernames must not contain profanity. Please contact the administrator if you believe this to be in error."
USERNAME_IN_USE: "Username already in use"
USERNAME_REQUIRED: "Must input a username"
confirm_password: "Passwords don't match. Please check again"
edit_window_ended: "You can no longer edit this comment. The time window to do so has expired."
edit_username_not_authorized: "You do not have permission to update your username."
email: "Not a valid E-Mail"
network_error: "Failed to connect to server. Check your internet connection and try again."
email_in_use: "Email address already in use"
email_not_verified: "E-mail address {0} not verified."
email_password: "E-mail and/or password combination incorrect."
email_required: "An email address is required"
email_username_in_use: "Email address or username already in use"
login_maximum_exceeded: "You have made too many unsuccessful password attempts. Please wait."
organization_name: "Organization name must only contain letters or numbers."
password: "Password must be at least 8 characters"
password_required: "Must input a password"
username: "Usernames can contain letters numbers and _ only"
flag_comment: "Report comment"
flag_reason: "Reason for reporting (Optional)"
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."
comment: comment
comment_is_ignored: "This comment is hidden because you ignored this user."
comments: comments
content_not_available: "This content is not available"
edit_name:
button: Submit
error: "Usernames can contain letters numbers and _ only"
label: "New Username"
msg: "Your account is currently suspended because your username has been deemed inappropriate. To restore your account please enter a new username. Please contact us if you have any questions."
my_comments: "My Comments"
my_profile: "My profile"
new_count: "View 0 new 1"
profile: Profile
show_all_comments: "Show all comments"
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"
view_all_replies: "view 0 replies"
view_all_replies_initial: "view all 0 replies"
view_more_comments: "view more comments"
view_reply: "view reply"
from_settings_page: "From the Profile Page you can see your comment history."
like: Like
loading_results: "Loading Results"
marketing: "This looks like an ad/marketing"
moderate_this_stream: "Moderate this stream"
modqueue:
account: "account flags"
actions: Actions
all: all
approve: "Approve comment"
approved: approved
billion: B
close: Close
dont_like_username: "Don't like username"
empty_queue: "No more comments to moderate! You're all caught up. Go have some ☕️"
flagged: flagged
impersonating: Impersonating
less_detail: "Less detail"
likes: likes
million: M
mod_faster: "Moderate faster with keyboard shortcuts"
more_detail: "More detail"
navigation: Navigation
next_comment: "Go to the next comment"
offensive: Offensive
other: Other
premod: pre-mod
prev_comment: "Go to the previous comment"
reject: "Reject comment"
rejected: rejected
shift_key:
shortcuts: Shortcuts
show_shortcuts: "Show Shortcuts"
singleview: "Toggle single comment edit view"
spam_ads: Spam/Ads
thismenu: "Open this menu"
thousand: k
try_these: "Try these"
view_more_shortcuts: "View more shortcuts"
my_comment_history: "My comment History"
name: Name
no_agree_comment: "I don't agree with this comment"
no_like_bio: "I don't like this bio"
no_like_username: "I don't like this username"
other: Other
permalink: Link
personal_info: "This comment reveals personally identifiable information"
post: Post
profile: Profile
profile_settings: "Profile Settings"
sign_in: "Sign in"
to_access: "to access Profile"
reply: Reply
report: Report
report_notif: "Thank you for reporting this comment. Our moderation team has been notified and will review it shortly."
report_notif_remove: "Your report has been removed."
reported: Reported
set_best: "Tag as Best"
settings:
all_comments: "All Comments"
from_settings_page: "From the Profile Page you can see your comment history."
my_comment_history: "My comment History"
profile: Profile
profile_settings: "Profile Settings"
sign_in: "Sign in"
to_access: "to access Profile"
user_no_comment: "You've never left a comment. Join the conversation!"
sign_in:
email_verify_cta: "Please verify your email address."
request_new_verify_email: "Request another email:"
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"
facebook_sign_in: "Sign in with Facebook"
facebook_sign_up: "Sign up with Facebook"
logout: "Logout"
sign_in: "Sign in"
sign_in_to_join: "Sign in to join the conversation"
or: "Or"
email: "E-mail Address"
password: "Password"
forgot_your_pass: "Forgot your password?"
need_an_account: "Need an account?"
register: "Register"
sign_up: "Sign Up"
confirm_password: "Confirm Password"
username: "Username"
already_have_an_account: "Already have an account?"
recover_password: "Recover password"
email_in_use: "Email address already in use"
email_or_username_in_use: "Email address or Username already in use"
required_field: "This field is required"
passwords_dont_match: "Passwords don't match."
special_characters: "Usernames can contain letters, numbers and _ only"
check_the_form: "Invalid Form. Please, check the fields"
step_1_header: "Report an issue"
step_2_header: "Help us understand"
step_3_header: "Thank you for your input"
streams:
all: All
article: Story
closed: Closed
empty_result: "No assets match this search. Maybe try widening your search?"
filter_streams: "Filter Streams"
newest: Newest
oldest: Oldest
open: Open
pubdate: "Publication Date"
search: Search
sort_by: "Sort By"
status: "Stream Status"
stream_status: "Stream Status"
suspenduser:
bio: bio
description_0: "Would you like to temporarily ban this user because of their {0}? Doing so will temporarily hide their comments until they rewrite their {0}."
description_1: "Suspending this user will temporarily disable their account and hide all of their comments on the site."
email: "Another member of the community recently flagged your username for review. Because of its content your user was rejected. This means you can no longer comment like or flag content until you rewrite your username. Please e-mail us if you have any questions or concerns."
email_subject: "Your account has been suspended"
no_cancel: "No cancel"
send: Send
title: "Suspend a user"
title_0: "We noticed you rejected a username"
title_1: "Notify the user of their temporary suspension"
username: username
write_message: "Write a message"
yes_suspend: "Yes suspend"
thank_you: "We value your safety and feedback. A moderator will review your report."
unset_best: "Untag as Best"
user:
bio_flags: "flags for this bio"
user_bio: "User Bio"
username_flags: "flags for this username"
user_impersonating: "This user is impersonating"
user_no_comment: "You've never left a comment. Join the conversation!"
sign_in:
email_verify_cta: "Please verify your email address."
request_new_verify_email: "Request another email:"
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"
facebook_sign_in: "Sign in with Facebook"
facebook_sign_up: "Sign up with Facebook"
logout: "Logout"
sign_in: "Sign in"
sign_in_to_join: "Sign in to join the conversation"
or: "Or"
email: "E-mail Address"
password: "Password"
forgot_your_pass: "Forgot your password?"
need_an_account: "Need an account?"
register: "Register"
sign_up: "Sign Up"
confirm_password: "Confirm Password"
username: "Username"
already_have_an_account: "Already have an account?"
recover_password: "Recover password"
email_in_use: "Email address already in use"
email_or_username_in_use: "Email address or Username already in use"
required_field: "This field is required"
passwords_dont_match: "Passwords don't match."
special_characters: "Usernames can contain letters, numbers and _ only"
check_the_form: "Invalid Form. Please, check the fields"
step_1_header: "Report an issue"
step_2_header: "Help us understand"
step_3_header: "Thank you for your input"
streams:
all: All
article: Story
closed: Closed
empty_result: "No assets match this search. Maybe try widening your search?"
filter_streams: "Filter Streams"
newest: Newest
oldest: Oldest
open: Open
pubdate: "Publication Date"
search: Search
sort_by: "Sort By"
status: "Stream Status"
stream_status: "Stream Status"
suspenduser:
bio: bio
description_0: "Would you like to temporarily ban this user because of their {0}? Doing so will temporarily hide their comments until they rewrite their {0}."
description_1: "Suspending this user will temporarily disable their account and hide all of their comments on the site."
email: "Another member of the community recently flagged your username for review. Because of its content your user was rejected. This means you can no longer comment like or flag content until you rewrite your username. Please e-mail us if you have any questions or concerns."
email_subject: "Your account has been suspended"
no_cancel: "No cancel"
send: Send
title: "Suspend a user"
title_0: "We noticed you rejected a username"
title_1: "Notify the user of their temporary suspension"
username: username
write_message: "Write a message"
yes_suspend: "Yes suspend"
thank_you: "We value your safety and feedback. A moderator will review your report."
unset_best: "Untag as Best"
user:
bio_flags: "flags for this bio"
user_bio: "User Bio"
username_flags: "flags for this username"
user_impersonating: "This user is impersonating"
user_no_comment: "You've never left a comment. Join the conversation!"
username_offensive: "This username is offensive"
username_offensive: "This username is offensive"
install:
INITIAL:
DESCRIPTION: "Let's set up your Talk community in just a few short steps."
SUBMIT: "Get Started"
ADD_ORGANIZATION:
DESCRIPTION: "Please tell us the name of your organization. This will appear in emails when inviting new team members."
LABEL: "Organization Name"
SAVE: "Save"
CREATE:
EMAIL: "Email address"
USERNAME: "Username"
PASSWORD: "Password"
CONFIRM_PASSWORD: "Confirm Password"
SAVE: "Save"
PERMITTED_DOMAINS:
TITLE: "Permitted domains"
DESCRIPTION: "Enter the domains you would like to permit for Talk, e.g. your local, staging and production environments (ex. localhost:3000, staging.domain.com, domain.com)."
SUBMIT: "Finish install"
FINAL:
DESCRIPTION: "Thanks for installing Talk! We sent an email to verify your email address. While you finish setting up the account, you can start engaging with your readers now."
LAUNCH: "Launch Talk"
CLOSE: "Close this Installer"
+316 -315
View File
@@ -1,321 +1,322 @@
---
bandialog:
are_you_sure: "¿Estás segura que quieres suspender a {0}?"
ban_user: "¿Quieres suspender el Usuario?"
banned_user: "Usuario Suspendido"
es:
bandialog:
are_you_sure: "¿Estás segura que quieres suspender a {0}?"
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."
yes_ban_user: "Si, Suspender el usuario"
bio_offensive: "Esta biografia es ofensiva"
cancel: Cancelar
note: "Nota: Suspender a este usuario también va a colocar este comentario en la cola de Rechazados."
yes_ban_user: "Si, Suspender el usuario"
bio_offensive: "Esta biografia es ofensiva"
cancel: Cancelar
characters_remaining: "carácteres restantes"
comment:
anon: Anónimo
ban_user: "Usuario Suspendido"
comment: "Publicar un comentario"
flagged: reportado
comment_box:
post: "Publicar"
cancel: "Cancelar"
reply: "Responder"
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 estan 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 estan 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.
community:
account_creation_date: Fecha de creación de la cuenta
active: Activa
admin: Administratora
are_you_sure: '¿Estas segura que quieres suspender a {0}?'
ban_user: ¿Quieres suspender al Usuario?
banned: Suspendido
banned-user: Usuarix Suspendido
cancel: Cancelar
flaggedaccounts: Nombres de Usuarix Reportados
flags: Reportes
loading: Cargando resultados
moderator: Moderatora
newsroom_role: Rol en la redacción
no-flagged-accounts: No hay ninguna cuenta reportada en este momento.
no-results: No se encontraron usuarixs con ese nombre o correo.
note: 'Nota: Suspender a este usuario no le va a permitir (al usuario) borrar ni editar ni comentar.'
other: Otro
people: Gente
role: Seleccionar rol...
select-status: Seleccionar estado...
status: Estado
username_and_email: Usuario y E-mail
yes_ban_user: Si, Suspendan el usuario
configure:
apply: Aplicar
banned_word_text: Comentarios que contengan estas palabras o frases, no separadas por comas y en mayusculas o minusuculas, serán automaticamente marcadas para separar los comentarios publicados.
banned_words_title: Lista de palabras prohibidas
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.
closed_comments_label: Escribe un mensaje...
closed_stream_settings: Mensaje que se meustra cuando los comentarios están cerrados 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: cáracteres
comment_count_text_pre: Los comentarios serán limitados a
comment_settings: Configuración
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 articulos
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.
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).
domain_list_title: Dominios Permitidos
embed_comment_stream: Colocar Hilo de Comentarios
enable-premod-links-text: Moderators must approve any comment containing a link before its published.
enable_pre_moderation: Enable pre-moderation
enable_pre_moderation_text: Moderators must approve any comment before it is published.
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_questionbox: Hacer una pregunta a los y las lectoras.
enable_questionbox_description: Esta pregunta aparecera en la parte de arriba del hilo de comentarios.
hours: Horas
include_comment_stream: Incluir Descripción de Hilo de Comentarios para Lectorxs
include_comment_stream_desc: Escribir un mensaje para ser incluido al principio del hilo de comentarios. Un tema podria ser incluir la guia de comunidad, etc.
include_text: Agregar tu texto aquí.
include_question_here: Escribir la pregunta aquí.
moderate: Moderate
moderation_settings: Configuración de la Moderación
open_stream: Abrir Hilo de Comentarios
open_stream_configuration: Este hilo de comentarios está abierto. Al cerrarlo no se podran publicar nuevos comentarios pero todos los comentarios anteriores aún serán mostrados.
require_email_verification: Necesita confirmación de e-mail
require_email_verification_text: Nuevos usuarios deben verificar sus e-mails antes de comentar
save_changes: Guardar Cambios
shortcuts: Atajos
sign_out: Desconectar
stories: Artículos
stream_settings: Configuración de Comentarios
suspect_word_text: Comentarios que contengan estas palabras o frases, considerando mayusculas y minusculas, serán automaticamente destacadas en los comentarios publicados. Escribir una palabra y apretar Enter o Tabulador para agergarla. Opcionalmente pegar una lista separada por coma.
suspect_words_title: Lista de palabras sospechosas
tech_settings: Configuración Técnica
title: Configurar los comentarios
weeks: Semanas
wordlist: Palabras Suspendidas
continue: Continuar
createdisplay:
check_the_form: Formulario Inválido. Por favor verifica los campos
continue: Continuar con nombre de 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_date: hace un minuto
if_you_dont_change_your_name: Si no modificas tu nombre de usuario en este paso tu nombre de Facebook aparecera al lado de cada comentario que publiques.
required_field: Campo necesario
save: Guardar
special_characters: Sólo pueden contener letras números y _
username: Nombre
write_your_username: Edita tu nombre
your_username: Tu nombre aparece en cada comentario que publiques.
dashboard:
auto_update: Data automatically updates every five minutes or when you Reload.
comment_count: comments
flags: Flags
most_flags: Articles with the most flags
nex_update: '{0} minutes until next update.'
no_activity: There haven't been any comments anywhere in the last five minutes.
no_flags: There have been no flags in the last 5 minutes! Hooray!
no_likes: There have been no likes in the last 5 minutes. All quiet.
done: hecho
embedlink:
copy: Copy to Clipboard
error:
comment_too_short: "Tu comentario debe tener algo escrito"
NOT_AUTHORIZED: Acción no autorizada.
NO_SPECIAL_CHARACTERS: Los nombres pueden contener letras números y _
PASSWORD_LENGTH: La 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
USERNAME_IN_USE: Nombre en uso.
USERNAME_REQUIRED: Debe ingresar un nombre
confirm_password: Las contraseñas no coinciden
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 e-mail válido
network_error: "Error al conectar con el servidor. Compruebe su conexión a Internet y vuelva a intentarlo."
email_in_use: El e-mail se encuentra en uso
email_not_verified: E-mail {0} no verificado.
email_password: "E-mail y/o contraseña incorrecta."
email_required: Se requiere un e-mail
email_username_in_use: E-mail o Nombre en uso.
login_maximum_exceeded: Ha realizado demasiados intentos fallidos de colocar 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 ingresas la contraseña
username: Los nombres pueden contener letras números y _
flag_comment: Reportar el comentario
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 commentarios."
comment: commentario
comment_is_ignored: Este comentario está escondido porque has ignorado al usuario.
comments: commentarios
content_not_available: El contenido no se encuentra disponible
edit_name:
button: Enviar
error: Nombres de usuarios pueden sólamente 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. Contactactanos si tienes alguna pregunta.
my_comments: Mis Comentarios
my_profile: Mi pérfil
new_count: Ver 0 1 más
profile: Pérfil
show_all_comments: Mostrar todos los comentarios
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
view_all_replies: ver 0 respuestas
view_all_replies_initial: ver todas las 0 respuestas
view_more_comments: Ver commentarios más
view_reply: ver respuesta
from_settings_page: Desde la página de configuración puedes ver tu historia de comentarios.
like: Me gusta
marketing: Esto parece una propaganda
moderate_this_stream: Modera este hilo de comentarios
modqueue:
account: account flags
actions: Actions
all: all
approve: Approve comment
approved: approved
billion: B
close: Close
dont_like_username: Don't like username
empty_queue: No more comments to moderate! You're all caught up. Go have some ☕️
flagged: flagged
impersonating: Impersonating
less_detail: Less detail
likes: likes
million: M
mod_faster: Moderate faster with keyboard shortcuts
more_detail: More detail
navigation: Navigation
next_comment: Go to the next comment
offensive: Offensive
other: Other
premod: pre-mod
prev_comment: Go to the previous comment
reject: Reject comment
rejected: rejected
shift_key:
shortcuts: Shortcuts
show_shortcuts: Show Shortcuts
singleview: Toggle single comment edit view
spam_ads: Spam/Ads
thismenu: Open this menu
thousand: k
try_these: Try these
view_more_shortcuts: View more shortcuts
my_comment_history: Mi historial de comentarios
name: Nombre
no_agree_comment: No estoy de acuerdo con este comentario
no_like_bio: No me gusta esta biografia
no_like_username: No me gusta este nombre de usuario
other: Otro
permalink: Enlace
personal_info: Este comentario muestra información personal
post: Publicar
profile: Perfil
profileSettings: 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_remove: Tu reporte ha sido eliminada.
reported: Reportado
set_best: Etiquetar como el mejor
settings:
all_comments: Todos los comentarios
comment:
anon: Anónimo
ban_user: "Usuario Suspendido"
comment: "Publicar un comentario"
flagged: reportado
view_context: "Ver contexto"
comment_box:
post: "Publicar"
cancel: "Cancelar"
reply: "Responder"
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 estan 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 estan 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.
community:
account_creation_date: Fecha de creación de la cuenta
active: Activa
admin: Administratora
are_you_sure: '¿Estas segura que quieres suspender a {0}?'
ban_user: ¿Quieres suspender al Usuario?
banned: Suspendido
banned-user: Usuarix Suspendido
cancel: Cancelar
flaggedaccounts: Nombres de Usuarix Reportados
flags: Reportes
loading: Cargando resultados
moderator: Moderatora
newsroom_role: Rol en la redacción
no-flagged-accounts: No hay ninguna cuenta reportada en este momento.
no-results: No se encontraron usuarixs con ese nombre o correo.
note: 'Nota: Suspender a este usuario no le va a permitir (al usuario) borrar ni editar ni comentar.'
other: Otro
people: Gente
role: Seleccionar rol...
select-status: Seleccionar estado...
status: Estado
username_and_email: Usuario y E-mail
yes_ban_user: Si, Suspendan el usuario
configure:
apply: Aplicar
banned_word_text: Comentarios que contengan estas palabras o frases, no separadas por comas y en mayusculas o minusuculas, serán automaticamente marcadas para separar los comentarios publicados.
banned_words_title: Lista de palabras prohibidas
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.
closed_comments_label: Escribe un mensaje...
closed_stream_settings: Mensaje que se meustra cuando los comentarios están cerrados 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: cáracteres
comment_count_text_pre: Los comentarios serán limitados a
comment_settings: Configuración
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 articulos
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.
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).
domain_list_title: Dominios Permitidos
embed_comment_stream: Colocar Hilo de Comentarios
enable-premod-links-text: Moderators must approve any comment containing a link before its published.
enable_pre_moderation: Enable pre-moderation
enable_pre_moderation_text: Moderators must approve any comment before it is published.
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_questionbox: Hacer una pregunta a los y las lectoras.
enable_questionbox_description: Esta pregunta aparecera en la parte de arriba del hilo de comentarios.
hours: Horas
include_comment_stream: Incluir Descripción de Hilo de Comentarios para Lectorxs
include_comment_stream_desc: Escribir un mensaje para ser incluido al principio del hilo de comentarios. Un tema podria ser incluir la guia de comunidad, etc.
include_text: Agregar tu texto aquí.
include_question_here: Escribir la pregunta aquí.
moderate: Moderate
moderation_settings: Configuración de la Moderación
open_stream: Abrir Hilo de Comentarios
open_stream_configuration: Este hilo de comentarios está abierto. Al cerrarlo no se podran publicar nuevos comentarios pero todos los comentarios anteriores aún serán mostrados.
require_email_verification: Necesita confirmación de e-mail
require_email_verification_text: Nuevos usuarios deben verificar sus e-mails antes de comentar
save_changes: Guardar Cambios
shortcuts: Atajos
sign_out: Desconectar
stories: Artículos
stream_settings: Configuración de Comentarios
suspect_word_text: Comentarios que contengan estas palabras o frases, considerando mayusculas y minusculas, serán automaticamente destacadas en los comentarios publicados. Escribir una palabra y apretar Enter o Tabulador para agergarla. Opcionalmente pegar una lista separada por coma.
suspect_word_title: Lista de palabras sospechosas
tech_settings: Configuración Técnica
title: Configurar los comentarios
weeks: Semanas
wordlist: Palabras Suspendidas
continue: Continuar
createdisplay:
check_the_form: Formulario Inválido. Por favor verifica los campos
continue: Continuar con nombre de 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_date: hace un minuto
if_you_dont_change_your_name: Si no modificas tu nombre de usuario en este paso tu nombre de Facebook aparecera al lado de cada comentario que publiques.
required_field: Campo necesario
save: Guardar
special_characters: Sólo pueden contener letras números y _
username: Nombre
write_your_username: Edita tu nombre
your_username: Tu nombre aparece en cada comentario que publiques.
dashboard:
auto_update: Data automatically updates every five minutes or when you Reload.
comment_count: comments
flags: Flags
most_flags: Articles with the most flags
nex_update: '{0} minutes until next update.'
no_activity: There haven't been any comments anywhere in the last five minutes.
no_flags: There have been no flags in the last 5 minutes! Hooray!
no_likes: There have been no likes in the last 5 minutes. All quiet.
done: hecho
embedlink:
copy: Copy to Clipboard
error:
comment_too_short: "Tu comentario debe tener algo escrito"
NOT_AUTHORIZED: Acción no autorizada.
NO_SPECIAL_CHARACTERS: Los nombres pueden contener letras números y _
PASSWORD_LENGTH: La 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
USERNAME_IN_USE: Nombre en uso.
USERNAME_REQUIRED: Debe ingresar un nombre
confirm_password: Las contraseñas no coinciden
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 e-mail válido
network_error: "Error al conectar con el servidor. Compruebe su conexión a Internet y vuelva a intentarlo."
email_in_use: El e-mail se encuentra en uso
email_not_verified: E-mail {0} no verificado.
email_password: "E-mail y/o contraseña incorrecta."
email_required: Se requiere un e-mail
email_username_in_use: E-mail o Nombre en uso.
login_maximum_exceeded: Ha realizado demasiados intentos fallidos de colocar 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 ingresas la contraseña
username: Los nombres pueden contener letras números y _
flag_comment: Reportar el comentario
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 commentarios."
comment: commentario
comment_is_ignored: Este comentario está escondido porque has ignorado al usuario.
comments: commentarios
content_not_available: El contenido no se encuentra disponible
edit_name:
button: Enviar
error: Nombres de usuarios pueden sólamente 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. Contactactanos si tienes alguna pregunta.
my_comments: Mis Comentarios
my_profile: Mi pérfil
new_count: Ver 0 1 más
profile: Pérfil
show_all_comments: Mostrar todos los comentarios
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
view_all_replies: ver 0 respuestas
view_all_replies_initial: ver todas las 0 respuestas
view_more_comments: Ver commentarios más
view_reply: ver respuesta
from_settings_page: Desde la página de configuración puedes ver tu historia de comentarios.
like: Me gusta
marketing: Esto parece una propaganda
moderate_this_stream: Modera este hilo de comentarios
modqueue:
account: account flags
actions: Actions
all: all
approve: Approve comment
approved: approved
billion: B
close: Close
dont_like_username: Don't like username
empty_queue: No more comments to moderate! You're all caught up. Go have some ☕️
flagged: flagged
impersonating: Impersonating
less_detail: Less detail
likes: likes
million: M
mod_faster: Moderate faster with keyboard shortcuts
more_detail: More detail
navigation: Navigation
next_comment: Go to the next comment
offensive: Offensive
other: Other
premod: pre-mod
prev_comment: Go to the previous comment
reject: Reject comment
rejected: rejected
shift_key:
shortcuts: Shortcuts
show_shortcuts: Show Shortcuts
singleview: Toggle single comment edit view
spam_ads: Spam/Ads
thismenu: Open this menu
thousand: k
try_these: Try these
view_more_shortcuts: View more shortcuts
my_comment_history: Mi historial de comentarios
name: Nombre
no_agree_comment: No estoy de acuerdo con este comentario
no_like_bio: No me gusta esta biografia
no_like_username: No me gusta este nombre de usuario
other: Otro
permalink: Enlace
personal_info: Este comentario muestra información personal
post: Publicar
profile: Perfil
profile_settings: Configuración del perfil
sign_in: Entrar
to_access: para acceder a al perfil
profileSettings: 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_remove: Tu reporte ha sido eliminada.
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 historia de comentarios.
my_comment_history: Mi historial de comentarios
profile: Perfil
profile_settings: Configuración del perfil
sign_in: Entrar
to_access: para acceder a al perfil
user_no_comment: No has dejado aún ningún comentario. ¡Únete a la conversación!
sign_in:
email_verify_cta: "Por favor verifique 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 verificar su cuenta."
verify_email2: "Debe verificarla antes de poder involucrarse en la comunidad."
not_you: "¿No eres tu?"
logged_in_as: "Entraste como"
facebook_sign_in: "Acceder con Facebook"
facebook_sign_up: "Registrarse con Facebook"
logout: "Salir"
sign_in: "Entrar"
sign_in_to_join: "Entrar para unirte a la conversación"
or: "O"
email: "Correo"
password: "Contraseña"
forgot_your_pass: "¿Has olvidado tu contraseña?"
need_an_account: "¿Necesitas una cuenta?"
register: "Registrar"
sign_up: "Registro"
confirm_password: "Confirmar Contraseña"
username: "Nombre"
already_have_an_account: "¿Ya tienes una cuenta?"
recover_password: "Recuperar contraseña"
email_in_use: "Este correo se encuentra en uso"
email_or_username_in_use: "Este correo ó nombre de usuario se encuentran en uso"
required_field: "Este campo es necesario"
passwords_dont_match: "Las contraseñas no coinciden."
special_characters: "Los nombres pueden contener letras, números y _"
check_the_form: "Formulario Inválido. Por favor, completa los campos"
step_1_header: Reportar un problema
step_2_header: Ayudanos a comprender
step_3_header: Gracias por tu participación
streams:
all: All
article: Story
closed: Closed
empty_result: No assets match this search. Maybe try widening your search?
filter_streams: Filter Streams
newest: Newest
oldest: Oldest
open: Open
pubdate: Publication Date
search: Search
sort_by: Sort By
status: Stream Status
stream_status: Stream Status
suspenduser:
bio: bio
description_0: "Would you like to temporarily ban this user because of their {0}? Doing so will temporarily hide their comments until they rewrite their {0}."
description_1: "Suspending this user will temporarily disable their account and hide all of their comments on the site."
email: "Another member of the community recently flagged your username for review. Because of its content your user was rejected. This means you can no longer comment like or flag content until you rewrite your username. Please e-mail us if you have any questions or concerns."
email_subject: Your account has been suspended
no_cancel: No cancel
send: Send
title: Suspend a user
title_0: We noticed you rejected a username
title_1: Notify the user of their temporary suspension
username: username
write_message: Write a message
yes_suspend: Yes suspend
thank_you: Valoramos tanto tu seguridad en este espacio como tus comentarios. Un o una moderadora van a leer tu reporte.
unset_best: Desetiquetar como el mejor
user:
bio_flags: flags for this bio
user_bio: User Bio
username_flags: flags for this username
user_impersonating: Este usuario suplanta a alguien
user_no_comment: No has dejado aún ningún comentario. ¡Únete a la conversación!
sign_in:
email_verify_cta: "Por favor verifique 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 verificar su cuenta."
verify_email2: "Debe verificarla antes de poder involucrarse en la comunidad."
not_you: "¿No eres tu?"
logged_in_as: "Entraste como"
facebook_sign_in: "Acceder con Facebook"
facebook_sign_up: "Registrarse con Facebook"
logout: "Salir"
sign_in: "Entrar"
sign_in_to_join: "Entrar para unirte a la conversación"
or: "O"
email: "Correo"
password: "Contraseña"
forgot_your_pass: "¿Has olvidado tu contraseña?"
need_an_account: "¿Necesitas una cuenta?"
register: "Registrar"
sign_up: "Registro"
confirm_password: "Confirmar Contraseña"
username: "Nombre"
already_have_an_account: "¿Ya tienes una cuenta?"
recover_password: "Recuperar contraseña"
email_in_use: "Este correo se encuentra en uso"
email_or_username_in_use: "Este correo ó nombre de usuario se encuentran en uso"
required_field: "Este campo es necesario"
passwords_dont_match: "Las contraseñas no coinciden."
special_characters: "Los nombres pueden contener letras, números y _"
check_the_form: "Formulario Inválido. Por favor, completa los campos"
step_1_header: Reportar un problema
step_2_header: Ayudanos a comprender
step_3_header: Gracias por tu participación
streams:
all: All
article: Story
closed: Closed
empty_result: No assets match this search. Maybe try widening your search?
filter_streams: Filter Streams
newest: Newest
oldest: Oldest
open: Open
pubdate: Publication Date
search: Search
sort_by: Sort By
status: Stream Status
stream_status: Stream Status
suspenduser:
bio: bio
description_0: "Would you like to temporarily ban this user because of their {0}? Doing so will temporarily hide their comments until they rewrite their {0}."
description_1: "Suspending this user will temporarily disable their account and hide all of their comments on the site."
email: "Another member of the community recently flagged your username for review. Because of its content your user was rejected. This means you can no longer comment like or flag content until you rewrite your username. Please e-mail us if you have any questions or concerns."
email_subject: Your account has been suspended
no_cancel: No cancel
send: Send
title: Suspend a user
title_0: We noticed you rejected a username
title_1: Notify the user of their temporary suspension
username: username
write_message: Write a message
yes_suspend: Yes suspend
thank_you: Valoramos tanto tu seguridad en este espacio como tus comentarios. Un o una moderadora van a leer tu reporte.
unset_best: Desetiquetar como el mejor
user:
bio_flags: flags for this bio
user_bio: User Bio
username_flags: flags for this username
user_impersonating: Este usuario suplanta a alguien
user_no_comment: No has dejado aún ningún comentario. ¡Únete a la conversación!
username_offensive: Este nombre de usuario es ofensivo
username_offensive: Este nombre de usuario es ofensivo
-90
View File
@@ -1,90 +0,0 @@
import has from 'lodash/has';
import get from 'lodash/get';
const localesFiles = {
'en': require('json-loader!yaml-loader!../../locales/en.yml'),
'es': require('json-loader!yaml-loader!../../locales/es.yml')
};
/**
* Default locales, this should be overriden by config file
*/
class i18n {
constructor(translations) {
this.locales = {'en': 'en', 'es': 'es'};
/**
* Register locales
*/
try {
const locale = this.getLocale();
this.setLocale(locale);
this.language = this.locales[locale.split('-')[0]] || 'en';
this.loadTranslations(translations);
} catch (err) {
console.error(err);
}
}
loadTranslations = (translations) => {
try {
if (typeof translations == 'undefined'){
// Translations need to be loaded from translations or localesFiles.
this.translations = localesFiles[this.language];
} else {
this.translations = translations[this.language];
}
}
catch(err) {
// To Do: get configuration for default translation
this.translations = localesFiles['en'];
}
}
setLocale = (locale) => {
try {
localStorage.setItem('locale', locale);
} catch (err) {
console.error(err);
}
};
getLocale = () => (
localStorage.getItem('locale') || navigator.language || 'en-US'
);
/**
* Expose the translation function
*
* it takes a string with the translation key and returns
* the translation value or the key itself if not found
* it works with nested translations (my.page.title)
*
* any extra parameters are optional and replace a variable marked by {0}, {1}, etc in the translation.
*/
t = (key, ...replacements) => {
if (has(this.translations, key)) {
let translation = get(this.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;
}
};
}
export default i18n;
+65
View File
@@ -0,0 +1,65 @@
const has = require('lodash/has');
const get = require('lodash/get');
const defaultLanguage = 'en';
let translations = {};
const fetchTranslations = (locale) => {
translations = require(`json-loader!yaml-loader!../locales/${locale}.yml`)[locale];
};
const setLocale = (locale) => {
try {
localStorage.setItem('locale', locale);
} catch (err) {
console.error(err);
}
};
const getLocale = () => (localStorage.getItem('locale') || navigator.language || defaultLanguage).split('-')[0];
export const loadTranslations = (translations) => {
try {
const locale = getLocale();
setLocale(locale);
if (translations !== undefined) {
translations = translations[locale];
}
return fetchTranslations(locale);
} catch (err) {
console.error(err);
return fetchTranslations(defaultLanguage);
}
};
export const timeago = (date) => timeago().format(date, getLocale().replace('-', '_'));
/**
* Expose the translation function
*
* it takes a string with the translation key and returns
* the translation value or the key itself if not found
* it works with nested translations (my.page.title)
*
* any extra parameters are optional and replace a variable marked by {0}, {1}, etc in the translation.
*/
const t = (key, ...replacements) => {
if (has(translations, 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;
}
};
export default t;
+4 -4
View File
@@ -1,5 +1,6 @@
import React, {Component, PropTypes} from 'react';
import {I18n} from '../coral-framework';
import t from 'coral-i18n/services/i18n';
import {Icon} from 'coral-ui';
import classnames from 'classnames';
@@ -12,7 +13,6 @@ export const commentIsBest = ({tags} = {}) => {
};
const name = 'coral-plugin-best';
const lang = new I18n();
// It would be best if the backend/api held this business logic
const canModifyBestTag = ({roles = []} = {}) => roles && ['ADMIN', 'MODERATOR'].some((role) => roles.includes(role));
@@ -20,7 +20,7 @@ const canModifyBestTag = ({roles = []} = {}) => roles && ['ADMIN', 'MODERATOR'].
// Put this on a comment to show that it is best
export const BestIndicator = ({children = <Icon name='star'/>}) => (
<span aria-label={lang.t('comment_is_best')}>
<span aria-label={t('comment_is_best')}>
{ children }
</span>
);
@@ -98,7 +98,7 @@ export class BestButton extends Component {
<button onClick={isBest ? this.onClickRemoveBest : this.onClickAddBest}
disabled={disabled}
className={classnames(`${name}-button`, `e2e__${isBest ? 'unset' : 'set'}-best-comment`)}
aria-label={lang.t(isBest ? 'unsetBest' : 'setBest')}>
aria-label={t(isBest ? 'unsetBest' : 'setBest')}>
<Icon name={ isBest ? 'star' : 'star_border' } />
</button>
);
@@ -1,12 +0,0 @@
{
"en": {
"setBest": "Tag as Best",
"unsetBest": "Untag as Best",
"commentIsBest": "This comment is one of the best"
},
"es": {
"setBest": "Etiquetar como el mejor",
"unsetBest": "Desetiquetar como el mejor",
"commentIsBest": "Este comentario es uno de los mejores"
}
}
@@ -1,11 +1,12 @@
import React, {PropTypes} from 'react';
import {I18n} from '../coral-framework';
import t from 'coral-i18n/services/i18n';
const name = 'coral-plugin-comment-count';
const CommentCount = ({count}) => {
return <div className={`${name}-text`}>
{`${count} ${count === 1 ? lang.t('comment.comment') : lang.t('comment_plural')}`}
{`${count} ${count === 1 ? t('comment.comment') : t('comment_plural')}`}
</div>;
};
@@ -14,5 +15,3 @@ CommentCount.propTypes = {
};
export default CommentCount;
const lang = new I18n();
@@ -1,10 +0,0 @@
{
"en": {
"comment": "Comment",
"comment-plural": "Comments"
},
"es": {
"comment": "Comentario",
"comment-plural": "Comentarios"
}
}
+6 -7
View File
@@ -1,5 +1,6 @@
import React, {PropTypes} from 'react';
import {I18n} from '../coral-framework';
import t from 'coral-i18n/services/i18n';
import Slot from 'coral-framework/components/Slot';
import {connect} from 'react-redux';
@@ -11,9 +12,9 @@ export const name = 'coral-plugin-commentbox';
// if needed
export const notifyForNewCommentStatus = (addNotification, status) => {
if (status === 'REJECTED') {
addNotification('error', lang.t('comment_box.comment_post_banned_word'));
addNotification('error', t('comment_box.comment_post_banned_word'));
} else if (status === 'PREMOD') {
addNotification('success', lang.t('comment_box.comment_post_notif-premod'));
addNotification('success', t('comment_box.comment_post_notif_premod'));
}
};
@@ -156,10 +157,10 @@ class CommentBox extends React.Component {
key={this.state.postedCount}
defaultValue={this.props.defaultValue}
bodyInputId={isReply ? 'replyText' : 'commentText'}
bodyLabel={isReply ? lang.t('comment_box.reply') : lang.t('comment.comment')}
bodyLabel={isReply ? t('comment_box.reply') : t('comment.comment')}
maxCharCount={maxCharCount}
charCountEnable={this.props.charCountEnable}
bodyPlaceholder={lang.t('comment.comment')}
bodyPlaceholder={t('comment.comment')}
bodyInputId={isReply ? 'replyText' : 'commentText'}
saveComment={authorId && this.postComment}
buttonContainerStart={<Slot
@@ -194,5 +195,3 @@ CommentBox.propTypes = {
const mapStateToProps = ({commentBox}) => ({commentBox});
export default connect(mapStateToProps, null)(CommentBox);
const lang = new I18n();
@@ -1,12 +1,11 @@
import React, {PropTypes} from 'react';
import {Button} from 'coral-ui';
import classnames from 'classnames';
import {I18n} from '../coral-framework';
import Slot from 'coral-framework/components/Slot';
import {name} from './CommentBox';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
/**
* Common UI for Creating or Editing a Comment
@@ -55,9 +54,9 @@ export class CommentForm extends React.Component {
}
static get defaultProps() {
return {
bodyLabel: lang.t('comment_box.comment'),
bodyPlaceholder: lang.t('comment_box.comment'),
submitText: lang.t('comment_box.post'),
bodyLabel: t('comment_box.comment'),
bodyPlaceholder: t('comment_box.comment'),
submitText: t('comment_box.post'),
saveButtonCStyle: 'darkGrey',
saveCommentEnabled: () => true,
};
@@ -108,7 +107,7 @@ export class CommentForm extends React.Component {
{
this.props.charCountEnable &&
<div className={`${name}-char-count ${length > maxCharCount ? `${name}-char-max` : ''}`}>
{maxCharCount && `${maxCharCount - length} ${lang.t('comment_box.characters_remaining')}`}
{maxCharCount && `${maxCharCount - length} ${t('comment_box.characters_remaining')}`}
</div>
}
<div className={`${name}-button-container`}>
@@ -119,7 +118,7 @@ export class CommentForm extends React.Component {
cStyle='darkGrey'
className={classnames(`${name}-cancel-button`, buttonClass)}
onClick={this.props.cancelButtonClicked}>
{lang.t('comment_box.cancel')}
{t('comment_box.cancel')}
</Button>
)
}
+5 -6
View File
@@ -1,5 +1,6 @@
import React, {Component} from 'react';
import {I18n} from '../coral-framework';
import t from 'coral-i18n/services/i18n';
import {PopupMenu, Button} from 'coral-ui';
import onClickOutside from 'react-onclickoutside';
@@ -141,8 +142,8 @@ class FlagButton extends Component {
className={`${name}-button`}>
{
flagged
? <span className={`${name}-button-text`}>{lang.t('reported')}</span>
: <span className={`${name}-button-text`}>{lang.t('report')}</span>
? <span className={`${name}-button-text`}>{t('reported')}</span>
: <span className={`${name}-button-text`}>{t('report')}</span>
}
<i className={`${name}-icon material-icons ${flagged && 'flaggedIcon'}`}
style={flagged ? styles.flaggedIcon : {}}
@@ -176,7 +177,7 @@ class FlagButton extends Component {
{
this.state.reason && <div>
<label htmlFor={'message'} className={`${name}-popup-radio-label`}>
{lang.t('flag_reason')}
{t('flag_reason')}
</label><br/>
<textarea
className={`${name}-reason-text`}
@@ -215,5 +216,3 @@ const styles = {
color: 'inherit'
}
};
const lang = new I18n();
+19 -20
View File
@@ -1,50 +1,49 @@
import React from 'react';
import FlagButton from './FlagButton';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const FlagComment = (props) => <FlagButton {...props} getPopupMenu={getPopupMenu} />;
const getPopupMenu = [
() => {
return {
header: lang.t('step_1_header'),
header: t('step_1_header'),
options: [
{val: 'COMMENTS', text: lang.t('flag_comment')},
{val: 'USERS', text: lang.t('flag_username')}
{val: 'COMMENTS', text: t('flag_comment')},
{val: 'USERS', text: t('flag_username')}
],
button: lang.t('continue'),
button: t('continue'),
sets: 'itemType'
};
},
(itemType) => {
const options = itemType === 'COMMENTS' ?
[
{val: 'This comment is offensive', text: lang.t('comment_offensive')},
{val: 'This looks like an ad/marketing', text: lang.t('marketing')},
{val: 'I don\'t agree with this comment', text: lang.t('no_agree_comment')},
{val: 'Other', text: lang.t('other')}
{val: 'This comment is offensive', text: t('comment_offensive')},
{val: 'This looks like an ad/marketing', text: t('marketing')},
{val: 'I don\'t agree with this comment', text: t('no_agree_comment')},
{val: 'Other', text: t('other')}
]
: [
{val: 'This username is offensive', text: lang.t('username_offensive')},
{val: 'I don\'t like this username', text: lang.t('no_like_username')},
{val: 'This user is impersonating', text: lang.t('user_impersonating')},
{val: 'This looks like an ad/marketing', text: lang.t('marketing')},
{val: 'Other', text: lang.t('other')}
{val: 'This username is offensive', text: t('username_offensive')},
{val: 'I don\'t like this username', text: t('no_like_username')},
{val: 'This user is impersonating', text: t('user_impersonating')},
{val: 'This looks like an ad/marketing', text: t('marketing')},
{val: 'Other', text: t('other')}
];
return {
header: lang.t('step_2_header'),
header: t('step_2_header'),
options,
button: lang.t('continue'),
button: t('continue'),
sets: 'reason'
};
},
() => {
return {
header: lang.t('step_3_header'),
text: lang.t('thank_you'),
button: lang.t('done'),
header: t('step_3_header'),
text: t('thank_you'),
button: t('done'),
};
}
];
@@ -1,52 +0,0 @@
{
"en": {
"report": "Report",
"reported": "Reported",
"report-notif": "Thank you for reporting this comment. Our moderation team has been notified and will review it shortly.",
"report-notif-remove": "Your report has been removed.",
"step-1-header": "Report an issue",
"step-2-header": "Help us understand",
"step-3-header": "Thank you for your input",
"flag-username": "Report username",
"flag-comment": "Report comment",
"continue": "Continue",
"done": "Done",
"no-agree-comment": "I don't agree with this comment",
"comment-offensive": "This comment is offensive",
"personal-info": "This comment reveals personally identifiable information",
"username-offensive": "This username is offensive",
"no-like-username": "I don't like this username",
"bio-offensive": "This bio is offensive",
"no-like-bio": "I don't like this bio",
"marketing": "This looks like an ad/marketing",
"user-impersonating": "This user is impersonating",
"thank-you": "We value your safety and feedback. A moderator will review your report.",
"flag-reason": "Reason for reporting (Optional)",
"other": "Other"
},
"es": {
"report": "Reportar",
"reported": "Reportado",
"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 eliminada.",
"step-1-header": "Reportar un problema",
"step-2-header": "Ayudanos a comprender",
"step-3-header": "Gracias por tu participación",
"flag-username": "Reportar el nombre de usuario",
"flag-comment": "Reportar el comentario",
"continue": "Continuar",
"done": "hecho",
"no-agree-comment": "No estoy de acuerdo con este comentario",
"comment-offensive": "Este comentario es ofensivo",
"personal-info": "Este comentario muestra información personal",
"username-offensive": "Este nombre de usuario es ofensivo",
"no-like-username": "No me gusta este nombre de usuario",
"bio-offensive": "Esta biografia es ofensiva",
"no-like-bio": "No me gusta esta biografia",
"user-impersonating": "Este usuario suplanta a alguien",
"marketing": "Esto parece una propaganda",
"thank-you": "Valoramos tanto tu seguridad en este espacio como tus comentarios. Un o una moderadora van a leer tu reporte.",
"flag-reason": "Razón por la que hacer este reporte (Opcional)",
"other": "Otro"
}
}
@@ -1,14 +1,12 @@
import React, {PropTypes} from 'react';
import styles from './styles.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const ModerationLink = (props) => props.isAdmin ? (
<div className={styles.moderationLink}>
<a href={`/admin/moderate/${props.assetId}`} target="_blank">
{lang.t('moderate_this_stream')}
{t('moderate_this_stream')}
</a>
</div>
) : null;
@@ -1,8 +0,0 @@
{
"en": {
"MODERATE_THIS_STREAM": "Moderate this stream"
},
"es": {
"MODERATE_THIS_STREAM": "Modera este hilo de comentarios"
}
}
@@ -1,11 +1,10 @@
import React, {PropTypes} from 'react';
import I18n from 'coral-i18n/modules/i18n/i18n';
import onClickOutside from 'react-onclickoutside';
const name = 'coral-plugin-permalinks';
import {Button} from 'coral-ui';
import styles from './styles.css';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
class PermalinkButton extends React.Component {
@@ -55,7 +54,7 @@ class PermalinkButton extends React.Component {
ref={(ref) => this.linkButton = ref}
onClick={this.toggle}
className={`${name}-button`}>
{lang.t('permalink')}
{t('permalink')}
<i className={`${name}-icon material-icons`} aria-hidden={true}>link</i>
</button>
<div
@@ -1,12 +0,0 @@
{
"en": {
"permalink": {
"permalink": "Link"
}
},
"es": {
"permalink": {
"permalink": "Enlace"
}
}
}
+2 -4
View File
@@ -1,12 +1,10 @@
import React from 'react';
import timeago from 'timeago.js';
import {I18n} from '../coral-framework';
import timeago from 'coral-i18n/services/i18n';
const lang = new I18n();
const name = 'coral-plugin-pubdate';
const PubDate = ({created_at}) => <div className={`${name}-text`}>
{timeago().format(created_at, lang.getLocale().replace('-', '_'))}
{timeago(created_at)}
</div>;
export default PubDate;
+3 -4
View File
@@ -1,5 +1,6 @@
import React, {PropTypes} from 'react';
import {I18n} from '../coral-framework';
import t from 'coral-i18n/services/i18n';
import classnames from 'classnames';
@@ -10,7 +11,7 @@ const ReplyButton = ({banned, onClick}) => {
<button
className={classnames(`${name}-reply-button`)}
onClick={onClick}>
{lang.t('reply')}
{t('reply')}
<i className={`${name}-icon material-icons`}
aria-hidden={true}>{banned ? 'BANNED' : 'reply'}</i>
</button>
@@ -23,5 +24,3 @@ ReplyButton.propTypes = {
};
export default ReplyButton;
const lang = new I18n();
@@ -1,8 +0,0 @@
{
"en": {
"reply": "Reply"
},
"es": {
"reply": "Responder"
}
}
@@ -1,16 +1,15 @@
import React from 'react';
import styles from './NotLoggedIn.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
export default ({showSignInDialog}) => (
<div className={styles.message}>
<div>
<a onClick={showSignInDialog}>{lang.t('sign_in')}</a> {lang.t('toAccess')}
<a onClick={showSignInDialog}>{t('sign_in')}</a> {t('toAccess')}
</div>
<div>
{lang.t('from_settings_page')}
{t('from_settings_page')}
</div>
</div>
);
@@ -1,7 +1,6 @@
import {connect} from 'react-redux';
import {compose, graphql, gql} from 'react-apollo';
import React, {Component} from 'react';
import I18n from 'coral-i18n/modules/i18n/i18n';
import {bindActionCreators} from 'redux';
import {withStopIgnoringUser} from 'coral-framework/graphql/mutations';
@@ -13,7 +12,7 @@ import {Spinner} from 'coral-ui';
import CommentHistory from 'coral-plugin-history/CommentHistory';
import {showSignInDialog, checkLogin} from 'coral-framework/actions/auth';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
class ProfileContainer extends Component {
constructor() {
@@ -67,7 +66,7 @@ class ProfileContainer extends Component {
<h3>My comments</h3>
{me.comments.length
? <CommentHistory comments={me.comments} asset={asset} link={link} />
: <p>{lang.t('user_no_comment')}</p>}
: <p>{t('user_no_comment')}</p>}
</div>
);
}
-22
View File
@@ -1,22 +0,0 @@
{
"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 Profile",
"fromSettingsPage": "From the Profile Page you can see your comment history."
},
"es":{
"profile": "Perfil",
"userNoComment": "No has dejado aún ningún comentario. ¡Únete a la conversación!",
"allComments": "Todos los comentarios",
"profileSettings": "Configuración del perfil",
"myCommentHistory": "Mi historial de comentarios",
"signIn": "Entrar",
"toAccess": "para acceder a al perfil",
"fromSettingsPage": "Desde la página de configuración puedes ver tu historia de comentarios."
}
}
@@ -6,9 +6,7 @@ import FakeComment from './FakeComment';
import styles from './styles.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const CreateUsernameDialog = ({open, handleClose, formData, handleSubmitUsername, handleChange, ...props}) => {
return (
@@ -20,31 +18,31 @@ const CreateUsernameDialog = ({open, handleClose, formData, handleSubmitUsername
<div>
<div className={styles.header}>
<h1>
{lang.t('createdisplay.write_your_username')}
{t('createdisplay.write_your_username')}
</h1>
</div>
<div>
<p className={styles.yourusername}>{lang.t('createdisplay.your_username')}</p>
<p className={styles.yourusername}>{t('createdisplay.your_username')}</p>
<FakeComment
className={styles.fakeComment}
username={formData.username}
created_at={Date.now()}
body={lang.t('createdisplay.fake_comment_body')}
body={t('createdisplay.fake_comment_body')}
/>
<p className={styles.ifyoudont}>{lang.t('createdisplay.if_you_dont_change_your_name')}</p>
<p className={styles.ifyoudont}>{t('createdisplay.if_you_dont_change_your_name')}</p>
{ props.auth.error && <Alert>{props.auth.error}</Alert> }
<form id="saveUsername" onSubmit={handleSubmitUsername}>
{ props.errors.username && <span className={styles.hint}> {lang.t('createdisplay.special_characters')} </span> }
{ props.errors.username && <span className={styles.hint}> {t('createdisplay.special_characters')} </span> }
<div className={styles.saveusername}>
<TextField
id="username"
style={{fontSize: 16}}
type="string"
label={lang.t('createdisplay.username')}
label={t('createdisplay.username')}
value={formData.username}
onChange={handleChange}
/>
<Button id="save" type="submit" className={styles.saveButton}>{lang.t('createdisplay.save')}</Button>
<Button id="save" type="submit" className={styles.saveButton}>{t('createdisplay.save')}</Button>
</div>
</form>
</div>
@@ -5,10 +5,7 @@ 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-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
class FakeComment extends React.Component {
constructor (props) {
@@ -30,7 +27,7 @@ class FakeComment extends React.Component {
<div className="commentActionsLeft comment__action-container">
<div className={`${'coral-plugin-likes'}-container`}>
<button className={'coral-plugin-likes-button'}>
<span className={'coral-plugin-likes-button-text'}>{lang.t('like')}</span>
<span className={'coral-plugin-likes-button-text'}>{t('like')}</span>
<i className={`${'coral-plugin-likes'}-icon material-icons`}
aria-hidden={true}>thumb_up</i>
</button>
@@ -45,13 +42,13 @@ class FakeComment extends React.Component {
<div className="commentActionsRight comment__action-container">
<div className="coral-plugin-permalinks-container">
<button className="coral-plugin-permalinks-button">
<span className={`comment__action-button comment__action-button--nowrap ${'coral-plugin-flags'}-button-text`}>{lang.t('permalink')}</span>
<span className={`comment__action-button comment__action-button--nowrap ${'coral-plugin-flags'}-button-text`}>{t('permalink')}</span>
<i className="coral-plugin-permalinks-icon material-icons" aria-hidden={true}>link</i>
</button>
</div>
<div className={`${'coral-plugin-flags'}-container`}>
<button className={`${'coral-plugin-flags'}-button`}>
<span className={`comment__action-button comment__action-button--nowrap ${'coral-plugin-flags'}-button-text`}>{lang.t('report')}</span>
<span className={`comment__action-button comment__action-button--nowrap ${'coral-plugin-flags'}-button-text`}>{t('report')}</span>
<i className={`${'coral-plugin-flags'}-icon material-icons`}
aria-hidden={true}>flag</i>
</button>
@@ -1,9 +1,7 @@
import React from 'react';
import styles from './styles.css';
import Button from 'coral-ui/components/Button';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
class ForgotContent extends React.Component {
constructor (props) {
@@ -23,11 +21,11 @@ class ForgotContent extends React.Component {
return (
<div>
<div className={styles.header}>
<h1>{lang.t('sign_in.recover_password')}</h1>
<h1>{t('sign_in.recover_password')}</h1>
</div>
<form onSubmit={this.handleSubmit}>
<div className={styles.textField}>
<label htmlFor="email">{lang.t('sign_in.email')}</label>
<label htmlFor="email">{t('sign_in.email')}</label>
<input
ref={(input) => this.emailInput = input}
type="text"
@@ -36,7 +34,7 @@ class ForgotContent extends React.Component {
name="email" />
</div>
<Button type="submit" cStyle="black" className={styles.signInButton} full>
{lang.t('sign_in.recover_password')}
{t('sign_in.recover_password')}
</Button>
{
passwordRequestSuccess
@@ -50,8 +48,8 @@ class ForgotContent extends React.Component {
}
</form>
<div className={styles.footer}>
<span>{lang.t('sign_in.need_an_account')} <a onClick={() => changeView('SIGNUP')}>{lang.t('sign_in.register')}</a></span>
<span>{lang.t('sign_in.already_have_an_account')} <a onClick={() => changeView('SIGNIN')}>{lang.t('sign_in.sign_in')}</a></span>
<span>{t('sign_in.need_an_account')} <a onClick={() => changeView('SIGNUP')}>{t('sign_in.register')}</a></span>
<span>{t('sign_in.already_have_an_account')} <a onClick={() => changeView('SIGNIN')}>{t('sign_in.sign_in')}</a></span>
</div>
</div>
);
@@ -1,9 +1,7 @@
import React, {PropTypes} from 'react';
import {Button, TextField, Spinner, Success, Alert} from 'coral-ui';
import styles from './styles.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const SignInContent = ({
handleChange,
@@ -23,18 +21,18 @@ const SignInContent = ({
<div className="coral-sign-in">
<div className={`${styles.header} header`}>
<h1>
{auth.emailVerificationFailure ? lang.t('sign_in.email_verify_cta') : lang.t('sign_in.sign_in_to_join')}
{auth.emailVerificationFailure ? t('sign_in.email_verify_cta') : t('sign_in.sign_in_to_join')}
</h1>
</div>
{ auth.error && <Alert>{auth.error}</Alert> }
{
auth.emailVerificationFailure
? <form onSubmit={handleResendVerification}>
<p>{lang.t('sign_in.request_new_verify_email')}</p>
<p>{t('sign_in.request_new_verify_email')}</p>
<TextField
id="confirm-email"
type="email"
label={lang.t('sign_in.email')}
label={t('sign_in.email')}
value={emailToBeResent}
onChange={handleChangeEmail} />
<Button id='resendConfirmEmail' type='submit' cStyle='black' full>Send Email</Button>
@@ -44,19 +42,19 @@ const SignInContent = ({
: <div>
<div className={`${styles.socialConnections} social-connections`}>
<Button cStyle="facebook" onClick={fetchSignInFacebook} full>
{lang.t('sign_in.facebook_sign_in')}
{t('sign_in.facebook_sign_in')}
</Button>
</div>
<div className={styles.separator}>
<h1>
{lang.t('sign_in.or')}
{t('sign_in.or')}
</h1>
</div>
<form onSubmit={handleSignIn}>
<TextField
id="email"
type="email"
label={lang.t('sign_in.email')}
label={t('sign_in.email')}
value={formData.email}
style={{fontSize: 16}}
onChange={handleChange}
@@ -64,7 +62,7 @@ const SignInContent = ({
<TextField
id="password"
type="password"
label={lang.t('sign_in.password')}
label={t('sign_in.password')}
value={formData.password}
style={{fontSize: 16}}
onChange={handleChange}
@@ -73,7 +71,7 @@ const SignInContent = ({
{
!auth.isLoading ?
<Button id='coralLogInButton' type="submit" cStyle="black" className={styles.signInButton} full>
{lang.t('sign_in.sign_in')}
{t('sign_in.sign_in')}
</Button>
:
<Spinner />
@@ -83,11 +81,11 @@ const SignInContent = ({
</div>
}
<div className={`${styles.footer} footer`}>
<span><a onClick={() => changeView('FORGOT')}>{lang.t('sign_in.forgot_your_pass')}</a></span>
<span><a onClick={() => changeView('FORGOT')}>{t('sign_in.forgot_your_pass')}</a></span>
<span>
{lang.t('sign_in.need_an_account')}
{t('sign_in.need_an_account')}
<a onClick={() => changeView('SIGNUP')} id='coralRegister'>
{lang.t('sign_in.register')}
{t('sign_in.register')}
</a>
</span>
</div>
@@ -1,9 +1,7 @@
import React, {PropTypes} from 'react';
import {Button, TextField, Spinner, Success, Alert} from 'coral-ui';
import styles from './styles.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
class SignUpContent extends React.Component {
@@ -60,7 +58,7 @@ class SignUpContent extends React.Component {
<div>
<div className={styles.header}>
<h1>
{lang.t('sign_in.sign_up')}
{t('sign_in.sign_up')}
</h1>
</div>
@@ -69,19 +67,19 @@ class SignUpContent extends React.Component {
<div>
<div className={styles.socialConnections}>
<Button cStyle="facebook" onClick={fetchSignUpFacebook} full>
{lang.t('sign_in.facebook_sign_up')}
{t('sign_in.facebook_sign_up')}
</Button>
</div>
<div className={styles.separator}>
<h1>
{lang.t('sign_in.or')}
{t('sign_in.or')}
</h1>
</div>
<form onSubmit={handleSignUp}>
<TextField
id="email"
type="email"
label={lang.t('sign_in.email')}
label={t('sign_in.email')}
value={formData.email}
style={{fontSize: 16}}
showErrors={showErrors}
@@ -91,7 +89,7 @@ class SignUpContent extends React.Component {
<TextField
id="username"
type="text"
label={lang.t('sign_in.username')}
label={t('sign_in.username')}
value={formData.username}
showErrors={showErrors}
style={{fontSize: 16}}
@@ -101,7 +99,7 @@ class SignUpContent extends React.Component {
<TextField
id="password"
type="password"
label={lang.t('sign_in.password')}
label={t('sign_in.password')}
value={formData.password}
showErrors={showErrors}
style={{fontSize: 16}}
@@ -113,7 +111,7 @@ class SignUpContent extends React.Component {
<TextField
id="confirmPassword"
type="password"
label={lang.t('sign_in.confirm_password')}
label={t('sign_in.confirm_password')}
value={formData.confirmPassword}
style={{fontSize: 16}}
showErrors={showErrors}
@@ -123,7 +121,7 @@ class SignUpContent extends React.Component {
/>
<div className={styles.action}>
<Button type="submit" cStyle="black" id='coralSignUpButton' className={styles.signInButton} full>
{lang.t('sign_in.sign_up')}
{t('sign_in.sign_up')}
</Button>
{ auth.isLoading && <Spinner /> }
</div>
@@ -136,13 +134,13 @@ class SignUpContent extends React.Component {
<Success />
{
emailVerificationEnabled &&
<p>{lang.t('sign_in.verify_email')}<br /><br />{lang.t('sign_in.verify_email2')}</p>
<p>{t('sign_in.verify_email')}<br /><br />{t('sign_in.verify_email2')}</p>
}
</div>
}
<div className={styles.footer}>
{lang.t('sign_in.already_have_an_account')} <a id="coralSignInViewTrigger" onClick={() => changeView('SIGNIN')}>
{lang.t('sign_in.sign_in')}
{t('sign_in.already_have_an_account')} <a id="coralSignInViewTrigger" onClick={() => changeView('SIGNIN')}>
{t('sign_in.sign_in')}
</a>
</div>
</div>
+4 -6
View File
@@ -1,14 +1,12 @@
import React from 'react';
import styles from './styles.css';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
const UserBox = ({className, user, onLogout, onShowProfile}) => (
<div className={`${styles.userBox} ${className ? className : ''}`}>
{lang.t('sign_in.logged_in_as')}
<a onClick={onShowProfile}>{user.username}</a>. {lang.t('sign_in.not_you')}
<a className={styles.logout} onClick={onLogout} id='logout'>{lang.t('sign_in.logout')}</a>
{t('sign_in.logged_in_as')}
<a onClick={onShowProfile}>{user.username}</a>. {t('sign_in.not_you')}
<a className={styles.logout} onClick={onLogout} id='logout'>{t('sign_in.logout')}</a>
</div>
);
@@ -6,9 +6,7 @@ import errorMsj from 'coral-framework/helpers/error';
import CreateUsernameDialog from '../components/CreateUsernameDialog';
import I18n from 'coral-i18n/modules/i18n/i18n';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
import {
showCreateUsernameDialog,
@@ -63,7 +61,7 @@ class ChangeUsernameContainer extends Component {
const {addError} = this;
if (!value.length) {
addError(name, lang.t('createdisplay.required_field'));
addError(name, t('createdisplay.required_field'));
} else if (!validate[name](value)) {
addError(name, errorMsj[name]);
} else {
@@ -91,7 +89,7 @@ class ChangeUsernameContainer extends Component {
this.props.createUsername(this.props.user.id, this.state.formData);
validForm();
} else {
invalidForm(lang.t('createdisplay.check_the_form'));
invalidForm(t('createdisplay.check_the_form'));
}
}
@@ -3,10 +3,9 @@ import {connect} from 'react-redux';
import SignDialog from '../components/SignDialog';
import validate from 'coral-framework/helpers/validate';
import errorMsj from 'coral-framework/helpers/error';
import I18n from 'coral-i18n/modules/i18n/i18n';
import {pym} from 'coral-framework';
const lang = new I18n();
import t from 'coral-i18n/services/i18n';
import {
changeView,
@@ -59,7 +58,7 @@ class SignInContainer extends Component {
window.authCallback = this.props.facebookCallback;
const {formData} = this.state;
const errors = Object.keys(formData).reduce((map, prop) => {
map[prop] = lang.t('sign_in.required_field');
map[prop] = t('sign_in.required_field');
return map;
}, {});
this.setState({errors});
@@ -109,9 +108,9 @@ class SignInContainer extends Component {
const {formData} = this.state;
if (!value.length) {
addError(name, lang.t('sign_in.required_field'));
addError(name, t('sign_in.required_field'));
} else if (name === 'confirmPassword' && formData.confirmPassword !== formData.password) {
addError('confirmPassword', lang.t('sign_in.passwords_dont_match'));
addError('confirmPassword', t('sign_in.passwords_dont_match'));
} else if (!validate[name](value)) {
addError(name, errorMsj[name]);
} else {
@@ -139,7 +138,7 @@ class SignInContainer extends Component {
fetchSignUp(this.state.formData, pym.parentUrl || location.href);
validForm();
} else {
invalidForm(lang.t('sign_in.check_the_form'));
invalidForm(t('sign_in.check_the_form'));
}
}
-102
View File
@@ -1,102 +0,0 @@
{
"en": {
"signIn": {
"emailVerifyCTA": "Please verify your email address.",
"requestNewVerifyEmail": "Request another email:",
"verifyEmail": "Thank you for creating an account! We sent an email to the address you provided to verify your account.",
"verifyEmail2": "You must verify your account before engaging with the community.",
"notYou": "Not you?",
"loggedInAs": "Logged in as",
"facebookSignIn": "Sign in with Facebook",
"facebookSignUp": "Sign up with Facebook",
"logout": "Logout",
"signIn": "Sign in to join the conversation",
"or": "Or",
"email": "E-mail Address",
"password": "Password",
"forgotYourPass": "Forgot your password?",
"needAnAccount": "Need an account?",
"register": "Register",
"signUp": "Sign Up",
"confirmPassword": "Confirm Password",
"username": "Username",
"alreadyHaveAnAccount": "Already have an account?",
"recoverPassword": "Recover password",
"emailInUse": "Email address already in use",
"emailORusernameInUse": "Email address or Username already in use",
"requiredField": "This field is required",
"passwordsDontMatch": "Passwords don't match.",
"specialCharacters": "Usernames can contain letters, numbers and _ only",
"checkTheForm": "Invalid Form. Please, check the fields"
},
"createdisplay": {
"writeyourusername": "Edit your username",
"yourusername": "Your username appears on every comment you post.",
"ifyoudontchangeyourname": "If you don't change your username at this step, your Facebook display name will appear alongside of all your comments.",
"username": "Username",
"continue": "Continue with the same Facebook username",
"save": "Save",
"fakecommentdate": "1 minute ago",
"fakecommentbody": "This is an example comment. Readers can share their thoughts and opinions with newsrooms in the comments section.",
"requiredField": "Required field",
"errorCreate": "Error when changing username",
"checkTheForm": "Invalid Form. Please, check the fields",
"specialCharacters": "Usernames can contain letters, numbers and _ only"
},
"permalink": {
"permalink": "Link"
},
"report": "Report",
"like": "Like"
},
"es": {
"signIn": {
"emailVerifyCTA": "Por favor verifique su e-mail.",
"requestNewVerifyEmail": "Enviar otro correo:",
"verifyEmail": "¡Gracias por crear una cuenta! Le enviamos un correo a la dirección que dio para verificar su cuenta.",
"verifyEmail2": "Debe verificarla antes de poder involucrarse en la comunidad.",
"notYou": "¿No eres tu?",
"loggedInAs": "Entraste como",
"facebookSignIn": "Entrar con Facebook",
"facebookSignUp": "Regístrate con Facebook",
"logout": "Salir",
"signIn": "Entrar para Unirte a la Conversación",
"or": "o",
"email": "E-mail",
"password": "Contraseña",
"forgotYourPass": "¿Has olvidado tu contraseña?",
"needAnAccount": "¿Necesitas una cuenta?",
"register": "Regístrate",
"signUp": "Registro",
"confirmPassword": "Confirmar Contraseña",
"username": "Nombre",
"alreadyHaveAnAccount": "¿Ya tienes una cuenta?",
"recoverPassword": "Recuperar contraseña",
"emailInUse": "Este e-mail se encuentra en uso",
"emailORusernameInUse": "Este e-mail ó nombre de usuario se encuentran en uso",
"requiredField": "Este campo es requerido",
"passwordsDontMatch": "Las contraseñas no coinciden",
"specialCharacters": "Los nombres pueden contener letras, números y _",
"checkTheForm": "Formulario Inválido. Por favor, completa los campos"
},
"createdisplay": {
"writeyourusername": "Edita tu nombre",
"yourusername": "Tu nombre aparece en cada comentario que publiques.",
"ifyoudontchangeyourname": "Si no modificas tu nombre de usuario en este paso, tu nombre de Facebook aparecera al lado de cada comentario que publiques.",
"username": "Nombre",
"continue": "Continuar con nombre de Facebook",
"save": "Guardar",
"fakecommentdate": "hace un minuto",
"fakecommentbody": "Este es un comentario de ejemplo. Las lectoras pueden compartir sus ideas y opiniones con los periodistas en la sección de comentarios.",
"requiredField": "Campo necesario",
"errorCreate": "Hubo un error al cambiar el nombre de usuario",
"checkTheForm": "Formulario Inválido. Por favor, verifica los campos",
"specialCharacters": "Sólo pueden contener letras, números y _"
},
"permalink": {
"permalink": "Enlace"
},
"report": "Marcar",
"like": "Me gusta"
}
}
@@ -2,12 +2,11 @@ import React, { Component } from 'react';
import styles from './style.css';
import Icon from './Icon';
import { I18n } from 'coral-framework';
import t from 'coral-i18n/services/i18n';
import cn from 'classnames';
import translations from '../translations.json';
import { getMyActionSummary, getTotalActionCount } from 'coral-framework/utils';
const lang = new I18n(translations);
const name = 'coral-plugin-like';
class LikeButton extends Component {
@@ -62,7 +61,7 @@ class LikeButton extends Component {
onClick={this.handleClick}
>
<span className={`${name}-button-text`}>
{lang.t(myLike ? 'liked' : 'like')}
{t(myLike ? 'liked' : 'like')}
</span>
<i
className={cn(
@@ -1,5 +1,10 @@
import LikeButton from './containers/LikeButton';
import translations from './translations.json';
import {loadTranslations} from '/coral-i18n/services/i18n';
Promise.all([loadTranslations(translations)]);
export default {
slots: {
commentReactions: [LikeButton]
@@ -1,10 +1,8 @@
import React from 'react';
import {Icon} from 'coral-ui';
import styles from './styles.css';
import {I18n} from 'coral-framework';
import translations from './translations.json';
import t from 'coral-i18n/services/i18n';
import {withReaction} from 'coral-plugin-api';
const lang = new I18n(translations);
class LoveButton extends React.Component {
handleClick = () => {
@@ -41,7 +39,7 @@ class LoveButton extends React.Component {
className={`${styles.button} ${alreadyReacted() ? styles.loved : ''}`}
onClick={this.handleClick}
>
<span>{lang.t(alreadyReacted() ? 'loved' : 'love')}</span>
<span>{t(alreadyReacted() ? 'loved' : 'love')}</span>
<Icon name="favorite" />
<span>{count > 0 && count}</span>
</button>
@@ -1,5 +1,10 @@
import LoveButton from './LoveButton';
import translations from './translations.json';
import {loadTranslations} from '/coral-i18n/services/i18n';
Promise.all([loadTranslations(translations)]);
export default {
slots: {
commentReactions: [LoveButton]
-1
View File
@@ -34,4 +34,3 @@ module.exports = {
}
}
};
@@ -2,13 +2,10 @@ import React, {Component} from 'react';
import styles from './style.css';
import Icon from './Icon';
import I18n from 'coral-i18n/modules/i18n/i18n';
import t from 'coral-i18n/services/i18n';
import cn from 'classnames';
import translations from '../translations.json';
import {getMyActionSummary, getTotalActionCount} from 'coral-framework/utils';
const lang = new I18n(translations);
import {getMyActionSummary, getTotalActionCount} from 'coral-framework/utils';
class RespectButton extends Component {
@@ -54,7 +51,7 @@ class RespectButton extends Component {
<button
className={cn(styles.button, {[styles.respected]: myRespect})}
onClick={this.handleClick} >
<span>{lang.t(myRespect ? 'respected' : 'respect')}</span>
<span>{t(myRespect ? 'respected' : 'respect')}</span>
<Icon className={cn(styles.icon, {[styles.respected]: myRespect})} />
{count > 0 && count}
</button>
@@ -1,5 +1,10 @@
import RespectButton from './containers/RespectButton';
import translations from './translations.json';
import {loadTranslations} from 'coral-i18n/services/i18n';
Promise.all([loadTranslations(translations)]);
export default {
slots: {
commentActions: [RespectButton],
+2 -2
View File
@@ -117,9 +117,9 @@ module.exports = {
loader: 'graphql-tag/loader'
},
{
test: /\.yaml$/,
loader: 'yaml',
include: path.resolve('locales'),
loader: 'yaml'
test: /\.yml$/,
}
]
},
+7 -14
View File
@@ -4604,9 +4604,9 @@ jwt-decode@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-2.2.0.tgz#7d86bd56679f58ce6a84704a657dd392bba81a79"
kareem@1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/kareem/-/kareem-1.4.0.tgz#640285bc0174f10d4bf2127bb30e861bc0372c1c"
kareem@1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/kareem/-/kareem-1.4.1.tgz#ed76200044fa041ef32b4da8261e2553f1173531"
keymaster@^1.6.2:
version "1.6.2"
@@ -5250,14 +5250,14 @@ mongodb@2.2.26:
mongodb-core "2.1.10"
readable-stream "2.2.7"
mongoose@^4.9.1:
version "4.9.6"
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-4.9.6.tgz#8485879893a33fe4b8c8b596950cfa9a8d597ec1"
mongoose@^4.9.8:
version "4.9.9"
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-4.9.9.tgz#8671fbe06c945f55fba7ad03797bc02f19516762"
dependencies:
async "2.1.4"
bson "~1.0.4"
hooks-fixed "2.0.0"
kareem "1.4.0"
kareem "1.4.1"
mongodb "2.2.26"
mpath "0.2.1"
mpromise "0.5.5"
@@ -8450,13 +8450,6 @@ 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"