mirror of
https://github.com/wassname/talk.git
synced 2026-09-13 13:10:43 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45c193b9bf | ||
|
|
ed037f8461 | ||
|
|
7bb0c73ee4 | ||
|
|
f13654b297 | ||
|
|
4a165c0972 | ||
|
|
bbf034a595 | ||
|
|
9f6ddd3801 | ||
|
|
34184d07eb | ||
|
|
057d083341 | ||
|
|
c5f107a168 | ||
|
|
17a801d6d2 | ||
|
|
888a61f895 | ||
|
|
9edf1d7c41 | ||
|
|
b802fdd5eb | ||
|
|
1a7b3fe903 | ||
|
|
cadbbd0b5c | ||
|
|
b6101b880d | ||
|
|
afb9fdcdc1 | ||
|
|
53abb65da1 | ||
|
|
7b5192d40c | ||
|
|
8fdea8734a | ||
|
|
588fbb0eb9 | ||
|
|
a28024dfed | ||
|
|
343eb3e8b6 | ||
|
|
80319f9aca | ||
|
|
33e1e5e729 | ||
|
|
ea2b2bc2e3 | ||
|
|
6ca2f21bc2 | ||
|
|
0d9b795740 | ||
|
|
73482d68ac | ||
|
|
e837dfc3c1 | ||
|
|
2cd9a71d62 | ||
|
|
ad73fcd94b | ||
|
|
66145d6fd5 | ||
|
|
7d246bba76 | ||
|
|
0ce0d57a96 | ||
|
|
792bc713f2 | ||
|
|
399f5ef7ba | ||
|
|
14c0945687 | ||
|
|
52f2f48385 | ||
|
|
e52605e26b | ||
|
|
ae4d6e2424 | ||
|
|
968d20e744 | ||
|
|
49d2416172 | ||
|
|
aac7cae6d6 | ||
|
|
f4fd843efe | ||
|
|
c4de69218c | ||
|
|
94ae029a4a | ||
|
|
1dc1f91b72 | ||
|
|
c98216cf3c | ||
|
|
2c9f8586d3 | ||
|
|
4ce5d97e3b | ||
|
|
3ea2632187 | ||
|
|
c9b709ad43 | ||
|
|
dcd7145510 | ||
|
|
d3896ed97d | ||
|
|
47a3cba5f5 | ||
|
|
0f1cabe126 | ||
|
|
5f62083c2f | ||
|
|
3cabe50a7b | ||
|
|
c0efc33044 | ||
|
|
9344c1bc80 | ||
|
|
1bfe0fbac1 | ||
|
|
b3d704be76 | ||
|
|
3c100160fb | ||
|
|
49c7d2eeda | ||
|
|
cff9b29a36 | ||
|
|
5a1f93975c | ||
|
|
cd6da751a6 | ||
|
|
41610ccf57 | ||
|
|
607a59ad63 | ||
|
|
c0fea4821b | ||
|
|
8432df15a1 | ||
|
|
61486caa9e | ||
|
|
7f45f7e2e2 | ||
|
|
9e511817a8 | ||
|
|
4015e19040 | ||
|
|
c1fcc82b62 | ||
|
|
893c8d32b2 | ||
|
|
2dfadebd42 | ||
|
|
a2d5af1372 | ||
|
|
7a5416a807 | ||
|
|
8c2c632f52 | ||
|
|
fabec2c89b | ||
|
|
7f18603fd5 | ||
|
|
3a69e0cf96 | ||
|
|
7ad3d247b5 | ||
|
|
130dc578b3 | ||
|
|
fd7114ab2a | ||
|
|
5e4bdf1f0c | ||
|
|
71e1b69afe | ||
|
|
6fa18f6c7c | ||
|
|
bda9b55562 | ||
|
|
d843320c4a | ||
|
|
8a88228d9c | ||
|
|
0a9664d464 | ||
|
|
b3749b9332 | ||
|
|
aecb7de019 | ||
|
|
ade3cf6252 | ||
|
|
1837ae4a0f | ||
|
|
334074a7ca | ||
|
|
f93c4adc97 | ||
|
|
bb54009567 | ||
|
|
c126d217ad | ||
|
|
8b2dc3a46d | ||
|
|
d0eca26d5b | ||
|
|
b742923897 | ||
|
|
1781b926d9 | ||
|
|
9222ee57a5 | ||
|
|
67cca7d85d | ||
|
|
7b97a8fca2 | ||
|
|
6bff2de371 | ||
|
|
05283b08f7 | ||
|
|
838687a3ae | ||
|
|
7b0213299a | ||
|
|
f4dbc7a24d | ||
|
|
161e8b4117 | ||
|
|
6f3535984c | ||
|
|
e3557c1f7a | ||
|
|
692b6af09d | ||
|
|
25932e10d6 | ||
|
|
ec13a001a2 | ||
|
|
702a616e6c | ||
|
|
a3dd208fbd | ||
|
|
55c3406990 | ||
|
|
197fbc33e0 | ||
|
|
008a4fd7d5 | ||
|
|
8c5665095f | ||
|
|
647b2ea0c8 | ||
|
|
e61f88b98d | ||
|
|
b024421bbb | ||
|
|
ce95467145 | ||
|
|
1564b380b1 | ||
|
|
593b8959c5 | ||
|
|
3fda3b4b7c | ||
|
|
7e680038d6 | ||
|
|
71b8bb5d60 | ||
|
|
cfbafdeb5c | ||
|
|
c19d4a433a | ||
|
|
13cc80bd35 | ||
|
|
1eea2daeae | ||
|
|
5b29e7d351 | ||
|
|
3af39d99e4 | ||
|
|
1abf988366 | ||
|
|
205f943ab5 | ||
|
|
879683da4f | ||
|
|
974e884432 | ||
|
|
846319f1a9 | ||
|
|
e5237ae805 | ||
|
|
b9d88251e6 | ||
|
|
0d720626d4 | ||
|
|
50b2c6aa88 | ||
|
|
382019d907 | ||
|
|
97103739c2 | ||
|
|
9cf13691ad | ||
|
|
e6107173fb | ||
|
|
1d9ec7a779 | ||
|
|
0c345fe913 | ||
|
|
b6f06f1e89 | ||
|
|
aea3a7449e | ||
|
|
4db73ae73a | ||
|
|
2af7acd3db | ||
|
|
da9847b88f | ||
|
|
5b9f9f1b0d | ||
|
|
5427f295f6 | ||
|
|
bcb294c625 | ||
|
|
b070a7cc52 | ||
|
|
e48d89a607 | ||
|
|
cb57e5c1e1 | ||
|
|
bf363621d3 |
@@ -14,11 +14,11 @@ Learn more about Talk, including a deep dive into features for commenters and mo
|
||||
|
||||
## Pre-Launch Guide
|
||||
|
||||
You’ve installed Talk on your server, and you’re preparing to launch it on your site. The real community work starts now, before you go live. You have a unique opportunity pre-launch to set your community up for success. Read our [Talk Community Guide](https://blog.coralproject.net/youve-installed-talk-now-what/).
|
||||
You’ve installed Talk on your server, and you’re preparing to launch it on your site. The real community work starts now, before you go live. You have a unique opportunity pre-launch to set your community up for success. Read our [Talk Community Guide](https://coralproject.net/blog/youve-installed-talk-now-what/).
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
For advanced configuration and usage of Talk, check out our [Configuration](https://docs.coralproject.net/talk/advanced-configuration/) and [Integration](https://docs.coralproject.net/talk/integrating/authentication/) how-tos. This covers topics in whih you will need dev support to fully customize and integrate Talk, such as SSO/authentication, creating and managing assets and articles, styling Talk with custom CSS, and setting up Notifications and SMTP support.
|
||||
For advanced configuration and usage of Talk, check out our [Configuration](https://docs.coralproject.net/talk/advanced-configuration/) and [Integration](https://docs.coralproject.net/talk/integrating/authentication/) how-tos. This covers topics in which you will need dev support to fully customize and integrate Talk, such as SSO/authentication, creating and managing assets and articles, styling Talk with custom CSS, and setting up Notifications and SMTP support.
|
||||
|
||||
## Versions & Upgrading
|
||||
|
||||
|
||||
@@ -219,6 +219,28 @@ async function rewrite(search, replace, options) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* debugAssetURL will scrape the given URL and print it's scraped values.
|
||||
*/
|
||||
async function debugAssetURL(url) {
|
||||
try {
|
||||
const meta = await scraper.scrape(url);
|
||||
|
||||
const table = new Table({ head: ['Property', 'Value'] });
|
||||
|
||||
for (const [property, value] of Object.entries(meta)) {
|
||||
table.push([property, value]);
|
||||
}
|
||||
|
||||
console.log(table.toString());
|
||||
|
||||
util.shutdown(0);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
util.shutdown(1);
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Setting up the program command line arguments.
|
||||
//==============================================================================
|
||||
@@ -234,6 +256,13 @@ program
|
||||
.description('list all the assets in the database')
|
||||
.action(listAssets);
|
||||
|
||||
program
|
||||
.command('debug [url]')
|
||||
.description(
|
||||
'prints the scraped metadata that would be added to the given asset'
|
||||
)
|
||||
.action(debugAssetURL);
|
||||
|
||||
program
|
||||
.command('refresh [age]')
|
||||
.description('queues the assets that exceed the age requested')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import queryString from 'query-string';
|
||||
import queryString from 'querystringify';
|
||||
|
||||
import {
|
||||
FETCH_USERS_REQUEST,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import queryString from 'query-string';
|
||||
import queryString from 'querystringify';
|
||||
|
||||
import {
|
||||
FETCH_ASSETS_REQUEST,
|
||||
|
||||
@@ -7,9 +7,9 @@ import t from 'coral-framework/services/i18n';
|
||||
import { can } from 'coral-framework/services/perms';
|
||||
import cn from 'classnames';
|
||||
|
||||
const CoralDrawer = ({ handleLogout, currentUser }) => (
|
||||
<Drawer className={cn('talk-admin-drawer-nav', styles.drawer)}>
|
||||
{currentUser && can(currentUser, 'ACCESS_ADMIN') ? (
|
||||
const CoralDrawer = ({ handleLogout, currentUser }) =>
|
||||
currentUser && can(currentUser, 'ACCESS_ADMIN') ? (
|
||||
<Drawer className={cn('talk-admin-drawer-nav', styles.drawer)}>
|
||||
<div>
|
||||
<Navigation className={styles.nav}>
|
||||
{can(currentUser, 'MODERATE_COMMENTS') && (
|
||||
@@ -48,9 +48,8 @@ const CoralDrawer = ({ handleLogout, currentUser }) => (
|
||||
<span>{`v${process.env.VERSION}`}</span>
|
||||
</Navigation>
|
||||
</div>
|
||||
) : null}
|
||||
</Drawer>
|
||||
);
|
||||
</Drawer>
|
||||
) : null;
|
||||
|
||||
CoralDrawer.propTypes = {
|
||||
handleLogout: PropTypes.func.isRequired,
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import React from 'react';
|
||||
import styles from './Forbidden.css';
|
||||
import t from 'coral-framework/services/i18n';
|
||||
|
||||
const Forbidden = () => (
|
||||
<div className={styles.container}>
|
||||
<p className={styles.copy}>
|
||||
This page is for team use only. Please contact an administrator if you
|
||||
want to join this team.
|
||||
</p>
|
||||
<p className={styles.copy}>{t('error.PAGE_NOT_AVAILABLE_ROLE')}</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class ForgotPassword extends React.Component {
|
||||
href="#"
|
||||
onClick={this.handleSignInLink}
|
||||
>
|
||||
Sign in
|
||||
{t('login.sign_in')}
|
||||
</a>
|
||||
<Success />
|
||||
</div>
|
||||
@@ -48,7 +48,7 @@ class ForgotPassword extends React.Component {
|
||||
onChange={this.handleEmailChange}
|
||||
/>
|
||||
<Button type="submit" cStyle="black" full>
|
||||
{t('login.reset_password')}
|
||||
{t('login.reset_password_send_button')}
|
||||
</Button>
|
||||
<p className={styles.cta}>
|
||||
{t('login.go_back')}{' '}
|
||||
|
||||
@@ -14,7 +14,9 @@ import ApproveButton from './ApproveButton';
|
||||
import RejectButton from 'coral-admin/src/components/RejectButton';
|
||||
import CommentDeletedTombstone from './CommentDeletedTombstone';
|
||||
|
||||
import t, { timeago } from 'coral-framework/services/i18n';
|
||||
import { buildCommentURL } from 'coral-framework/utils/url';
|
||||
import TimeAgo from 'coral-framework/components/TimeAgo';
|
||||
import t from 'coral-framework/services/i18n';
|
||||
|
||||
class UserDetailComment extends React.Component {
|
||||
approve = () =>
|
||||
@@ -73,9 +75,7 @@ class UserDetailComment extends React.Component {
|
||||
checked={selected}
|
||||
onChange={e => toggleSelect(e.target.value, e.target.checked)}
|
||||
/>
|
||||
<span className={styles.created}>
|
||||
{timeago(comment.created_at)}
|
||||
</span>
|
||||
<TimeAgo className={styles.created} datetime={comment.created_at} />
|
||||
{comment.editing && comment.editing.edited ? (
|
||||
<span>
|
||||
<span className={styles.editedMarker}>
|
||||
@@ -112,7 +112,7 @@ class UserDetailComment extends React.Component {
|
||||
/>
|
||||
<a
|
||||
className={styles.external}
|
||||
href={`${comment.asset.url}?commentId=${comment.id}`}
|
||||
href={buildCommentURL(comment.asset.url, comment.id)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
@@ -123,7 +123,7 @@ class UserDetailComment extends React.Component {
|
||||
<IfHasLink text={comment.body}>
|
||||
<span className={styles.hasLinks}>
|
||||
{/* TODO: translate string */}
|
||||
<Icon name="error_outline" /> Contains Link
|
||||
<Icon name="error_outline" /> {t('common.contains_link')}
|
||||
</span>
|
||||
</IfHasLink>
|
||||
<div className={styles.actions}>
|
||||
|
||||
@@ -34,6 +34,21 @@
|
||||
}
|
||||
}
|
||||
|
||||
.filterHeader {
|
||||
margin-top: 30px;
|
||||
font-size: 16px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.filterDetail {
|
||||
margin-top: 15px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.radioGroup {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.mainContent {
|
||||
width: calc(100% - 300px);
|
||||
padding: 34px 14px;
|
||||
|
||||
@@ -9,6 +9,7 @@ import PropTypes from 'prop-types';
|
||||
import ActionsMenu from 'coral-admin/src/components/ActionsMenu';
|
||||
import ActionsMenuItem from 'coral-admin/src/components/ActionsMenuItem';
|
||||
import { isSuspended, isBanned } from 'coral-framework/utils/user';
|
||||
import { RadioGroup, Radio } from 'react-mdl';
|
||||
import moment from 'moment';
|
||||
import {
|
||||
ADMIN,
|
||||
@@ -64,11 +65,12 @@ class People extends React.Component {
|
||||
|
||||
render() {
|
||||
const {
|
||||
onSearchChange,
|
||||
onFilterChange,
|
||||
users = [],
|
||||
setUserRole,
|
||||
viewUserDetail,
|
||||
loadMore,
|
||||
filters,
|
||||
} = this.props;
|
||||
|
||||
const hasResults = !!users.nodes.length;
|
||||
@@ -87,11 +89,43 @@ class People extends React.Component {
|
||||
id="commenters-search"
|
||||
type="text"
|
||||
className={styles.searchBoxInput}
|
||||
defaultValue=""
|
||||
onChange={onSearchChange}
|
||||
value={filters.search}
|
||||
onChange={onFilterChange('search')}
|
||||
placeholder={t('streams.search')}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.filterHeader}>
|
||||
{t('community.filter_users')}
|
||||
</div>
|
||||
<div className={styles.filterDetail}>{t('community.status')}</div>
|
||||
<RadioGroup
|
||||
name="statusFilter"
|
||||
value={filters.status}
|
||||
childContainer="div"
|
||||
onChange={onFilterChange('status')}
|
||||
className={styles.radioGroup}
|
||||
>
|
||||
<Radio value="">{t('community.all')}</Radio>
|
||||
<Radio value="active">{t('community.active')}</Radio>
|
||||
<Radio value="suspended">{t('community.suspended')}</Radio>
|
||||
<Radio value="banned">{t('community.banned')}</Radio>
|
||||
</RadioGroup>
|
||||
<div className={styles.filterDetail}>
|
||||
{t('community.filter_role')}
|
||||
</div>
|
||||
<RadioGroup
|
||||
name="roleFilter"
|
||||
value={filters.role}
|
||||
childContainer="div"
|
||||
onChange={onFilterChange('role')}
|
||||
className={styles.radioGroup}
|
||||
>
|
||||
<Radio value="">{t('community.all')}</Radio>
|
||||
<Radio value={ADMIN}>{t('community.admin')}</Radio>
|
||||
<Radio value={STAFF}>{t('community.staff')}</Radio>
|
||||
<Radio value={MODERATOR}>{t('community.moderator')}</Radio>
|
||||
<Radio value={COMMENTER}>{t('community.commenter')}</Radio>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
<div className={styles.mainContent}>
|
||||
{hasResults ? (
|
||||
@@ -176,7 +210,7 @@ class People extends React.Component {
|
||||
})
|
||||
}
|
||||
>
|
||||
Suspend User
|
||||
{t('modqueue.suspend')}
|
||||
</ActionsMenuItem>
|
||||
)}
|
||||
|
||||
@@ -195,7 +229,7 @@ class People extends React.Component {
|
||||
})
|
||||
}
|
||||
>
|
||||
Ban User
|
||||
{t('modqueue.ban_user_actions')}
|
||||
</ActionsMenuItem>
|
||||
)}
|
||||
</ActionsMenu>
|
||||
@@ -254,7 +288,8 @@ class People extends React.Component {
|
||||
|
||||
People.propTypes = {
|
||||
users: PropTypes.object.isRequired,
|
||||
onSearchChange: PropTypes.func.isRequired,
|
||||
filters: PropTypes.object.isRequired,
|
||||
onFilterChange: PropTypes.func.isRequired,
|
||||
setUserRole: PropTypes.func.isRequired,
|
||||
viewUserDetail: PropTypes.func.isRequired,
|
||||
unbanUser: PropTypes.func.isRequired,
|
||||
|
||||
@@ -17,59 +17,65 @@ import update from 'immutability-helper';
|
||||
import { Spinner } from 'coral-ui';
|
||||
import withQuery from 'coral-framework/hocs/withQuery';
|
||||
|
||||
class PeopleContainer extends React.Component {
|
||||
class PeopleContainer extends React.PureComponent {
|
||||
timer = null;
|
||||
|
||||
state = {
|
||||
searchValue: '',
|
||||
search: '',
|
||||
role: '',
|
||||
status: '',
|
||||
};
|
||||
|
||||
onSearchChange = e => {
|
||||
const { value } = e.target;
|
||||
this.setState({ searchValue: value }, () => {
|
||||
statusToQuery = {
|
||||
active: { suspended: false, banned: false },
|
||||
suspended: { suspended: true },
|
||||
banned: { banned: true },
|
||||
};
|
||||
|
||||
onFilterChange = filter => e =>
|
||||
this.setState({ [filter]: e.target.value }, () => {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = setTimeout(() => {
|
||||
this.search(value);
|
||||
}, 350);
|
||||
this.timer = setTimeout(this.filter, 350);
|
||||
});
|
||||
|
||||
getFilterState = () => {
|
||||
const { role, status } = this.state;
|
||||
|
||||
return {
|
||||
status: this.statusToQuery[status] || null,
|
||||
role: role || null,
|
||||
};
|
||||
};
|
||||
|
||||
search = async value => {
|
||||
return this.props.data.fetchMore({
|
||||
query: SEARCH_QUERY,
|
||||
filter = () =>
|
||||
this.props.data.fetchMore({
|
||||
query: FILTER_QUERY,
|
||||
variables: {
|
||||
value,
|
||||
state: this.getFilterState(),
|
||||
value: this.state.search,
|
||||
limit: 10,
|
||||
},
|
||||
updateQuery: (previous, { fetchMoreResult: { users } }) => {
|
||||
const updated = update(previous, {
|
||||
updateQuery: (previous, { fetchMoreResult: { users } }) =>
|
||||
update(previous, {
|
||||
users: {
|
||||
nodes: {
|
||||
$set: users.nodes,
|
||||
},
|
||||
nodes: { $set: users.nodes },
|
||||
hasNextPage: { $set: users.hasNextPage },
|
||||
endCursor: { $set: users.endCursor },
|
||||
},
|
||||
});
|
||||
return updated;
|
||||
},
|
||||
}),
|
||||
});
|
||||
};
|
||||
|
||||
setUserRole = async (id, role) => {
|
||||
await this.props.setUserRole(id, role);
|
||||
};
|
||||
|
||||
loadMore = () => {
|
||||
return this.props.data.fetchMore({
|
||||
loadMore = () =>
|
||||
this.props.data.fetchMore({
|
||||
query: LOAD_MORE_QUERY,
|
||||
variables: {
|
||||
value: this.state.searchValue,
|
||||
limit: 5,
|
||||
cursor: this.props.root.users.endCursor,
|
||||
state: this.getFilterState(),
|
||||
value: this.state.search,
|
||||
limit: 5,
|
||||
},
|
||||
updateQuery: (previous, { fetchMoreResult: { users } }) => {
|
||||
const updated = update(previous, {
|
||||
updateQuery: (previous, { fetchMoreResult: { users } }) =>
|
||||
update(previous, {
|
||||
users: {
|
||||
nodes: {
|
||||
$apply: nodes => appendNewNodes(nodes, users.nodes),
|
||||
@@ -77,11 +83,8 @@ class PeopleContainer extends React.Component {
|
||||
hasNextPage: { $set: users.hasNextPage },
|
||||
endCursor: { $set: users.endCursor },
|
||||
},
|
||||
});
|
||||
return updated;
|
||||
},
|
||||
}),
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
if (this.props.data.error) {
|
||||
@@ -98,9 +101,9 @@ class PeopleContainer extends React.Component {
|
||||
|
||||
return (
|
||||
<People
|
||||
onSearchChange={this.onSearchChange}
|
||||
onFilterChange={this.onFilterChange}
|
||||
viewUserDetail={this.props.viewUserDetail}
|
||||
setUserRole={this.setUserRole}
|
||||
setUserRole={this.props.setUserRole}
|
||||
showSuspendUserDialog={this.props.showSuspendUserDialog}
|
||||
showBanUserDialog={this.props.showBanUserDialog}
|
||||
unbanUser={this.props.unbanUser}
|
||||
@@ -109,6 +112,7 @@ class PeopleContainer extends React.Component {
|
||||
root={this.props.root}
|
||||
users={this.props.root.users}
|
||||
loadMore={this.loadMore}
|
||||
filters={this.state}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -125,16 +129,6 @@ PeopleContainer.propTypes = {
|
||||
root: PropTypes.object,
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch =>
|
||||
bindActionCreators(
|
||||
{
|
||||
viewUserDetail,
|
||||
showSuspendUserDialog,
|
||||
showBanUserDialog,
|
||||
},
|
||||
dispatch
|
||||
);
|
||||
|
||||
const LOAD_MORE_QUERY = gql`
|
||||
query TalkAdmin_Community_People_LoadMoreUsers(
|
||||
$limit: Int
|
||||
@@ -169,9 +163,13 @@ const LOAD_MORE_QUERY = gql`
|
||||
}
|
||||
`;
|
||||
|
||||
const SEARCH_QUERY = gql`
|
||||
query TalkAdmin_Community_People_SearchUsers($value: String, $limit: Int) {
|
||||
users(query: { value: $value, limit: $limit }) {
|
||||
const FILTER_QUERY = gql`
|
||||
query TalkAdmin_Community_People_FilterUsers(
|
||||
$state: UserStateInput
|
||||
$value: String
|
||||
$limit: Int
|
||||
) {
|
||||
users(query: { state: $state, value: $value, limit: $limit }) {
|
||||
hasNextPage
|
||||
endCursor
|
||||
nodes {
|
||||
@@ -199,6 +197,16 @@ const SEARCH_QUERY = gql`
|
||||
}
|
||||
`;
|
||||
|
||||
const mapDispatchToProps = dispatch =>
|
||||
bindActionCreators(
|
||||
{
|
||||
viewUserDetail,
|
||||
showSuspendUserDialog,
|
||||
showBanUserDialog,
|
||||
},
|
||||
dispatch
|
||||
);
|
||||
|
||||
export default compose(
|
||||
connect(
|
||||
null,
|
||||
|
||||
@@ -53,7 +53,7 @@ class EmbedLink extends Component {
|
||||
{t('embedlink.copy')}
|
||||
</Button>
|
||||
<div className={styles.copiedText}>
|
||||
{this.state.copied && 'Copied!'}
|
||||
{this.state.copied && t('embedlink.copied')}
|
||||
</div>
|
||||
</div>
|
||||
</ConfigureCard>
|
||||
|
||||
@@ -155,9 +155,19 @@ class StreamSettings extends React.Component {
|
||||
<ConfigureCard
|
||||
checked={settings.infoBoxEnable}
|
||||
onCheckbox={this.updateInfoBoxEnable}
|
||||
title={t('configure.include_comment_stream')}
|
||||
title={t('configure.code_of_conduct_summary')}
|
||||
>
|
||||
<p>{t('configure.include_comment_stream_desc')}</p>
|
||||
<p>
|
||||
{t('configure.code_of_conduct_summary_desc')}
|
||||
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://guides.coralproject.net/create-a-code-of-conduct/"
|
||||
>
|
||||
Code of Conduct Guide.
|
||||
</a>
|
||||
</p>
|
||||
<div
|
||||
className={cn(
|
||||
styles.configSettingInfoBox,
|
||||
@@ -238,12 +248,14 @@ class StreamSettings extends React.Component {
|
||||
onChange={this.updateClosedTimeout}
|
||||
value={getTimeoutAmount(settings.closedTimeout)}
|
||||
label={t('configure.closed_comments_label')}
|
||||
disabled={!settings.autoCloseStream}
|
||||
/>
|
||||
<div className={styles.configTimeoutSelect}>
|
||||
<SelectField
|
||||
label="comments closed time window"
|
||||
value={getTimeoutMeasure(settings.closedTimeout)}
|
||||
onChange={this.updateClosedTimeoutMeasure}
|
||||
readOnly={!settings.autoCloseStream}
|
||||
>
|
||||
<Option value={'hours'}>{t('configure.hours')}</Option>
|
||||
<Option value={'days'}>{t('configure.days')}</Option>
|
||||
|
||||
@@ -6,19 +6,23 @@ import ConfigureCard from 'coral-framework/components/ConfigureCard';
|
||||
|
||||
const Wordlist = ({ suspectWords, bannedWords, onChangeWordlist }) => (
|
||||
<div>
|
||||
<ConfigureCard title={t('configure.banned_words_title')}>
|
||||
<ConfigureCard collapsible title={t('configure.banned_words_title')}>
|
||||
<p>{t('configure.banned_word_text')}</p>
|
||||
<TagsInput
|
||||
value={bannedWords}
|
||||
inputProps={{ placeholder: 'word or phrase' }}
|
||||
inputProps={{
|
||||
placeholder: t('configure.suspect_or_forbidden_words_placeholder'),
|
||||
}}
|
||||
onChange={tags => onChangeWordlist('banned', tags)}
|
||||
/>
|
||||
</ConfigureCard>
|
||||
<ConfigureCard title={t('configure.suspect_word_title')}>
|
||||
<ConfigureCard collapsible title={t('configure.suspect_word_title')}>
|
||||
<p>{t('configure.suspect_word_text')}</p>
|
||||
<TagsInput
|
||||
value={suspectWords}
|
||||
inputProps={{ placeholder: 'word or phrase' }}
|
||||
inputProps={{
|
||||
placeholder: t('configure.suspect_or_forbidden_words_placeholder'),
|
||||
}}
|
||||
onChange={tags => onChangeWordlist('suspect', tags)}
|
||||
/>
|
||||
</ConfigureCard>
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
line-height: 1.5;
|
||||
font-weight: 300;
|
||||
margin-bottom: 8px;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.body {
|
||||
@@ -188,4 +189,4 @@
|
||||
|
||||
.commentContentFooter {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,10 @@ import cn from 'classnames';
|
||||
import ApproveButton from 'coral-admin/src/components/ApproveButton';
|
||||
import RejectButton from 'coral-admin/src/components/RejectButton';
|
||||
import CommentDeletedTombstone from '../../../components/CommentDeletedTombstone';
|
||||
import TimeAgo from 'coral-framework/components/TimeAgo';
|
||||
|
||||
import t, { timeago } from 'coral-framework/services/i18n';
|
||||
import { buildCommentURL } from 'coral-framework/utils/url';
|
||||
import t from 'coral-framework/services/i18n';
|
||||
|
||||
class Comment extends React.Component {
|
||||
ref = null;
|
||||
@@ -126,9 +128,10 @@ class Comment extends React.Component {
|
||||
{comment.user.username}
|
||||
</span>
|
||||
|
||||
<span className={styles.created}>
|
||||
{timeago(comment.created_at)}
|
||||
</span>
|
||||
<TimeAgo
|
||||
className={styles.created}
|
||||
datetime={comment.created_at}
|
||||
/>
|
||||
{comment.editing && comment.editing.edited ? (
|
||||
<span>
|
||||
<span className={styles.editedMarker}>
|
||||
@@ -168,7 +171,7 @@ class Comment extends React.Component {
|
||||
<div className={styles.commentContentFooter}>
|
||||
<a
|
||||
className={styles.external}
|
||||
href={`${comment.asset.url}?commentId=${comment.id}`}
|
||||
href={buildCommentURL(comment.asset.url, comment.id)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
@@ -180,8 +183,7 @@ class Comment extends React.Component {
|
||||
<div className={styles.sideActions}>
|
||||
<IfHasLink text={comment.body}>
|
||||
<span className={styles.hasLinks}>
|
||||
{/* TODO: translate string */}
|
||||
<Icon name="error_outline" /> Contains Link
|
||||
<Icon name="error_outline" /> {t('common.contains_link')}
|
||||
</span>
|
||||
</IfHasLink>
|
||||
<div className={`actions ${styles.actions}`}>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './Story.css';
|
||||
import t from 'coral-framework/services/i18n';
|
||||
|
||||
const formatDate = date => {
|
||||
const d = new Date(date);
|
||||
@@ -14,7 +15,9 @@ const Story = ({ author, title, createdAt, open, id, goToStory }) => {
|
||||
<div className={styles.meta}>
|
||||
<span className={styles.author}>By {author}</span>
|
||||
<span className={styles.createdAt}>{formatDate(createdAt)}</span>
|
||||
<span className={styles.status}>{open ? 'Open' : 'Closed'}</span>
|
||||
<span className={styles.status}>
|
||||
{open ? t('streams.open') : t('streams.closed')}
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
|
||||
@@ -50,7 +50,7 @@ class StoriesContainer extends Component {
|
||||
const { updateAssetState } = this.props;
|
||||
|
||||
try {
|
||||
updateAssetState(id, closeStream ? Date.now() : null);
|
||||
await updateAssetState(id, closeStream ? Date.now() : null);
|
||||
this.fetchAssets();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { createPostMessage } from 'coral-framework/services/postMessage';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const staticConfig = getStaticConfiguration();
|
||||
const { STATIC_ORIGIN: origin } = staticConfig;
|
||||
const { BASE_ORIGIN: origin } = staticConfig;
|
||||
const postMessage = createPostMessage(origin);
|
||||
|
||||
// Get the auth element and parse it as JSON by decoding it.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as actions from '../constants/stream';
|
||||
import { buildUrl } from 'coral-framework/utils/url';
|
||||
import queryString from 'query-string';
|
||||
import queryString from 'querystringify';
|
||||
|
||||
export const setActiveReplyBox = id => ({
|
||||
type: actions.SET_ACTIVE_REPLY_BOX,
|
||||
@@ -14,12 +14,13 @@ export const setSort = ({ sortOrder, sortBy }) => ({
|
||||
});
|
||||
|
||||
export const viewAllComments = () => (dispatch, _, { pym }) => {
|
||||
const search = queryString.stringify({
|
||||
...queryString.parse(location.search),
|
||||
comment_id: undefined,
|
||||
});
|
||||
const query = queryString.parse(location.search);
|
||||
|
||||
// remove the comment_id url param
|
||||
delete query.comment_id;
|
||||
|
||||
const search = queryString.stringify(query);
|
||||
|
||||
const url = buildUrl({ ...location, search });
|
||||
|
||||
try {
|
||||
|
||||
@@ -9,6 +9,7 @@ import cn from 'classnames';
|
||||
import { getTotalReactionsCount } from 'coral-framework/utils';
|
||||
|
||||
import t from 'coral-framework/services/i18n';
|
||||
import { buildCommentURL } from 'coral-framework/utils/url';
|
||||
|
||||
class Comment extends React.Component {
|
||||
render() {
|
||||
@@ -79,9 +80,10 @@ class Comment extends React.Component {
|
||||
<li>
|
||||
<a
|
||||
className={styles.viewLink}
|
||||
href={`${this.props.comment.asset.url}?commentId=${
|
||||
href={buildCommentURL(
|
||||
this.props.comment.asset.url,
|
||||
this.props.comment.id
|
||||
}`}
|
||||
)}
|
||||
target="_parent"
|
||||
>
|
||||
<Icon name="open_in_new" className={styles.iconView} />
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
.comment {
|
||||
position: relative;
|
||||
padding-left: 15px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.commentContainer {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.commentLevel0 {
|
||||
@@ -138,6 +143,7 @@
|
||||
}
|
||||
|
||||
.commentAvatar {
|
||||
margin-top: 10px;
|
||||
max-width: 60px;
|
||||
}
|
||||
|
||||
|
||||
@@ -645,7 +645,7 @@ export default class Comment extends React.Component {
|
||||
})}
|
||||
onClick={this.onClickEdit}
|
||||
>
|
||||
Edit
|
||||
{t('framework.edit')}
|
||||
</a>
|
||||
)}
|
||||
</span>
|
||||
|
||||
@@ -38,5 +38,4 @@
|
||||
position: relative;
|
||||
margin-top: 28px;
|
||||
padding-bottom: 50px;
|
||||
min-height: 600px;
|
||||
}
|
||||
|
||||
@@ -206,15 +206,30 @@ class Stream extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
renderQuestionBox() {
|
||||
const {
|
||||
root,
|
||||
asset,
|
||||
asset: {
|
||||
settings: { questionBoxEnable, questionBoxContent, questionBoxIcon },
|
||||
},
|
||||
} = this.props;
|
||||
const slotPassthrough = { root, asset };
|
||||
if (questionBoxEnable) {
|
||||
return (
|
||||
<QuestionBox content={questionBoxContent} icon={questionBoxIcon}>
|
||||
<Slot fill="streamQuestionArea" passthrough={slotPassthrough} />
|
||||
</QuestionBox>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
root,
|
||||
appendItemArray,
|
||||
asset,
|
||||
asset: {
|
||||
comment: highlightedComment,
|
||||
settings: { questionBoxEnable },
|
||||
},
|
||||
asset: { comment: highlightedComment },
|
||||
postComment,
|
||||
notify,
|
||||
updateItem,
|
||||
@@ -260,14 +275,7 @@ class Stream extends React.Component {
|
||||
content={asset.settings.infoBoxContent}
|
||||
enable={asset.settings.infoBoxEnable}
|
||||
/>
|
||||
{questionBoxEnable && (
|
||||
<QuestionBox
|
||||
content={asset.settings.questionBoxContent}
|
||||
icon={asset.settings.questionBoxIcon}
|
||||
>
|
||||
<Slot fill="streamQuestionArea" passthrough={slotPassthrough} />
|
||||
</QuestionBox>
|
||||
)}
|
||||
{this.renderQuestionBox()}
|
||||
{!banned &&
|
||||
temporarilySuspended && (
|
||||
<RestrictedMessageBox>
|
||||
@@ -305,6 +313,7 @@ class Stream extends React.Component {
|
||||
) : (
|
||||
<Markdown content={asset.settings.disableCommentingMessage} />
|
||||
)}
|
||||
{this.renderQuestionBox()}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import queryString from 'query-string';
|
||||
import queryString from 'querystringify';
|
||||
import pym from 'pym.js';
|
||||
import EventEmitter from 'eventemitter2';
|
||||
import { buildUrl } from 'coral-framework/utils/url';
|
||||
@@ -94,12 +94,13 @@ export default class Stream {
|
||||
|
||||
// Remove the permalink comment id from the hash.
|
||||
this.pym.onMessage('coral-view-all-comments', () => {
|
||||
const search = queryString.stringify({
|
||||
...queryString.parse(location.search),
|
||||
commentId: undefined,
|
||||
});
|
||||
const query = queryString.parse(location.search);
|
||||
|
||||
// Remove the commentId url param.
|
||||
delete query.commentId;
|
||||
|
||||
const search = queryString.stringify(query);
|
||||
|
||||
const url = buildUrl({ ...location, search });
|
||||
|
||||
// Change the url.
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
import * as actions from '../constants/auth';
|
||||
import jwtDecode from 'jwt-decode';
|
||||
|
||||
function cleanAuthData(localStorage) {
|
||||
localStorage.removeItem('token');
|
||||
localStorage.removeItem('exp');
|
||||
}
|
||||
import { setStorageAuthToken, clearStorageAuthToken } from '../services/auth';
|
||||
|
||||
export const checkLogin = () => (
|
||||
dispatch,
|
||||
@@ -15,7 +10,7 @@ export const checkLogin = () => (
|
||||
rest('/auth')
|
||||
.then(result => {
|
||||
if (!result.user) {
|
||||
cleanAuthData(localStorage);
|
||||
clearStorageAuthToken(localStorage);
|
||||
dispatch(checkLoginSuccess(null));
|
||||
client.resetWebsocket();
|
||||
return;
|
||||
@@ -23,12 +18,16 @@ export const checkLogin = () => (
|
||||
|
||||
dispatch(checkLoginSuccess(result.user));
|
||||
pym.sendMessage('coral-auth-changed', JSON.stringify(result.user));
|
||||
client.resetWebsocket();
|
||||
|
||||
// We don't need to reset the websocket here because if the request
|
||||
// returned that there was a user (which is the case here), then the
|
||||
// original request has already succeeded, or a previous call to a token
|
||||
// set handler has already reset it.
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.status && error.status === 401 && localStorage) {
|
||||
// Unauthorized.
|
||||
cleanAuthData(localStorage);
|
||||
clearStorageAuthToken(localStorage);
|
||||
client.resetWebsocket();
|
||||
} else {
|
||||
console.error(error);
|
||||
@@ -49,14 +48,20 @@ const checkLoginSuccess = user => ({
|
||||
user,
|
||||
});
|
||||
|
||||
export const setAuthToken = token => (dispatch, _, { localStorage }) => {
|
||||
localStorage.setItem('exp', jwtDecode(token).exp);
|
||||
localStorage.setItem('token', token);
|
||||
export const setAuthToken = token => (
|
||||
dispatch,
|
||||
_,
|
||||
{ localStorage, client }
|
||||
) => {
|
||||
setStorageAuthToken(localStorage, token);
|
||||
|
||||
// Dispatch the set auth token action. For some browsers and situations, we
|
||||
// may not be able to persist the auth token any other way. Keep it in redux!
|
||||
dispatch({ type: actions.SET_AUTH_TOKEN, token });
|
||||
|
||||
// Now that we set a token, let's reset the subscriptions.
|
||||
client.resetWebsocket();
|
||||
|
||||
dispatch(checkLogin());
|
||||
};
|
||||
|
||||
@@ -65,9 +70,7 @@ export const handleSuccessfulLogin = (user, token) => (
|
||||
_,
|
||||
{ client, localStorage, postMessage }
|
||||
) => {
|
||||
const { exp } = jwtDecode(token);
|
||||
localStorage.setItem('exp', exp);
|
||||
localStorage.setItem('token', token);
|
||||
setStorageAuthToken(localStorage, token);
|
||||
|
||||
// Send the message via the messages service to the window.opener if it
|
||||
// exists.
|
||||
@@ -79,6 +82,7 @@ export const handleSuccessfulLogin = (user, token) => (
|
||||
);
|
||||
}
|
||||
|
||||
// Now that we just set a token, set the token!
|
||||
client.resetWebsocket();
|
||||
|
||||
dispatch({
|
||||
@@ -105,7 +109,7 @@ export const logout = () => async (
|
||||
}
|
||||
|
||||
// Clear the auth data persisted to localStorage.
|
||||
cleanAuthData(localStorage);
|
||||
clearStorageAuthToken(localStorage);
|
||||
|
||||
// Reset the websocket.
|
||||
client.resetWebsocket();
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { timeago } from 'coral-framework/services/i18n';
|
||||
import cn from 'classnames';
|
||||
import styles from './CommentTimestamp.css';
|
||||
import TimeAgo from 'coral-framework/components/TimeAgo';
|
||||
|
||||
const CommentTimestamp = ({ className, created_at }) => (
|
||||
<div className={cn(className, styles.timestamp, 'talk-comment-timestamp')}>
|
||||
{timeago(created_at)}
|
||||
</div>
|
||||
<TimeAgo
|
||||
className={cn(className, styles.timestamp, 'talk-comment-timestamp')}
|
||||
datetime={created_at}
|
||||
/>
|
||||
);
|
||||
|
||||
CommentTimestamp.propTypes = {
|
||||
|
||||
@@ -1,50 +1,48 @@
|
||||
.card {
|
||||
margin-bottom: 20px;
|
||||
align-items: flex-start;
|
||||
min-height: 100px;
|
||||
max-width: 600px;
|
||||
min-height: 100px;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 20px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.collapsibleCard {
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
.enabledCard {
|
||||
border-left: 7px solid #00796b;
|
||||
}
|
||||
|
||||
.action {
|
||||
flex-shrink: 0;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-top: 3px;
|
||||
margin-bottom: 7px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
.body {
|
||||
margin-top: 7px;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.action {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: inline-block;
|
||||
padding: 0px 30px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.enabledSetting {
|
||||
border-left-color: #00796b;
|
||||
border-left-style: solid;
|
||||
border-left-width: 7px;
|
||||
}
|
||||
|
||||
.disabledSetting {
|
||||
padding-left: 22px;
|
||||
}
|
||||
|
||||
.disabledSettingText {
|
||||
.disabledBody {
|
||||
color: #ccc;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,46 +1,69 @@
|
||||
import React from 'react';
|
||||
import React, { PureComponent } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './ConfigureCard.css';
|
||||
import classnames from 'classnames/bind';
|
||||
import { Card } from 'coral-ui';
|
||||
import { Checkbox } from 'react-mdl';
|
||||
import cn from 'classnames';
|
||||
import { Checkbox, IconButton } from 'react-mdl';
|
||||
|
||||
const ConfigureCard = ({
|
||||
title,
|
||||
children,
|
||||
className,
|
||||
onCheckbox,
|
||||
checked,
|
||||
...rest
|
||||
}) => (
|
||||
<Card
|
||||
{...rest}
|
||||
className={cn(styles.card, className, {
|
||||
[styles.enabledSetting]: checked === true,
|
||||
[styles.disabledSetting]: checked === false,
|
||||
})}
|
||||
>
|
||||
{checked !== undefined && (
|
||||
<div className={styles.action}>
|
||||
<Checkbox onChange={onCheckbox} checked={checked} />
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className={cn(styles.wrapper, {
|
||||
[styles.content]: checked !== undefined,
|
||||
})}
|
||||
>
|
||||
<div className={styles.header}>{title}</div>
|
||||
<div
|
||||
className={cn({
|
||||
[styles.disabledSettingText]: checked === false,
|
||||
import styles from './ConfigureCard.css';
|
||||
|
||||
const cn = classnames.bind(styles);
|
||||
|
||||
class ConfigureCard extends PureComponent {
|
||||
state = {
|
||||
isOpen: !this.props.collapsible,
|
||||
};
|
||||
|
||||
toggle = () => this.setState({ isOpen: !this.state.isOpen });
|
||||
|
||||
render() {
|
||||
const {
|
||||
title,
|
||||
children,
|
||||
className,
|
||||
onCheckbox,
|
||||
checked,
|
||||
collapsible,
|
||||
...rest
|
||||
} = this.props;
|
||||
|
||||
const { isOpen } = this.state;
|
||||
|
||||
const iconName = isOpen ? 'keyboard_arrow_up' : 'keyboard_arrow_down';
|
||||
|
||||
return (
|
||||
<Card
|
||||
{...rest}
|
||||
className={cn(styles.card, className, {
|
||||
enabledCard: checked === true,
|
||||
collapsibleCard: collapsible,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
{checked !== undefined && (
|
||||
<div className={styles.action}>
|
||||
<Checkbox onChange={onCheckbox} checked={checked} />
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.wrapper}>
|
||||
<div className={styles.header}>
|
||||
<div className={styles.title}>{title}</div>
|
||||
{collapsible && (
|
||||
<IconButton onClick={this.toggle} name={iconName} ripple />
|
||||
)}
|
||||
</div>
|
||||
{isOpen && (
|
||||
<div
|
||||
className={cn(styles.body, {
|
||||
disabledBody: checked === false,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ConfigureCard.propTypes = {
|
||||
title: PropTypes.string,
|
||||
@@ -48,6 +71,7 @@ ConfigureCard.propTypes = {
|
||||
onCheckbox: PropTypes.func,
|
||||
checked: PropTypes.bool,
|
||||
children: PropTypes.node,
|
||||
collapsible: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default ConfigureCard;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
.timeago {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { timeago } from 'coral-framework/services/i18n';
|
||||
import cn from 'classnames';
|
||||
import styles from './TimeAgo.css';
|
||||
|
||||
class TimeAgo extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { timeago: true };
|
||||
}
|
||||
toggleDate = () => this.setState({ timeago: !this.state.timeago });
|
||||
render() {
|
||||
var displayTime = this.state.timeago
|
||||
? timeago(this.props.datetime)
|
||||
: new Date(this.props.datetime).toLocaleString();
|
||||
|
||||
var titleDate = !this.state.timeago
|
||||
? timeago(this.props.datetime)
|
||||
: new Date(this.props.datetime).toLocaleString();
|
||||
return (
|
||||
<span
|
||||
onClick={this.toggleDate}
|
||||
className={cn(
|
||||
this.props.className,
|
||||
styles.timeago,
|
||||
'talk-comment-timeago'
|
||||
)}
|
||||
title={titleDate}
|
||||
>
|
||||
{displayTime}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TimeAgo.propTypes = {
|
||||
datetime: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
export default TimeAgo;
|
||||
@@ -1,7 +1,7 @@
|
||||
import url from 'url';
|
||||
import parse from 'url-parse';
|
||||
|
||||
const base = document.querySelector('base');
|
||||
const baseUrl = (base && url.parse(base.href)) || {};
|
||||
const baseUrl = (base && parse(base.href)) || {};
|
||||
|
||||
export const BASE_URL = base.href;
|
||||
export const BASE_PATH = baseUrl.pathname;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import jwtDecode from 'jwt-decode';
|
||||
|
||||
export const setStorageAuthToken = (storage, token) => {
|
||||
storage.setItem('exp', jwtDecode(token).exp);
|
||||
storage.setItem('token', token);
|
||||
};
|
||||
|
||||
export const clearStorageAuthToken = storage => {
|
||||
storage.removeItem('token');
|
||||
storage.removeItem('exp');
|
||||
};
|
||||
+26
-2
@@ -22,6 +22,7 @@ import {
|
||||
} from 'coral-framework/services/storage';
|
||||
import { createHistory } from 'coral-framework/services/history';
|
||||
import { createIntrospection } from 'coral-framework/services/introspection';
|
||||
import { setStorageAuthToken } from 'coral-framework/services/auth';
|
||||
import introspectionData from 'coral-framework/graphql/introspection.json';
|
||||
import coreReducers from '../reducers';
|
||||
import { checkLogin as checkLoginAction } from '../actions/auth';
|
||||
@@ -46,7 +47,30 @@ const getAuthToken = (store, storage) => {
|
||||
// capable of storing the token in localStorage, then we would have
|
||||
// persisted it to the redux state.
|
||||
return state.config.auth_token || state.auth.token;
|
||||
} else if (!bowser.safari && !bowser.ios && storage) {
|
||||
} else if (location.hash && location.hash.startsWith('#access_token=')) {
|
||||
// Check to see if the access token is living in the URL as a hash.
|
||||
const token = location.hash.substring(14);
|
||||
|
||||
history.replaceState(
|
||||
{},
|
||||
document.title,
|
||||
window.location.pathname + window.location.search
|
||||
);
|
||||
|
||||
// Once we clear the hash above, this login method will not persist across
|
||||
// refreshes. We will need to persist the token to storage if it's
|
||||
// available.
|
||||
if (storage) {
|
||||
setStorageAuthToken(storage, token);
|
||||
}
|
||||
|
||||
return token;
|
||||
} else if (
|
||||
!bowser.safari &&
|
||||
!bowser.ios &&
|
||||
storage &&
|
||||
storage.getItem('token')
|
||||
) {
|
||||
// Use local storage auth tokens where there's a stable api.
|
||||
return storage.getItem('token');
|
||||
}
|
||||
@@ -136,7 +160,7 @@ export async function createContext({
|
||||
});
|
||||
|
||||
const staticConfig = getStaticConfiguration();
|
||||
let { LIVE_URI: liveUri, STATIC_ORIGIN: origin } = staticConfig;
|
||||
let { LIVE_URI: liveUri, BASE_ORIGIN: origin } = staticConfig;
|
||||
if (liveUri == null) {
|
||||
// The protocol must match the origin protocol, secure/insecure.
|
||||
const protocol = location.protocol === 'https:' ? 'wss' : 'ws';
|
||||
|
||||
@@ -88,21 +88,23 @@ export function createClient(options = {}) {
|
||||
});
|
||||
|
||||
client.resetWebsocket = () => {
|
||||
// Close socket connection which will also unregister subscriptions on the server-side.
|
||||
wsClient.close();
|
||||
if (wsClient.client) {
|
||||
// Close socket connection which will also unregister subscriptions on the server-side.
|
||||
wsClient.close(true);
|
||||
|
||||
// Reconnect to the server.
|
||||
wsClient.connect();
|
||||
// Reconnect to the server.
|
||||
wsClient.connect();
|
||||
|
||||
// Reregister all subscriptions (uses non public api).
|
||||
// See: https://github.com/apollographql/subscriptions-transport-ws/issues/171
|
||||
Object.keys(wsClient.operations).forEach(id => {
|
||||
wsClient.sendMessage(
|
||||
id,
|
||||
MessageTypes.GQL_START,
|
||||
wsClient.operations[id].options
|
||||
);
|
||||
});
|
||||
// Re-register all subscriptions (uses non public api).
|
||||
// See: https://github.com/apollographql/subscriptions-transport-ws/issues/171
|
||||
Object.keys(wsClient.operations).forEach(id => {
|
||||
wsClient.sendMessage(
|
||||
id,
|
||||
MessageTypes.GQL_START,
|
||||
wsClient.operations[id].options
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return client;
|
||||
|
||||
@@ -12,6 +12,7 @@ import 'moment/locale/da';
|
||||
import 'moment/locale/de';
|
||||
import 'moment/locale/es';
|
||||
import 'moment/locale/fr';
|
||||
import 'moment/locale/it';
|
||||
import 'moment/locale/nl';
|
||||
import 'moment/locale/pt-br';
|
||||
|
||||
@@ -22,6 +23,7 @@ import daTA from 'timeago.js/locales/da';
|
||||
import deTA from 'timeago.js/locales/de';
|
||||
import esTA from 'timeago.js/locales/es';
|
||||
import frTA from 'timeago.js/locales/fr';
|
||||
import itTA from 'timeago.js/locales/it';
|
||||
import nlTA from 'timeago.js/locales/nl';
|
||||
import pt_BRTA from 'timeago.js/locales/pt_BR';
|
||||
import zh_CNTA from 'timeago.js/locales/zh_CN';
|
||||
@@ -34,6 +36,7 @@ import da from '../../../locales/da.yml';
|
||||
import de from '../../../locales/de.yml';
|
||||
import es from '../../../locales/es.yml';
|
||||
import fr from '../../../locales/fr.yml';
|
||||
import it from '../../../locales/it.yml';
|
||||
import nl_NL from '../../../locales/nl_NL.yml';
|
||||
import pt_BR from '../../../locales/pt_BR.yml';
|
||||
import zh_CN from '../../../locales/zh_CN.yml';
|
||||
@@ -61,6 +64,7 @@ export const translations = {
|
||||
...de,
|
||||
...es,
|
||||
...fr,
|
||||
...it,
|
||||
...nl_NL,
|
||||
...pt_BR,
|
||||
...zh_CN,
|
||||
@@ -106,10 +110,11 @@ export function setupTranslations() {
|
||||
ta.register('da', daTA);
|
||||
ta.register('de', deTA);
|
||||
ta.register('fr', frTA);
|
||||
ta.register('nl-NL', nlTA);
|
||||
ta.register('pt-BR', pt_BRTA);
|
||||
ta.register('zh-CN', zh_CNTA);
|
||||
ta.register('zh-TW', zh_TWTA);
|
||||
ta.register('it', itTA);
|
||||
ta.register('nl_NL', nlTA);
|
||||
ta.register('pt_BR', pt_BRTA);
|
||||
ta.register('zh_CN', zh_CNTA);
|
||||
ta.register('zh_TW', zh_TWTA);
|
||||
TIMEAGO_INSTANCE = ta();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { capitalize } from 'coral-framework/helpers/strings';
|
||||
import assignWith from 'lodash/assignWith';
|
||||
import mapValues from 'lodash/mapValues';
|
||||
export * from 'coral-framework/helpers/strings';
|
||||
export * from './url';
|
||||
|
||||
export const getTotalActionCount = (type, comment) => {
|
||||
return comment.action_summaries
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import parse from 'url-parse';
|
||||
|
||||
export function buildUrl(
|
||||
{ protocol, hostname, port, pathname, search, hash } = window.location
|
||||
) {
|
||||
@@ -10,3 +12,10 @@ export function buildUrl(
|
||||
port ? `:${port}` : ''
|
||||
}${pathname}${search}${hash}`;
|
||||
}
|
||||
|
||||
export function buildCommentURL(assetURL, commentID) {
|
||||
const u = parse(assetURL, true);
|
||||
u.query.commentId = commentID;
|
||||
u.set('query', u.query);
|
||||
return u.href;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ const CONFIG = {
|
||||
ENABLE_TRACING: Boolean(process.env.APOLLO_ENGINE_KEY),
|
||||
|
||||
// EMAIL_SUBJECT_PREFIX is the string before emails in the subject.
|
||||
EMAIL_SUBJECT_PREFIX: process.env.TALK_EMAIL_SUBJECT_PREFIX || '[Talk]',
|
||||
EMAIL_SUBJECT_PREFIX: process.env.TALK_EMAIL_SUBJECT_PREFIX,
|
||||
|
||||
// DEFAULT_LANG is the default language used for server sent emails and
|
||||
// rendered text.
|
||||
@@ -271,6 +271,10 @@ const CONFIG = {
|
||||
// CONFIG VALIDATION
|
||||
//==============================================================================
|
||||
|
||||
if (typeof CONFIG.EMAIL_SUBJECT_PREFIX === 'undefined') {
|
||||
CONFIG.EMAIL_SUBJECT_PREFIX = '[Talk]';
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'test') {
|
||||
if (!CONFIG.ROOT_URL) {
|
||||
CONFIG.ROOT_URL = `http://${localAddress}:3001`;
|
||||
|
||||
@@ -98,12 +98,16 @@ sidebar:
|
||||
url: /configuration/
|
||||
- title: Advanced Configuration
|
||||
url: /advanced-configuration/
|
||||
- title: Configuration with CLI tools
|
||||
url: /configuration-cli-tools/
|
||||
- title: Integrating
|
||||
children:
|
||||
- title: Authentication
|
||||
url: /integrating/authentication/
|
||||
- title: Asset Management
|
||||
url: /integrating/asset-management/
|
||||
- title: Asset Scraping
|
||||
url: /integrating/asset-scraping/
|
||||
- title: Configuring the Comment Stream
|
||||
url: /integrating/configuring-comment-stream/
|
||||
- title: Configuring the Admin
|
||||
|
||||
@@ -22,13 +22,10 @@ to persist data. The following versions are supported:
|
||||
- MongoDB 3.2+
|
||||
- Redis 3.2.5+
|
||||
|
||||
An optional dependency for Talk is
|
||||
[Docker](https://www.docker.com/community-edition#/download).
|
||||
It is used during development to set up the database and can be
|
||||
used to [install via Docker](#installation-from-docker). We have tested Talk
|
||||
and this documentation with versions 17.06.2+.
|
||||
You can run Talk (and its dependencies) locally or from [Docker](https://www.docker.com/community-edition#/download) containers. Docker is used in the local example below for the database and cache, however it is possible to run Talk without Docker by configuring your own MongoDB and Redis instances. We have tested Talk
|
||||
and this documentation with Docker versions 17.06.2+.
|
||||
|
||||
Another optional dependency for Talk is
|
||||
An optional dependency for Talk is
|
||||
[Docker Compose](https://docs.docker.com/compose/install/). It
|
||||
can be used to setup your environment easily for testing. We have tested Talk
|
||||
and this documentation with versions 1.14.0+.
|
||||
@@ -38,8 +35,9 @@ and this documentation with versions 1.14.0+.
|
||||
### Installation from Docker
|
||||
|
||||
To use Talk without major customization you can run the application using our
|
||||
provided docker image. The following is a `docker-compose.yml` file that can
|
||||
be used to setup Talk:
|
||||
provided docker image.
|
||||
|
||||
Start by making a new directory and create a file called `docker-compose.yml` and copy the following:
|
||||
|
||||
```yml
|
||||
# For details on the syntax of docker-compose.yml files, check out:
|
||||
@@ -79,7 +77,7 @@ volumes:
|
||||
external: false
|
||||
```
|
||||
|
||||
This is the bare minimum needed to run the demo, for more configuration
|
||||
The environment variables listed above are the bare minimum needed to run the demo, for more configuration
|
||||
variables, check out the [Configuration](/talk/configuration/) section.
|
||||
|
||||
|
||||
@@ -104,8 +102,7 @@ Creating talk_1 ...
|
||||
Creating talk_1 ... done
|
||||
```
|
||||
|
||||
|
||||
And when you run `docker-compose ps`, you should see something like:
|
||||
Once everything has completed, run `docker-compose ps`, and you should see something like:
|
||||
|
||||
```
|
||||
Name Command State Ports
|
||||
@@ -116,8 +113,8 @@ talk_1 yarn start Up 0.0.0.0:3000->3000/tcp
|
||||
```
|
||||
|
||||
|
||||
Continue onto the [Running](#running) section for details on how to complete the
|
||||
installation and get started using Talk.
|
||||
You now have a Talk instance up and running! Continue on to the [Setup](#setup) section for details on how to complete the
|
||||
initial setup and get started using Talk.
|
||||
|
||||
### Installation from Source
|
||||
|
||||
@@ -178,32 +175,35 @@ You can now start the application by running:
|
||||
yarn watch:server
|
||||
```
|
||||
|
||||
Continue onto the [Running](#running) section for details on how to complete the
|
||||
Continue onto the [Setup](#setup) section for details on how to complete the
|
||||
installation and get started using Talk.
|
||||
|
||||
## Running
|
||||
## Setup
|
||||
### Create Admin Account
|
||||
|
||||
You can now navigate to
|
||||
With Talk running, you can now navigate to
|
||||
[http://127.0.0.1:3000/admin/install](http://127.0.0.1:3000/admin/install)
|
||||
and go through the admin installation. There you will be prompted to create your
|
||||
first admin account, and specify the domain whitelist for domains that are
|
||||
allowed to have the comment box on.
|
||||
and walk through the initial setup steps.
|
||||
|
||||
* First, enter your **Organization Name** and **Organization Contact Email**. This will appear in emails when inviting new team members.
|
||||
* Next, create your Admin user. You can specify an **Email Address**, **Username**, and **Password**
|
||||
* Finally, enter your list of **Permitted Domains**, read [here](/talk/configuring-talk/#permitted-domains) about whitelisting domains
|
||||
|
||||
_During development, ensure you whitelist 127.0.0.1:3000 otherwise the
|
||||
[http://127.0.0.1:3000/](http://127.0.0.1:3000/) page will not
|
||||
load._
|
||||
|
||||
Once you've completed the installation, you can visit
|
||||
[http://127.0.0.1:3000/](http://127.0.0.1:3000/) where you can
|
||||
view our development area where we test out features in Talk where you can write
|
||||
comments and see them in the admin interface where you can do moderation and
|
||||
reconfigure the user experience.
|
||||
Once the setup wizard has been completed you can log into Talk ([http://127.0.0.1:3000/](http://127.0.0.1:3000/)) using the email address and password for the Admin user account that you just created.
|
||||
|
||||
## Demo
|
||||
From here you can test out features in Talk, see comments in the admin interface where you can do moderation, and configure the user experience.
|
||||
In the next step you'll create some user comments to moderate.
|
||||
|
||||
|
||||
### Demo Embedded Comments
|
||||
|
||||
If you've followed the documentation above, you'll now have a running copy of
|
||||
Talk. To demonstrate what your own self-hosted copy of Talk can do, below
|
||||
you'll find a demo that can be used to test the copy that is running now on your
|
||||
Talk. To demonstrate what your own self-hosted copy of Talk can do, we created the demo below
|
||||
that can be used to test the copy that is running now on your
|
||||
machine.
|
||||
|
||||
In order for the demo to work, you must add
|
||||
|
||||
@@ -246,6 +246,21 @@ Refer to the documentation for [TALK_JWT_ALG](#talk-jwt-alg) for other signing
|
||||
methods and other forms of the `TALK_JWT_SECRET`. If you are interested in using
|
||||
multiple keys, then refer to [TALK_JWT_SECRETS](#talk-jwt-secrets).
|
||||
|
||||
You can also encode your secret as a base64 string (if you are using a symmetric
|
||||
algorithm) as long as you prefix it with `base64:`. For example:
|
||||
|
||||
```plain
|
||||
TALK_JWT_SECRET={"secret": "base64:dGVzdA=="}
|
||||
```
|
||||
|
||||
Would be the same as:
|
||||
|
||||
```plain
|
||||
TALK_JWT_SECRET={"secret": "test"}
|
||||
```
|
||||
|
||||
As `dGVzdA==` is just `test` encoded using base64.
|
||||
|
||||
## TALK_JWT_SECRETS
|
||||
|
||||
Used when specifying multiple secrets used for key rotations. This is a JSON
|
||||
@@ -271,7 +286,6 @@ Note that the secret is stored in a JSON object, keyed by `secret`. This is only
|
||||
needed when specifying in the multiple secrets for `TALK_JWT_SECRETS`, but may
|
||||
be used to specify the single [TALK_JWT_SECRET](#talk-jwt-secret).
|
||||
|
||||
|
||||
When the value of [TALK_JWT_ALG](#talk-jwt-alg) is **not** a `HS*` value, then
|
||||
the value of the `TALK_JWT_SECRETS` should take the form:
|
||||
|
||||
@@ -282,7 +296,6 @@ TALK_JWT_SECRETS=[{"kid": "1", "private": "<my private key>", "public": "<my pub
|
||||
Refer to the documentation on the [TALK_JWT_ALG](#talk-jwt-alg) for more
|
||||
information on what to store in these parameters.
|
||||
|
||||
|
||||
## TALK_JWT_SIGNING_COOKIE_NAME
|
||||
|
||||
The default cookie name that is use to set a cookie containing a JWT that was
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
---
|
||||
title: Configuration with CLI tools
|
||||
permalink: /configuration-cli-tools/
|
||||
class: configuration
|
||||
toc: true
|
||||
---
|
||||
|
||||
Talk can be configured using CLI tools. The CLI tools are available through `./bin/cli`. Below is a list of commands available:
|
||||
```
|
||||
Usage: cli [options] [command]
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help output usage information
|
||||
|
||||
Commands:
|
||||
|
||||
serve serve the application
|
||||
db run database commands
|
||||
settings interact with the application settings
|
||||
assets interact with assets
|
||||
setup setup the application
|
||||
jobs work with the job queues
|
||||
token work with the access tokens
|
||||
users work with the application auth
|
||||
migration provides utilities for migrating the database
|
||||
plugins provides utilities for interacting with the plugin system
|
||||
help [cmd] display help for [cmd]
|
||||
```
|
||||
|
||||
## Serving the application
|
||||
To serve the application, run `./bin/cli serve`. Please check that you have installed the Talk before doing this step. Below is a list of additional options available for this command:
|
||||
```
|
||||
Usage: cli-serve [options]
|
||||
|
||||
Options:
|
||||
|
||||
-j, --jobs enable job processing on this thread
|
||||
--disabled-jobs <jobs> disable jobs specified if the -j option is passed, specified as a comma separated list (default: )
|
||||
-w, --websockets enable the websocket (subscriptions) handler on this thread
|
||||
-h, --help output usage information
|
||||
```
|
||||
|
||||
## Database commands
|
||||
You can also run database commands using `./bin/cli db`. Below is a list of additional options available for this command:
|
||||
```
|
||||
Usage: cli-db [options] [command]
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help output usage information
|
||||
|
||||
Commands:
|
||||
|
||||
createIndexes creates the database indexes and waits until they are created
|
||||
```
|
||||
|
||||
## Application settings
|
||||
You can also change application settings using `./bin/cli settings`. Below is a list of additional options available for this command:
|
||||
```
|
||||
Usage: cli-settings [options] [command]
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help output usage information
|
||||
|
||||
Commands:
|
||||
|
||||
change-org-name change the organization name
|
||||
```
|
||||
|
||||
## Interaction with assets
|
||||
You can also interact with your application's assets using `./bin/cli assets`. Below is a list of additional options available for this command:
|
||||
```
|
||||
Usage: cli-assets [options] [command]
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help output usage information
|
||||
|
||||
Commands:
|
||||
|
||||
list [options] list all the assets in the database
|
||||
refresh [age] queues the assets that exceed the age requested
|
||||
update-url <assetID> <url> update the URL of an asset
|
||||
merge <srcID> <dstID> merges two assets together by moving comments from src to dst and deleting the src asset
|
||||
rewrite [options] <search> <replace> rewrites asset url's using the provided regex replacement pattern
|
||||
```
|
||||
|
||||
## Setting up the application
|
||||
You can also run a setup wizard to setup the wizard using `./bin/cli setup`. Below is a list of additional options available for this command:
|
||||
```
|
||||
Usage: cli-setup [options]
|
||||
|
||||
runs the setup wizard to setup the application
|
||||
|
||||
Options:
|
||||
|
||||
--defaults apply defaults for config instead of prompting
|
||||
-h, --help output usage information
|
||||
```
|
||||
|
||||
## Working with job queues
|
||||
You can also work with job queues using `./bin/cli jobs`. Below is a list of additional options available for this command:
|
||||
```
|
||||
Usage: cli-jobs [options] [command]
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help output usage information
|
||||
|
||||
Commands:
|
||||
|
||||
process starts job processing
|
||||
cleanup [options] cleans up inactive jobs
|
||||
```
|
||||
|
||||
## Working with access tokens
|
||||
You can also work with access tokens using `./bin/cli token`. Below is a list of additional options available for this command:
|
||||
```
|
||||
Usage: cli-token [options] [command]
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help output usage information
|
||||
|
||||
Commands:
|
||||
|
||||
list <userID> list tokens for a user
|
||||
revoke <tokenID> revokes a token with a given id
|
||||
create <userID> <tokenName> create a token for a user with a given name
|
||||
```
|
||||
|
||||
## Working with your application's authentication
|
||||
You can also work with your application's authentication using `./bin/cli users`. Below is a list of additional options available for this command:
|
||||
```
|
||||
Usage: cli-users [options] [command]
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help output usage information
|
||||
|
||||
Commands:
|
||||
|
||||
create creates a local user
|
||||
delete <userID> delete a user
|
||||
list searches for a user based on their stored username and email
|
||||
set-role <userID> sets the role on a user
|
||||
verify <userID> <email> verifies the given user's email address
|
||||
```
|
||||
|
||||
## Migrating your database
|
||||
Talk provides utilities for migrating your database using `./bin/cli migration`. Below is a list of additional options available for this command:
|
||||
```
|
||||
Usage: cli-migration [options] [command]
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help output usage information
|
||||
|
||||
Commands:
|
||||
|
||||
create <name> creates a new migration
|
||||
run [options] runs all pending migrations
|
||||
```
|
||||
|
||||
## Interacting with the plugin system
|
||||
Talk provides utilities to interact with the plugin system using `./bin/cli plugins`. Below is a list of additional options available for this command:
|
||||
```
|
||||
Usage: cli-plugins [options] [command]
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help output usage information
|
||||
|
||||
Commands:
|
||||
|
||||
create creates a seed plugin
|
||||
list
|
||||
reconcile [options] reconciles dependencies by downloading external plugins
|
||||
```
|
||||
@@ -5,7 +5,7 @@ permalink: /moderator-features/
|
||||
|
||||
## The Talk Admin
|
||||
|
||||
The Admin is your moderators will moderate your comments, and your Admins will
|
||||
The Admin is where your moderators will moderate your comments, and your Admins will
|
||||
configure and manage the different parts of Talk.
|
||||
|
||||
### Moderate
|
||||
@@ -18,57 +18,99 @@ site-wide.
|
||||
|
||||
**New**
|
||||
|
||||
The New queue contains all comments that have not been moderated yet.
|
||||
>_Conditions:_ Pre-Mod disabled
|
||||
|
||||
**Reported**
|
||||
Comments have been published? _**Yes**_
|
||||
|
||||
The Reported queue contains all comments that need moderator attention.
|
||||
The New queue contains all comments that have not been moderated yet. This queue contains comments that haven’t yet been Accepted or Rejected by a moderator
|
||||
|
||||
**Approved**
|
||||
**Pre-mod**
|
||||
|
||||
The Approved queue contains all approved comments.
|
||||
>_Conditions:_ Pre-Mod enabled
|
||||
|
||||
Comments have been published? _**No**_
|
||||
|
||||
This queue contains comments that haven’t yet been Accepted or Rejected by a moderator
|
||||
|
||||
**Accepted**
|
||||
|
||||
Comments have been published? _**Yes**_
|
||||
|
||||
Comments that have been approved by a moderator, written by a Staff member (and so auto approved), or Featured (and so auto approved). Tags for reports still appear on comments in this queue, but the comments will not go back into Reported.
|
||||
|
||||
**Rejected**
|
||||
|
||||
The Rejected queue contains all comments that have been rejected, either
|
||||
manually by moderators or automatically, e.g. they have used a banned word.
|
||||
Comments have been published? _**No**_
|
||||
|
||||
Comments that have been rejected by a moderator, or rejected because they contained a banned word/phrase. Tags for reports still appear on comments in this queue, but the comments will not go back into Reported.
|
||||
|
||||
|
||||
**Reported**
|
||||
|
||||
>_Conditions:_ Pre-Mod disabled
|
||||
|
||||
Comments have been published? _**depends**_
|
||||
|
||||
This queue contains comments that have been reported for moderator review, either by users or automatically by Talk, and have not yet been Approved or Rejected. If there are comments to review in this queue, a red dot will be displayed in the top menu.
|
||||
|
||||
**All**
|
||||
|
||||
The All queue contains all comments that have been submitted either article or
|
||||
site-wide.
|
||||
|
||||
#### Moderation Badges
|
||||
#### Moderation Tags that appear in Reported/other queues
|
||||
|
||||
**Pre-mod**
|
||||
|
||||
The Pre-mod badge signifies comments that are being pre-modded.
|
||||
_Comment published? No_
|
||||
|
||||
The Pre-mod tag signifies comments that are being pre-modded.
|
||||
|
||||
**User**
|
||||
|
||||
The User badge signifies comments that have been reported by another user.
|
||||
_Comment published? Yes_
|
||||
|
||||
**History**
|
||||
Comment has been reported by a user. The ‘More Details’ box contains the name/s of the users who reported the comment, and any additional information they provided.
|
||||
|
||||
**Staff**
|
||||
|
||||
_Comment published? Yes_
|
||||
|
||||
Comment has been reported by a staff member. The ‘More Details’ box contains the name/s of the staff member who reported the comment, and any additional information they provided.
|
||||
|
||||
**Suspect Word**
|
||||
|
||||
_Comment published? Yes_
|
||||
|
||||
Comment contains a word or phrase that is on the ’Suspect words’ list in the Configure > Moderation tab (administrators only). The word/phrase will be highlighted in yellow.
|
||||
|
||||
**Karma**
|
||||
|
||||
_Comment published? No_
|
||||
|
||||
The History tag signifies comments that have been flagged because the user’s history indicates their Accepted:Rejected ratio has reached below the karma threshold. [Read more about karma here.](/talk/trust/#user-karma-score)
|
||||
|
||||
**Spam**
|
||||
|
||||
_Comment published? No_
|
||||
|
||||
If you are using the Akismet anti-spam plugin, this tag means that Akismet has flagged the comment as spam. You must Approve it for it to appear in the stream. **Requires:** [talk-plugin-akismet](/talk/plugin/talk-plugin-akismet/)
|
||||
|
||||
The History badge signifies comments that have been flagged because of a user’s
|
||||
history.
|
||||
|
||||
**Toxic**
|
||||
|
||||
The Toxic badge signifies comments that are above the set Toxicity Probability
|
||||
Threshold. Note you must have [talk-plugin-toxic-comments](/talk/additional-plugins/#talk-plugin-toxic-comments) enabled.
|
||||
[Read more about Toxic Comments here](/talk/toxic-comments/).
|
||||
_Comment published? No_
|
||||
|
||||
**Suspect**
|
||||
If you are using the Toxic Comments plugin, this tag means that Perspective API has flagged the comment as likely to be toxic, above the threshold you have set (default: 80%). You must Approve it for it to appear in the stream. **Requires:** [talk-plugin-toxic-comments](/talk/additional-plugins/#talk-plugin-toxic-comments).
|
||||
Read more about [Toxic Comments here](/talk/toxic-comments/).
|
||||
|
||||
The Suspect badge signifies comments that contain a Suspect Word.
|
||||
|
||||
**Contains Link**
|
||||
|
||||
The Contains Link badge signifies a comment that contains a link, which can
|
||||
The Contains Link tag signifies a comment that contains a link, which can
|
||||
sometimes mean it is a spam or ad comment.
|
||||
|
||||
**Flag Details View**
|
||||
**More Details View**
|
||||
|
||||
At the bottom of each comment in the moderation queues, you can see more
|
||||
information about a comment’s flags by clicking on More Detail.
|
||||
@@ -88,9 +130,35 @@ Rejecting a comment removes the comment from the stream.
|
||||
Featuring a comment adds that comment to the Featured Comments tab on the
|
||||
stream.
|
||||
|
||||
#### Keyboard Shortcuts
|
||||
|
||||
Talk also supports a number of keyboard shortcuts that moderators can leverage
|
||||
to moderate queues quickly:
|
||||
|
||||
| Shortcut | Action |
|
||||
| -------- | -------------------------- |
|
||||
| `j` | Go to the next comment |
|
||||
| `k` | Go to the previous comment |
|
||||
| `ctrl+f` | Open search |
|
||||
| `1-5` | Switch queues |
|
||||
| `z` | Zen mode |
|
||||
| `?` | Open shortcuts menu |
|
||||
| `d` | Approve |
|
||||
| `f` | Reject |
|
||||
|
||||
Note: "Zen mode" allows a moderator to view and action only one comment at a time. Enjoy the silence!
|
||||
|
||||
#### The User Drawer
|
||||
|
||||
In order to get an idea of what sort of a commenter someone is, moderators can
|
||||
click on the commenter's username in any moderation queue/elsewhere in the admin (eg the Community page) to see details about
|
||||
their comments, and to take actions.
|
||||
|
||||
#### User Drawer Actions
|
||||
|
||||
**Suspend User**
|
||||
|
||||
Suspending a user allows a moderator to give a commenter a “time-out”; during
|
||||
Suspending a user allows a moderator to give a commenter a “time-out” for a set time chosen from four options; during
|
||||
that time they won’t be allowed to post comments or react to comments.
|
||||
|
||||
**Ban User**
|
||||
@@ -99,15 +167,13 @@ Banning a user allows a moderator to permanently disallow a commenter to
|
||||
interact with their community. The commenters previous comments will remain on
|
||||
the site. This action can only be un-done manually by a moderator.
|
||||
|
||||
#### Viewing a User’s Comment History
|
||||
**Reject Username**
|
||||
|
||||
In order to get an idea of what sort of a commenter someone is, moderators can
|
||||
click on the commenters username in any moderation queue and see details about
|
||||
their history.
|
||||
If a username is violating your guidelines but isn't bad enough to lead to a ban (eg. they are impersonating a famous person), you can reject their username. This will prevent them from publishing comments until they submit a new username. The new name will appear on the Community page for moderator approval before they can publish comments again.
|
||||
|
||||
**Username, Email and Member Since Date**
|
||||
|
||||
This shows the basic details about a commenter.
|
||||
This shows the basic details about a commenter's account
|
||||
|
||||
**Total Comments**
|
||||
|
||||
@@ -119,32 +185,17 @@ display on the site.
|
||||
This shows the % of comments a commenter has had rejected by moderators, or
|
||||
automatically.
|
||||
|
||||
**Reports**
|
||||
**Karma score**
|
||||
|
||||
This shows if a commenter is a reliable flagger, an unreliable flagger, or a
|
||||
neutral flagger. [Read more about reliable and unreliable flaggers here](/talk/trust/#reliable-and-unreliable-flaggers).
|
||||
The user's current score. To see the default threshhold, click on the 'i' next to the word Karma. If the user's score is equal to or below the default threshhold, the number will be highlighted red. [Read more about karma scores here.](/talk/trust/#user-karma-score)
|
||||
|
||||
**User History**
|
||||
|
||||
This shows the history of the account - if a user has changed their username, or been suspended or banned. The name of the moderator who suspended/banned them/lifted the suspection or ban is displayed here as well.
|
||||
|
||||
**Moderating from this View**
|
||||
|
||||
Talk also allows you to moderate a commenters recent comments from this view.
|
||||
|
||||
#### Keyboard Shortcuts
|
||||
|
||||
Talk also supports a number of keyboard shortcuts that moderators can leverage
|
||||
to moderate quickly:
|
||||
|
||||
| Shortcut | Action |
|
||||
| -------- | -------------------------- |
|
||||
| `j` | Go to the next comment |
|
||||
| `k` | Go to the previous comment |
|
||||
| `ctrl+f` | Open search |
|
||||
| `t` | Switch queues |
|
||||
| `z` | Zen mode |
|
||||
| `?` | Open this menu |
|
||||
| `d` | Approve |
|
||||
| `f` | Reject |
|
||||
|
||||
Note: "Zen mode" allows a moderator to view and action only one comment at a time. Enjoy the silence!
|
||||
Talk also allows you to moderate a commenters recent comments from this view. You can 'Select all' to select up to ten previous comments, and take bulk accept/reject actions.
|
||||
|
||||
### Stories
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ Trust is a set of components within Talk that incorporate basic automated modera
|
||||
|
||||
## User Karma Score
|
||||
|
||||
Using Trust’s calculations, Talk will automatically hold back, move to the Reported queue, and tag with a 'History' marker, any comments by users who have an Unreliable karma score. (This is for sites who practice post-moderation. If you set pre-moderation of all comments sitewide, this feature has limited use.)
|
||||
Using Trust’s calculations, Talk will automatically hold back, move to the Reported queue, and tag with a 'Karma' marker, any comments by users who have an Unreliable karma score. (This is for sites who practice post-moderation. If you set pre-moderation of all comments sitewide, this feature has limited use.)
|
||||
|
||||
All users start out with a Neutral karma score (`0`). If they have a comment approved by a moderator, their score increases by `1`; if they have a comment rejected by a moderator, it decreases by `1`. When a commenter's score is labeled as Unreliable, their comments must be approved from the Reported queue before they are posted. Commenters are shown a message stating that a moderator will review their comment shortly.
|
||||
|
||||
@@ -27,29 +27,3 @@ We strongly recommend not telling your community how this system works, or where
|
||||
|
||||
If you see that a high proportion of first-time commenters on your site are abusive, you might want to change the threshhold to `0`, at least temporarily. You can configure your own Trust thresholds by using [TRUST_THRESHOLDS](/talk/advanced-configuration/#trust-thresholds) in your site configuration.
|
||||
|
||||
|
||||
## Reliable and Unreliable Flaggers
|
||||
|
||||
Trust also calculates how reliable users are in terms of the comments they
|
||||
report. This information is displayed to moderators in the User History drawer,
|
||||
which is accessed by clicking on a user’s name in the Admin. Currently, no other action is taken based on this score.
|
||||
|
||||
If a user's reports mostly match what moderators reject, their Report status
|
||||
will display to moderators as Reliable in the user information drawer. If a
|
||||
user's reports mostly differ from what moderators reject, their Report status
|
||||
will show as Unreliable.
|
||||
|
||||
If Talk doesn't have enough reports to make a call, or the reports even out, their
|
||||
status is Neutral.
|
||||
|
||||
Here are the default thresholds:
|
||||
|
||||
```text
|
||||
-1 and lower: Unreliable
|
||||
0 to +1: Neutral
|
||||
+2 and higher: Reliable
|
||||
```
|
||||
You can configure your own Trust thresholds by using [TRUST_THRESHOLDS](/talk/advanced-configuration/#trust-thresholds) in your
|
||||
configuration.
|
||||
|
||||
Note: Report Karma doesn't include reports of "I don't agree with this comment".
|
||||
|
||||
@@ -15,7 +15,7 @@ Even if GDPR will not apply to you, it is recommended to enable these
|
||||
features as a best practice to provide your users with control over their own
|
||||
data.
|
||||
|
||||
## GPDR Feature Overview
|
||||
## GDPR Feature Overview
|
||||
|
||||
Integrating our GDPR tools will give your users and organizations the following benefits:
|
||||
|
||||
|
||||
@@ -144,9 +144,9 @@ Some queries you may notice seem to return `null` or an error of
|
||||
route that requires authorization. You can perform authorization a few ways in
|
||||
Talk:
|
||||
|
||||
1. As a [Bearer Token](#Bearer-Token)
|
||||
2. As a [Query Parameter](#Query-Parameter)
|
||||
3. As a [Cookie](#Cookie)
|
||||
1. As a [Bearer Token](#bearer-token)
|
||||
2. As a [Query Parameter](#query-parameter)
|
||||
3. As a [Cookie](#cookie)
|
||||
|
||||
Essentially, you need to get access to a JWT token that you can use to authorize
|
||||
your requests. Generating one is simple, you can use the CLI tools in Talk to do
|
||||
|
||||
@@ -18,11 +18,11 @@ By default, Talk will use "Lazy Asset Creation" to dynamically generate Assets
|
||||
in Talk in order to make it easier for lighter installations. In order to have
|
||||
more strict control over this flow, we will create a plugin that will:
|
||||
|
||||
1. Disable "Lazy Asset Creation" by [Overriding a Resolver](#Overriding-a-Resolver).
|
||||
2. Create Assets from our CMS by [Creating a New Asset Route](#Creating-a-New-Asset-Route).
|
||||
3. Facilitate updates from our CMS to keep Talk in sync by [Creating an Asset Update Route](#Creating-an-Asset-Update-Route).
|
||||
1. Disable "Lazy Asset Creation" by [Overriding a Resolver](#overriding-a-resolver).
|
||||
2. Create Assets from our CMS by [Creating a New Asset Route](#creating-a-new-asset-route).
|
||||
3. Facilitate updates from our CMS to keep Talk in sync by [Creating an Asset Update Route](#creating-an-asset-update-route).
|
||||
|
||||
We will then modify our embed so that we can [Target the Asset](#Target-the-Asset).
|
||||
We will then modify our embed so that we can [Target the Asset](#target-the-asset).
|
||||
|
||||
But first we should grab our basic plugin structure:
|
||||
|
||||
@@ -248,7 +248,7 @@ module.exports = router => {
|
||||
};
|
||||
```
|
||||
|
||||
As you can see from the previous step of [Creating a New Asset Route](#Creating-a-New-Asset-Route)
|
||||
As you can see from the previous step of [Creating a New Asset Route](#creating-a-New-Asset-Route)
|
||||
, we have added the new `PUT` route to the router. This is a simple addition
|
||||
that allows your CMS to call into Talk when the asset has updated it's title,
|
||||
it's url (or really anything in the [AssetSchema](https://github.com/coralproject/talk/blob/master/models/asset.js)) to keep the Talk Admin and links up to date.
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: Asset Scraping
|
||||
permalink: /integrating/asset-scraping/
|
||||
---
|
||||
|
||||
By default, Assets in Talk have their metadata scraped when they are loaded.
|
||||
This provides the easiest way for newsrooms to integrate their CMS's into Talk
|
||||
in a simple way. We use the following
|
||||
[meta tags](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta) on
|
||||
the target pages that allow us to extract some properties.
|
||||
|
||||
| Asset Property | Selector |
|
||||
|--------------------|----------|
|
||||
| `title` | See [`metascraper-title`](https://github.com/microlinkhq/metascraper/blob/dc664c37ea1b238b1e3e9d5342edfacc9027892c/packages/metascraper-title/index.js) |
|
||||
| `description` | See [`metascraper-description`](https://github.com/microlinkhq/metascraper/blob/dc664c37ea1b238b1e3e9d5342edfacc9027892c/packages/metascraper-description/index.js) |
|
||||
| `image` | See [`metascraper-image`](https://github.com/microlinkhq/metascraper/blob/dc664c37ea1b238b1e3e9d5342edfacc9027892c/packages/metascraper-image/index.js) |
|
||||
| `author` | See [`metascraper-author`](https://github.com/microlinkhq/metascraper/blob/dc664c37ea1b238b1e3e9d5342edfacc9027892c/packages/metascraper-author/index.js) |
|
||||
| `publication_date` | See [`metascraper-date`](https://github.com/microlinkhq/metascraper/blob/dc664c37ea1b238b1e3e9d5342edfacc9027892c/packages/metascraper-date/index.js) |
|
||||
| `modified_date` | `meta[property="article:modified"]` |
|
||||
| `section` | `meta[property="article:section"]` |
|
||||
|
||||
You can use the `./bin/cli assets debug <url>` to print the scraped metadata
|
||||
from that URL. For example:
|
||||
|
||||
```bash
|
||||
$ ./bin/cli assets debug https://www.washingtonpost.com/technology/2018/10/30/apple-event-october-ipad-pro-macbook-air/
|
||||
┌──────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Property │ Value │
|
||||
├──────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ title │ Apple redesigns the iPad Pro, breathes new life in the MacBook Air │
|
||||
├──────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ description │ Apple is unveiling new iPads and MacBooks at an event in New York starting at 10 a.m. Fowler is there and will report in with the news and hands-on analysis throughout the day. │
|
||||
├──────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ image │ https://www.washingtonpost.com/resizer/JAwNQE2alL2JjiWrbXeJ46wZHqA=/1484x0/arc-anglerfish-washpost-prod-washpost.s3.amazonaws.com/public/G5TWBFW4LAI6RC5MX7QB7TODUY.jpg │
|
||||
├──────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ author │ Geoffrey A. Fowler │
|
||||
├──────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ publication_date │ 2018-10-30T10:40:00.000Z │
|
||||
├──────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ modified_date │ │
|
||||
├──────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ section │ │
|
||||
└──────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -231,6 +231,15 @@ class ErrContainsProfanity extends TalkError {
|
||||
}
|
||||
}
|
||||
|
||||
class ErrHTTPNotFound extends TalkError {
|
||||
constructor() {
|
||||
super('http not found', {
|
||||
translation_key: 'NOT_FOUND',
|
||||
status: 404,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class ErrNotFound extends TalkError {
|
||||
constructor() {
|
||||
super('not found', {
|
||||
@@ -334,6 +343,20 @@ class ErrCommentTooShort extends TalkError {
|
||||
}
|
||||
}
|
||||
|
||||
// ErrCommentTooLong is returned when the comment is too long.
|
||||
class ErrCommentTooLong extends TalkError {
|
||||
constructor(length, allowed) {
|
||||
super(
|
||||
'Comment was too long',
|
||||
{
|
||||
translation_key: 'COMMENT_TOO_LONG',
|
||||
status: 400,
|
||||
},
|
||||
{ length, allowed }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ErrAssetURLAlreadyExists is returned when a rename operation is requested
|
||||
// but an asset already exists with the new url.
|
||||
class ErrAssetURLAlreadyExists extends TalkError {
|
||||
@@ -404,13 +427,15 @@ module.exports = {
|
||||
ErrAssetURLAlreadyExists,
|
||||
ErrAuthentication,
|
||||
ErrCannotIgnoreStaff,
|
||||
ErrCommentTooShort,
|
||||
ErrCommentingDisabled,
|
||||
ErrCommentTooLong,
|
||||
ErrCommentTooShort,
|
||||
ErrContainsProfanity,
|
||||
ErrEditWindowHasEnded,
|
||||
ErrEmailAlreadyVerified,
|
||||
ErrEmailTaken,
|
||||
ErrEmailVerificationToken,
|
||||
ErrHTTPNotFound,
|
||||
ErrInstallLock,
|
||||
ErrInvalidAssetURL,
|
||||
ErrLoginAttemptMaximumExceeded,
|
||||
|
||||
@@ -4,7 +4,11 @@ const { SEARCH_OTHER_USERS } = require('../../perms/constants');
|
||||
const { escapeRegExp } = require('../../services/regex');
|
||||
|
||||
const mergeState = (query, state) => {
|
||||
const { status } = state;
|
||||
const { role, status } = state;
|
||||
|
||||
if (role) {
|
||||
query.merge({ role });
|
||||
}
|
||||
|
||||
if (status) {
|
||||
const { username, banned, suspended } = status;
|
||||
|
||||
@@ -85,7 +85,7 @@ const onConnect = async (connectionParams, connection) => {
|
||||
*/
|
||||
const batchedUserRefresher = new DataLoader(
|
||||
userIDs => {
|
||||
console.log(`OPERATION: refreshing ${userIDs.length} users.`);
|
||||
debug(`OPERATION: refreshing ${userIDs.length} users.`);
|
||||
return User.find({ id: { $in: userIDs } }).then(
|
||||
singleJoinBy(userIDs, 'id')
|
||||
);
|
||||
|
||||
@@ -189,6 +189,7 @@ type UserStatus {
|
||||
}
|
||||
|
||||
input UserStateInput {
|
||||
role: USER_ROLES
|
||||
status: UserStatusInput
|
||||
}
|
||||
|
||||
|
||||
+3
-62
@@ -3,59 +3,7 @@ const scraper = require('../../services/scraper');
|
||||
const Assets = require('../../services/assets');
|
||||
const { createLogger } = require('../../services/logging');
|
||||
const logger = createLogger('jobs:scraper');
|
||||
const fetch = require('node-fetch');
|
||||
const { merge } = require('lodash');
|
||||
const { version } = require('../../package.json');
|
||||
const { SCRAPER_HEADERS, SCRAPER_PROXY_URL } = require('../../config');
|
||||
const HttpsProxyAgent = require('https-proxy-agent');
|
||||
|
||||
// Load the scraper with the rules.
|
||||
const metascraper = require('metascraper').load([
|
||||
require('metascraper-title')(),
|
||||
require('metascraper-description')(),
|
||||
require('metascraper-image')(),
|
||||
require('metascraper-author')(),
|
||||
require('metascraper-date')(),
|
||||
require('./rules/modified')(),
|
||||
require('./rules/section')(),
|
||||
]);
|
||||
|
||||
let customHeaders = {};
|
||||
try {
|
||||
customHeaders = JSON.parse(SCRAPER_HEADERS);
|
||||
} catch (err) {
|
||||
console.error('Cannot parse TALK_SCRAPER_HEADERS');
|
||||
throw err;
|
||||
}
|
||||
|
||||
// Parse the headers to be added to the scraper.
|
||||
const headers = merge(
|
||||
{
|
||||
'User-Agent': `Coral-Talk/${version}`,
|
||||
},
|
||||
customHeaders
|
||||
);
|
||||
|
||||
// Add proxy configuration if exists.
|
||||
const agent = SCRAPER_PROXY_URL ? new HttpsProxyAgent(SCRAPER_PROXY_URL) : null;
|
||||
|
||||
/**
|
||||
* Scrapes the given asset for metadata.
|
||||
*/
|
||||
async function scrape({ url }) {
|
||||
const res = await fetch(url, {
|
||||
headers,
|
||||
agent,
|
||||
});
|
||||
const html = await res.text();
|
||||
|
||||
// Get the metadata from the scraped html.
|
||||
const metadata = await metascraper({
|
||||
html,
|
||||
url,
|
||||
});
|
||||
return metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an Asset based on scraped asset metadata.
|
||||
@@ -64,16 +12,9 @@ function update(id, meta) {
|
||||
return Asset.update(
|
||||
{ id },
|
||||
{
|
||||
$set: {
|
||||
title: meta.title || '',
|
||||
description: meta.description || '',
|
||||
image: meta.image ? meta.image : '',
|
||||
author: meta.author || '',
|
||||
publication_date: meta.date || '',
|
||||
modified_date: meta.modified || '',
|
||||
section: meta.section || '',
|
||||
$set: merge(meta, {
|
||||
scraped: new Date(),
|
||||
},
|
||||
}),
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -95,7 +36,7 @@ module.exports = () => {
|
||||
}
|
||||
|
||||
// Scrape the metadata from the asset.
|
||||
const meta = await scrape(asset);
|
||||
const meta = await scraper.scrape(asset.url);
|
||||
|
||||
log.info('Finished scraping');
|
||||
|
||||
|
||||
+3
-3
@@ -130,8 +130,8 @@ ar:
|
||||
enable_questionbox: 'اطرح سؤال على القراء'
|
||||
enable_questionbox_description: 'هذا السؤال سيظهر في الجزء العلوي من جدول التعليقات هذا. اسأل القراء عن مسألة معينة في المقال او اطرح أسئلة نقاشية.. الخ.'
|
||||
hours: ساعات
|
||||
include_comment_stream: 'ادراج وصف جدول التعليقات للقراء'
|
||||
include_comment_stream_desc: 'اكتب رسالة ليتم إضافتها إلى الجزء العلوي من جدول التعليقات. ضع موضوعا، اشمل القواعد الإرشادية للمجموعة .. الخ'
|
||||
code_of_conduct_summary: 'ادراج وصف جدول التعليقات للقراء'
|
||||
code_of_conduct_summary_desc: 'اكتب رسالة ليتم إضافتها إلى الجزء العلوي من جدول التعليقات. ضع موضوعا، اشمل القواعد الإرشادية للمجموعة .. الخ'
|
||||
include_question_here: 'اكتب سؤالك هنا:'
|
||||
include_text: 'ادرج النص هنا.'
|
||||
moderate: اشرف
|
||||
@@ -225,6 +225,7 @@ ar:
|
||||
CANNOT_IGNORE_STAFF: 'لا يمكن تجاهل الموظفين.'
|
||||
COMMENT_PARENT_NOT_VISIBLE: 'التعليق الذي ترد عليه تمت إزالته أو غير موجود.'
|
||||
COMMENT_TOO_SHORT: 'يجب أن تكون التعليقات أكثر من حرف واحد، يرجى مراجعة تعليقك وإعادة المحاولة.'
|
||||
COMMENT_TOO_LONG: 'يتجاوز النص الحد الأقصى للطول المسموح'
|
||||
COMMENTING_CLOSED: 'تم إغلاق فاعلية التعليق'
|
||||
COMMENTING_DISABLED: 'التعليق معطّل حاليًا على هذا الموقع'
|
||||
confirm_password: 'كلمات المرور غير متطابقة. يرجى التحقق مرة أخرى'
|
||||
@@ -281,7 +282,6 @@ ar:
|
||||
reasons:
|
||||
comment:
|
||||
banned_word: 'كلمة محظورة'
|
||||
body_count: 'يتجاوز النص الحد الأقصى للطول المسموح'
|
||||
comment_noagree: أعارض
|
||||
comment_offensive: مسيء
|
||||
comment_other: آخر
|
||||
|
||||
+3
-3
@@ -123,8 +123,8 @@ da:
|
||||
enable_questionbox: 'Stil et spørgsmål til læserne'
|
||||
enable_questionbox_description: 'Dette spørgsmål vises øverst i denne kommentarstrøm. Stil et spørgsmål til læserne om et bestemt problem i artiklen eller stil spørgsmål til diskussion mv.'
|
||||
hours: Timer
|
||||
include_comment_stream: 'Inkluder kommentarstrømmens beskrivelse for læsere'
|
||||
include_comment_stream_desc: 'Skriv en besked, der skal tilføjes øverst i din kommentarstrøm. Indsæt et emne der omfatter fællesskabsretningslinjer mv.'
|
||||
code_of_conduct_summary: 'Inkluder kommentarstrømmens beskrivelse for læsere'
|
||||
code_of_conduct_summary_desc: 'Skriv en besked, der skal tilføjes øverst i din kommentarstrøm. Indsæt et emne der omfatter fællesskabsretningslinjer mv.'
|
||||
include_question_here: 'Stil dit spørgsmål her:'
|
||||
include_text: 'Medtag din tekst her.'
|
||||
moderate: Moderat
|
||||
@@ -197,6 +197,7 @@ da:
|
||||
CANNOT_IGNORE_STAFF: 'Kan ikke ignorere personale.'
|
||||
COMMENT_PARENT_NOT_VISIBLE: 'Den kommentar, du svarer på er blevet fjernet eller eksisterer ikke.'
|
||||
COMMENT_TOO_SHORT: 'Din kommentar skal indeholde noget'
|
||||
COMMENT_TOO_LONG: 'Body overstiger max længde'
|
||||
COMMENTING_CLOSED: 'Kommentering er allerede lukket'
|
||||
confirm_password: 'Kodeordene matcher ikke. Tjek venligst igen.'
|
||||
EDIT_USERNAME_NOT_AUTHORIZED: 'Du har ikke tilladelse til at opdatere dit brugernavn.'
|
||||
@@ -238,7 +239,6 @@ da:
|
||||
reasons:
|
||||
comment:
|
||||
banned_word: 'Forbudt ord'
|
||||
body_count: 'Body overstiger max længde'
|
||||
comment_noagree: Uenig
|
||||
comment_offensive: Offensiv
|
||||
comment_other: Andre
|
||||
|
||||
+6
-3
@@ -48,6 +48,8 @@ de:
|
||||
comment_post_notif_premod: 'Vielen Dank für Ihren Kommentar. Unsere Moderatoren werden ihn in Kürze bearbeiten.'
|
||||
comment_singular: Kommentar
|
||||
common:
|
||||
copied: 'Kopiert'
|
||||
notsupported: 'Nicht unterstützt'
|
||||
copy: Kopieren
|
||||
error: 'Ein Problem ist aufgetreten.'
|
||||
reaction: 'Reaktion'
|
||||
@@ -130,8 +132,8 @@ de:
|
||||
enable_questionbox: 'Stellen Sie den Lesern eine Frage'
|
||||
enable_questionbox_description: 'Diese Frage erscheint am Anfang des Kommentarbereichs. Regen Sie eine Diskussion an.'
|
||||
hours: Stunden
|
||||
include_comment_stream: 'Einleitung zum Kommentarbereich'
|
||||
include_comment_stream_desc: 'Verfassen Sie eine Einleitung, die über jedem Kommentarbereich erscheint. Nützlich z.B. für Community-Richtlinien.'
|
||||
code_of_conduct_summary: 'Einleitung zum Kommentarbereich'
|
||||
code_of_conduct_summary_desc: 'Verfassen Sie eine Einleitung, die über jedem Kommentarbereich erscheint. Nützlich z.B. für Community-Richtlinien.'
|
||||
include_question_here: 'Stellen Sie Ihre Frage hier:'
|
||||
include_text: 'Fügen Sie Ihren Text hier ein.'
|
||||
moderate: Moderieren
|
||||
@@ -216,11 +218,13 @@ de:
|
||||
embed_comments_tab: Kommentare
|
||||
embedlink:
|
||||
copy: 'In die Zwischenablage kopieren'
|
||||
copied: 'Kopiert'
|
||||
error:
|
||||
ALREADY_EXISTS: 'Ressource existiert bereits'
|
||||
CANNOT_IGNORE_STAFF: 'Mitarbeiter können nicht ignoriert werden.'
|
||||
COMMENT_PARENT_NOT_VISIBLE: 'Der Kommentar, auf den Sie antworten möchten, wurde entfernt oder existiert nicht.'
|
||||
COMMENT_TOO_SHORT: 'Kommentare sollten mehr als ein Zeichen enthalten, bitte überprüfen Sie Ihren Kommentar und probieren Sie es erneut.'
|
||||
COMMENT_TOO_LONG: 'Text überschreitet Zeichenlimit'
|
||||
COMMENTING_CLOSED: 'Kommentarbereich ist bereits geschlossen'
|
||||
COMMENTING_DISABLED: 'Die Kommentarfunktion ist derzeit abgeschaltet'
|
||||
confirm_password: 'Passwörter nicht identisch. Bitte erneut überprüfen'
|
||||
@@ -270,7 +274,6 @@ de:
|
||||
reasons:
|
||||
comment:
|
||||
banned_word: 'Unzulässiges Wort'
|
||||
body_count: 'Text überschreitet Zeichenlimit'
|
||||
comment_noagree: 'Andere Meinung'
|
||||
comment_offensive: Unangemessen
|
||||
comment_other: Anderes
|
||||
|
||||
+17
-3
@@ -48,7 +48,10 @@ en:
|
||||
comment_post_notif_premod: 'Thank you for posting. Our moderation team will review your comment shortly.'
|
||||
comment_singular: Comment
|
||||
common:
|
||||
contains_link: 'Contains Link'
|
||||
copy: Copy
|
||||
copied: 'Copied'
|
||||
notsupported: 'Not supported'
|
||||
error: 'An error has occurred.'
|
||||
reaction: reaction
|
||||
reactions: reactions
|
||||
@@ -60,6 +63,7 @@ en:
|
||||
active: Active
|
||||
admin: Administrator
|
||||
ads_marketing: 'This looks like an ad/marketing'
|
||||
all: 'All'
|
||||
are_you_sure: 'Are you sure you would like to ban {0}?'
|
||||
ban_user: 'Ban User?'
|
||||
banned: Banned
|
||||
@@ -67,6 +71,8 @@ en:
|
||||
cancel: Cancel
|
||||
commenter: Commenter
|
||||
dont_like_username: 'Dislike username'
|
||||
filter_users: 'Filter users'
|
||||
filter_role: Role
|
||||
flaggedaccounts: 'Reported Usernames'
|
||||
flags: Flags
|
||||
impersonating: Impersonation
|
||||
@@ -83,6 +89,7 @@ en:
|
||||
spam_ads: Spam/Ads
|
||||
staff: Staff
|
||||
status: Status
|
||||
suspended: Suspended
|
||||
username_and_email: 'Username and Email'
|
||||
yes_ban_user: 'Yes Ban User'
|
||||
configure:
|
||||
@@ -130,8 +137,8 @@ en:
|
||||
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.'
|
||||
code_of_conduct_summary: 'Summary of your Code of Conduct'
|
||||
code_of_conduct_summary_desc: 'This message will appear above every comments stream on your site. Click here to learn more about writing a good code.'
|
||||
include_question_here: 'Write your question here:'
|
||||
include_text: 'Include your text here.'
|
||||
moderate: Moderate
|
||||
@@ -144,6 +151,7 @@ en:
|
||||
organization_info_copy_2: 'We recommend creating a generic email account (eg. community@yournewsroom.com) for this purpose. This means it can remain consistent over time, and doesn''t expose a name that users could target if their account were blocked.'
|
||||
organization_information: 'Organization Information'
|
||||
organization_name: 'Organization Name'
|
||||
suspect_or_forbidden_words_placeholder: 'Word or phrase'
|
||||
product_guide_link: 'Product Guide'
|
||||
report_bug_or_feedback: 'Report a bug or give feedback'
|
||||
require_email_verification: 'Require Email Verification'
|
||||
@@ -219,12 +227,14 @@ en:
|
||||
embed_comments_tab: Comments
|
||||
embedlink:
|
||||
copy: 'Copy to Clipboard'
|
||||
copied: 'Copied'
|
||||
error:
|
||||
ALREADY_EXISTS: 'Resource already exists'
|
||||
AUTHENTICATION: 'An error occurred trying to authenticate your account.'
|
||||
CANNOT_IGNORE_STAFF: 'Cannot ignore Staff members.'
|
||||
COMMENT_PARENT_NOT_VISIBLE: 'The comment that you''re replying to has been removed or doesn''t exist.'
|
||||
COMMENT_TOO_SHORT: 'Comments should be more than one character, please revise your comment and try again.'
|
||||
COMMENT_TOO_LONG: 'Body exceeds max length'
|
||||
COMMENTING_CLOSED: 'Commenting is already closed'
|
||||
COMMENTING_DISABLED: 'Commenting is currently disabled on this site'
|
||||
confirm_password: 'Passwords don''t match. Please check again'
|
||||
@@ -249,6 +259,7 @@ en:
|
||||
organization_contact_email: 'Organization email is not valid.'
|
||||
organization_name: 'Organization name must only contain letters or numbers.'
|
||||
password: 'Password must be at least 8 characters'
|
||||
PAGE_NOT_AVAILABLE_ROLE: 'This page is for team use only. Please contact an administrator if you want to join this team.'
|
||||
PASSWORD_INCORRECT: 'Your current password was entered incorrectly'
|
||||
PASSWORD_LENGTH: 'Password is too short'
|
||||
PASSWORD_REQUIRED: 'Must input a password'
|
||||
@@ -281,7 +292,6 @@ en:
|
||||
reasons:
|
||||
comment:
|
||||
banned_word: 'Banned Word'
|
||||
body_count: 'Body exceeds max length'
|
||||
comment_noagree: Disagree
|
||||
comment_offensive: Offensive
|
||||
comment_other: Other
|
||||
@@ -308,6 +318,7 @@ en:
|
||||
comments: comments
|
||||
configure_stream: Configure
|
||||
content_not_available: 'This content is not available'
|
||||
edit: Edit
|
||||
edit_name:
|
||||
button: Submit
|
||||
error: 'Usernames can contain letters numbers and _ only'
|
||||
@@ -359,6 +370,7 @@ en:
|
||||
sign_in_button: 'Sign Inx'
|
||||
sign_in_message: 'Sign in to interact with your community.'
|
||||
password: Password
|
||||
reset_password_send_button: 'Retrieve Password'
|
||||
request_passowrd: 'Request a new one.'
|
||||
team_sign_in: 'Team sign in'
|
||||
marketing: 'This looks like an ad/marketing'
|
||||
@@ -372,6 +384,7 @@ en:
|
||||
approve: Approve
|
||||
approved: Approved
|
||||
ban_user: Ban
|
||||
ban_user_actions: 'Ban User'
|
||||
billion: B
|
||||
close: Close
|
||||
empty_queue: 'No more comments to moderate! You''re all caught up. Go have some ☕️'
|
||||
@@ -406,6 +419,7 @@ en:
|
||||
show_shortcuts: 'Show Shortcuts'
|
||||
singleview: 'Zen mode'
|
||||
sort: Sort
|
||||
suspend: 'Suspend User'
|
||||
system_withheld: 'System Withheld'
|
||||
thismenu: 'Open this menu'
|
||||
thousand: k
|
||||
|
||||
+52
-31
@@ -4,19 +4,19 @@ es:
|
||||
view_options: 'Ver opciones'
|
||||
already_flagged_username: 'Usted ya reportó a este usuario.'
|
||||
bandialog:
|
||||
are_you_sure: '¿Estás segura que quieres suspender a {0}?'
|
||||
ban_user: '¿Quieres suspender el Usuario?'
|
||||
are_you_sure: '¿Estás seguro que quieres suspender a {0}?'
|
||||
ban_user: '¿Quieres suspender al Usuario?'
|
||||
banned_user: 'Usuario Suspendido'
|
||||
cancel: Cancelar
|
||||
email_message_ban: "Estimado/a {0},\n\nUsted o alguien con acceso a su cuenta a violado los lineamientos de nuestra comunidad. Como consecuencia de esto, su cuenta fue bloqueada. No podrá realizar ni reportar más comentarios. Si usted piensa que esto ha sido un error, por favor contáctese con nosotros."
|
||||
email_message_ban: "Estimado/a {0},\n\nUsted o alguien con acceso a su cuenta ha violado los lineamientos de nuestra comunidad. Como consecuencia de esto, su cuenta fue bloqueada. No podrá realizar ni reportar más comentarios. Si usted piensa que esto ha sido un error, por favor contáctese con nosotros."
|
||||
note: 'Nota: {0}'
|
||||
note_ban_user: 'Suspender a este usuario no le va a permitir (al usuario) borrar ni editar ni comentar.'
|
||||
note_reject_comment: 'Suspender a este usuario también va a colocar este comentario en la cola de Rechazados.'
|
||||
notify_ban_description: 'Esto notificará al usuario por email que fueron suspendidos de la comunidad'
|
||||
notify_ban_description: 'Esto notificará al usuario por correo electrónico que fueron suspendidos de la comunidad'
|
||||
notify_ban_headline: 'Notificar al usuario de la suspensión'
|
||||
send: Enviar
|
||||
write_a_message: 'Escribe un mensaje'
|
||||
yes_ban_user: 'Si, Suspender al usuario'
|
||||
yes_ban_user: 'Si, suspender al usuario'
|
||||
bio_offensive: 'Esta biografia es ofensiva'
|
||||
cancel: Cancelar
|
||||
characters_remaining: 'caracteres restantes'
|
||||
@@ -30,9 +30,9 @@ es:
|
||||
view_context: 'Ver contexto'
|
||||
comment_box:
|
||||
cancel: Cancelar
|
||||
characters_remaining: 'carácteres restantes'
|
||||
characters_remaining: 'caracteres restantes'
|
||||
comment: 'Publicar un comentario'
|
||||
comment_post_banned_word: 'Tu comentario contiene una o más palabras que no están permitidas en nuestro espacio, por lo que no será publicado. Si crees que es un error, por favor contacta a nuestro equipo de moderación.'
|
||||
comment_post_banned_word: 'Tu comentario contiene una o más palabras que no están permitidas en nuestro espacio, por lo que no será publicado. Si crees que es un error, por favor contactate 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.'
|
||||
name: Nombre
|
||||
@@ -40,11 +40,12 @@ es:
|
||||
reply: Responder
|
||||
comment_offensive: 'Este comentario es ofensivo'
|
||||
comment_plural: Comentarios
|
||||
comment_post_banned_word: 'Tu comentario contiene una o más palabras que no están permitidas en nuestro espacio, por lo que no será publicado. Si crees que es un error, por favor contacta a nuestro equipo de moderación.'
|
||||
comment_post_banned_word: 'Tu comentario contiene una o más palabras que no están permitidas en nuestro espacio, por lo que no será publicado. Si crees que es un error, por favor contactate con nuestro equipo de moderación.'
|
||||
comment_post_notif: 'Tu comentario ha sido publicado.'
|
||||
comment_post_notif_premod: 'Gracias por el comentario. Nuestro equipo de moderación va a revisarlo muy pronto.'
|
||||
comment_singular: Comentario
|
||||
common:
|
||||
contains_link: 'Contiene enlace'
|
||||
copy: Copiar
|
||||
error: 'Ha ocurrido un error.'
|
||||
reaction: reacción
|
||||
@@ -56,36 +57,40 @@ es:
|
||||
account_creation_date: 'Fecha de creación de la cuenta'
|
||||
active: Activa
|
||||
admin: Administrator
|
||||
ads_marketing: 'Esto parece ser un ad/marketing'
|
||||
are_you_sure: '¿Estás segura que quieres suspender a {0}?'
|
||||
ads_marketing: 'Esto parece ser un publicidad/acción de comercialización'
|
||||
all: 'Todos'
|
||||
are_you_sure: '¿Estás seguro que quieres suspender a {0}?'
|
||||
ban_user: '¿Quieres suspender al Usuario?'
|
||||
banned: Suspendido
|
||||
banned_user: 'Usuario Suspendido'
|
||||
banned_user: 'Usuario suspendido'
|
||||
cancel: Cancelar
|
||||
commenter: Comentarista
|
||||
dont_like_username: 'No me gusta este nombre de usuario'
|
||||
flaggedaccounts: 'Nombres de Usuario Reportados'
|
||||
filter_users: 'Filtrarr usuarios'
|
||||
filter_role: Rol
|
||||
flaggedaccounts: 'Nombres de usuario reportados'
|
||||
flags: Reportes
|
||||
impersonating: Impersonando
|
||||
loading: 'Cargando resultados'
|
||||
moderator: Moderator
|
||||
newsroom_role: 'Rol en la redacción'
|
||||
no_flagged_accounts: 'No hay ningún nombre de usario reportado en este momento.'
|
||||
no_flagged_accounts: 'No hay ningún nombre de usuario reportado en este momento.'
|
||||
no_results: 'No se encontraron usuarios con ese nombre o correo.'
|
||||
offensive: Ofensivo
|
||||
other: Otro
|
||||
people: Gente
|
||||
role: 'Seleccionar rol...'
|
||||
select_status: 'Seleccionar estado...'
|
||||
spam_ads: Spam/Publicidad
|
||||
spam_ads: Correo basura/Publicidad
|
||||
staff: Personal
|
||||
status: Estado
|
||||
suspended: Suspendido
|
||||
username_and_email: 'Usuario y Correo'
|
||||
yes_ban_user: 'Si, Suspendan el usuario'
|
||||
yes_ban_user: 'Sí, suspendan el usuario'
|
||||
configure:
|
||||
access_message: 'Usted debe ser un administrador para acceder a esta página. Encuentre a otro admin y actualice los permisos de su cuenta!'
|
||||
access_message: 'Usted debe ser un administrador para acceder a esta página. Encuentre a otro administrador y actualice los permisos de su cuenta!'
|
||||
apply: Aplicar
|
||||
banned_word_text: 'Comentarios que contengan estas palabras o frases, en mayusculas o minúsculas, serán automáticamente eliminados del hilo de comentario. Escribir una palabra y apretar Enter o Tabulador para agregarla. O pueden pegar una lista de palabras separadas por coma.'
|
||||
banned_word_text: 'Comentarios que contengan estas palabras o frases, en mayúsculas o minúsculas, serán automáticamente eliminados del hilo de comentarios. Escribir una palabra y apretar Enter o Tabulador para agregarla. O pueden pegar una lista de palabras separadas por coma.'
|
||||
banned_words_title: 'Lista de palabras prohibidas'
|
||||
close: Cerrar
|
||||
close_after: 'Cerrar comentarios luego de'
|
||||
@@ -93,14 +98,14 @@ es:
|
||||
close_stream_configuration: 'Este hilo de comentario está en este momento cerrado. Al abrirlo, nuevos comentarios serán publicados y mostrados.'
|
||||
closed_comments_desc: 'Escribe un mensaje que será mostrado cuando los comentarios estén cerrados y no se acepten más comentarios.'
|
||||
closed_comments_label: 'Escribe un mensaje...'
|
||||
closed_stream_settings: 'Mensaje que se muestra cuando no se aceptan más comentarios en el articulo'
|
||||
closed_stream_settings: 'Mensaje que se muestra cuando no se aceptan más comentarios en el artículo'
|
||||
comment_count_error: 'Por favor escribir un número válido'
|
||||
comment_count_header: 'Limitar el largo del comentario'
|
||||
comment_count_text_post: carácteres
|
||||
comment_count_text_post: caracteres
|
||||
comment_count_text_pre: 'Los comentarios serán limitados a'
|
||||
comment_settings: Configuración
|
||||
comment_stream: 'Hilo de Comentarios'
|
||||
comment_stream_will_close: 'El hilo de comentarios se cerrara'
|
||||
comment_stream_will_close: 'El hilo de comentarios se cerrará'
|
||||
community: Comunidad
|
||||
configure: Configurar
|
||||
copy_and_paste: 'Copiar y pegar el código de más abajo en tu CMS para colocar la caja de comentarios en tus artículos'
|
||||
@@ -117,16 +122,16 @@ es:
|
||||
embed_comment_stream: 'Colocar Hilo de Comentarios'
|
||||
enable_pre_moderation: 'Permitir pre-moderación'
|
||||
enable_pre_moderation_text: 'Los moderadores deben aprobar todo comentario antes que sea publicado.'
|
||||
enable_premod: 'Activar Pre Moderación'
|
||||
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: 'Pre-Moderar Comentarios que contienen Enlaces'
|
||||
enable_premod_links: 'Pre-Moderar comentarios que contienen Enlaces'
|
||||
enable_premod_links_description: 'Los y las moderadoras deben aprobar cualquier comentario que contengan enlaces antes de su publicación.'
|
||||
enable_premod_links_text: 'Los moderadores deben aprobar todo comentario que contenga un enlace antes de que sea publicado.'
|
||||
enable_questionbox: 'Hacer una pregunta a los y las lectoras.'
|
||||
enable_questionbox_description: 'Esta pregunta aparecerá en la parte de arriba del hilo de comentarios.'
|
||||
hours: Horas
|
||||
include_comment_stream: 'Incluir Descripción de Hilo de Comentarios para Lectores'
|
||||
include_comment_stream_desc: 'Escribir un mensaje para ser incluido al principio del hilo de comentarios. Un tema planteado podría ser la guía de comunidad, etc.'
|
||||
code_of_conduct_summary: 'Incluir Descripción de Hilo de Comentarios para Lectores'
|
||||
code_of_conduct_summary_desc: 'Escribir un mensaje para ser incluido al principio del hilo de comentarios. Un tema planteado podría ser la guía de comunidad, etc.'
|
||||
include_question_here: 'Escribir la pregunta aquí.'
|
||||
include_text: 'Agregar tu texto aquí.'
|
||||
moderate: Moderar
|
||||
@@ -135,10 +140,12 @@ es:
|
||||
open_stream: 'Abrir Hilo de Comentarios'
|
||||
open_stream_configuration: 'Este hilo de comentarios está abierto. Al cerrarlo no se podrán publicar nuevos comentarios pero todos los comentarios anteriores aún serán mostrados.'
|
||||
organization_contact_email: 'Email de la Organización'
|
||||
organization_info_copy: 'Nosotros usamos esta información en las notificaciones de email generadas por Talk. Esto conecta los mensajes de tu organización, y provee una forma para que los usuarios se comuniquen si tienen un inconveniente con su cuenta.'
|
||||
organization_info_copy: 'Nosotros usamos esta información en las notificaciones de correo electrónico generadas por Talk. Esto conecta los mensajes de tu organización, y provee una forma para que los usuarios se comuniquen si tienen un inconveniente con su cuenta.'
|
||||
organization_info_copy_2: 'Recomendamos crear un email genérico (ej: community@yournewsroom.com) for this purpose. Esto significa que puede permanecer consistente con el tiempo y no expone un nombre que los usuarios puedan atacar si su cuenta fue bloqueada.'
|
||||
organization_information: 'Información de la Organización'
|
||||
organization_name: 'Nombre de la Organización'
|
||||
product_guide_link: 'Guía de Talk'
|
||||
report_bug_or_feedback: 'Registrar un error de Talk'
|
||||
require_email_verification: 'Necesita confirmación su correo'
|
||||
require_email_verification_text: 'Nuevos usuarios deben confirmar sus correos antes de comentar'
|
||||
save: Guardar
|
||||
@@ -157,6 +164,7 @@ es:
|
||||
suspect_word_title: 'Lista de palabras sospechosas'
|
||||
tech_settings: 'Configuración Técnica'
|
||||
title: 'Configurar los comentarios'
|
||||
view_last_version: 'Ver la versión de Talk'
|
||||
weeks: Semanas
|
||||
wordlist: 'Palabras Suspendidas'
|
||||
confirm_email:
|
||||
@@ -212,6 +220,7 @@ es:
|
||||
CANNOT_IGNORE_STAFF: 'No puede ignorar a miembros del Staff.'
|
||||
COMMENT_PARENT_NOT_VISIBLE: 'El comentario a la que estás contestando ha sido eliminado o no existe.'
|
||||
COMMENT_TOO_SHORT: 'Tu comentario debe tener algo escrito'
|
||||
COMMENT_TOO_LONG: 'El texto excede el límite permitido'
|
||||
COMMENTING_CLOSED: 'Los comentarios ya estan cerrados'
|
||||
confirm_password: 'Las contraseñas no coinciden. Inténtelo nuevamente'
|
||||
EDIT_USERNAME_NOT_AUTHORIZED: 'No tiene permiso para editar el nombre de usuario.'
|
||||
@@ -257,7 +266,6 @@ es:
|
||||
reasons:
|
||||
comment:
|
||||
banned_word: 'Palabra prohibida'
|
||||
body_count: 'El texto exede el límite permitido'
|
||||
comment_noagree: 'No está de acuerdo'
|
||||
comment_offensive: 'Es ofensivo'
|
||||
comment_other: 'Otra razón'
|
||||
@@ -280,8 +288,9 @@ es:
|
||||
comment_is_ignored: 'Este comentario está escondido porque has ignorado al usuario.'
|
||||
comment_is_rejected: 'Has rechazado este comentario.'
|
||||
comments: comentarios
|
||||
configure_stream: 'Configurar Hilo de Comentarios'
|
||||
configure_stream: 'Configurar'
|
||||
content_not_available: 'Este contenido no se encuentra disponible'
|
||||
edit: Editar
|
||||
edit_name:
|
||||
button: Enviar
|
||||
error: 'Nombres de usuarios pueden solamente incluir letras, números y _'
|
||||
@@ -307,14 +316,14 @@ es:
|
||||
save: Guardar
|
||||
create:
|
||||
confirm_password: 'Confirmar Contraseña'
|
||||
email: 'Dirección de correo'
|
||||
organization_contact_email: 'Organización: Email de contacto'
|
||||
email: 'Dirección de correo electrónico'
|
||||
organization_contact_email: 'Organización: correo electrónico de contacto'
|
||||
password: Contraseña
|
||||
save: Guardar
|
||||
username: 'Nombre de Usuario'
|
||||
final:
|
||||
close: 'Cerrar este instalador'
|
||||
description: '¡Gracias por instalar Talk! Enviamos un correo para verificar su dirección de correo. Mientras esta terminando de configurar su cuenta, ya puede comenzar a involucrarse con sus lectores.'
|
||||
description: '¡Gracias por instalar Talk! Enviamos un correo para verificar su dirección de correo electrónico. Mientras esta terminando de configurar su cuenta, ya puede comenzar a involucrarse con sus lectores.'
|
||||
launch: 'Iniciar Talk'
|
||||
initial:
|
||||
description: 'Vamos a crear su comunidad Talk en unos pocos pasos.'
|
||||
@@ -324,6 +333,17 @@ es:
|
||||
submit: 'Terminar la Instalación'
|
||||
title: 'Dominios permitidos'
|
||||
like: 'Me gusta'
|
||||
login:
|
||||
email_address: 'Dirección de correo'
|
||||
forgot_password: '¿Olvidaste tu contraseña?'
|
||||
go_back: 'Regresar'
|
||||
sign_in: 'Entrar'
|
||||
sign_in_button: 'Entrar'
|
||||
sign_in_message: 'Regístrese para interactuar con su comunidad.'
|
||||
password: Contraseña
|
||||
reset_password_send_button: 'Recuperar Contraseña'
|
||||
request_password: 'Solicita uno nuevo.'
|
||||
team_sign_in: 'Entrada del equipo'
|
||||
loading_results: 'Cargando Resultados'
|
||||
marketing: 'Esto parece una propaganda'
|
||||
moderate_this_stream: 'Moderar este hilo de comentarios'
|
||||
@@ -382,6 +402,7 @@ es:
|
||||
other: Otro
|
||||
password_reset:
|
||||
change_password: 'Cambio de contraseña'
|
||||
change_password_help: 'Por favor, introduzca una nueva contraseña. ¡Hazlo seguro!'
|
||||
confirm_new_password: 'Confirme su nueva contraseña'
|
||||
mail_sent: 'Si tiene una cuenta registrada, un enlace para resetear su clave ha sido enviado a esa dirección de correo.'
|
||||
new_password: 'Nueva contraseña'
|
||||
@@ -421,7 +442,7 @@ es:
|
||||
step_2_header: 'Ayúdanos a comprender'
|
||||
step_3_header: 'Gracias por tu participación'
|
||||
stream:
|
||||
all_comments: 'Todos los comentarios'
|
||||
all_comments: 'Todos'
|
||||
comment_not_found: 'Este comentario ha sido eliminado o no existe.'
|
||||
no_comments: 'Todavía no hay comentarios. ¿Por qué no escribes uno?'
|
||||
no_comments_and_closed: 'No hubo comentarios en este artículo.'
|
||||
|
||||
+3
-3
@@ -123,8 +123,8 @@ fi_FI:
|
||||
enable_questionbox: 'Kysy lukijoilta'
|
||||
enable_questionbox_description: 'Tämä kysymys tulee näkymään kommenttiosion ylälaidassa. Kysy artikkelin aiheesta tai ohjaa keskustelua kysymyksen avulla.'
|
||||
hours: Tuntia
|
||||
include_comment_stream: 'Sisällytä kommentoinnin kuvaus lukijoille'
|
||||
include_comment_stream_desc: 'Kirjoita kommenttiosion yläreunassa näkyvä viesti. Aseta keskustelun aihe, sisällytä sääntöjä tms.'
|
||||
code_of_conduct_summary: 'Sisällytä kommentoinnin kuvaus lukijoille'
|
||||
code_of_conduct_summary_desc: 'Kirjoita kommenttiosion yläreunassa näkyvä viesti. Aseta keskustelun aihe, sisällytä sääntöjä tms.'
|
||||
include_question_here: 'Kirjoita kysymyksesi tähän:'
|
||||
include_text: 'Lisää teksti tähän.'
|
||||
moderate: Moderoi
|
||||
@@ -197,6 +197,7 @@ fi_FI:
|
||||
CANNOT_IGNORE_STAFF: 'Työntekijöitä ei voi jättää huomioimatta'
|
||||
COMMENT_PARENT_NOT_VISIBLE: 'Kommenttia, johon yrität vastata, ei enää ole.'
|
||||
COMMENT_TOO_SHORT: 'Kommentin tulee olla vähintään kaksi merkkiä pitkä. Tarkista kirjoittamasi teksti.'
|
||||
COMMENT_TOO_LONG: Liian pitkä viesti'
|
||||
COMMENTING_CLOSED: 'Kommentointi on suljettu'
|
||||
confirm_password: 'Salasanat eivät täsmää. Tarkista, ole hyvä.'
|
||||
EDIT_USERNAME_NOT_AUTHORIZED: 'Sinulla ei ole oikeutta päivittää tai muokata käyttäjänimeä.'
|
||||
@@ -240,7 +241,6 @@ fi_FI:
|
||||
reasons:
|
||||
comment:
|
||||
banned_word: 'Kielletty sana'
|
||||
body_count: 'Liian pitkä viesti'
|
||||
comment_noagree: 'Olen eri mieltä'
|
||||
comment_offensive: Loukkaava
|
||||
comment_other: Muu
|
||||
|
||||
+3
-3
@@ -127,8 +127,8 @@ fr:
|
||||
enable_questionbox: 'Posez une question aux lecteurs.'
|
||||
enable_questionbox_description: 'Cette question apparaîtra en haut de ce fil de commentaires. Demandez aux lecteurs de s''exprimer sur un sujet évoqué dans l''article ou posez les termes de la discussion, etc.'
|
||||
hours: Heures
|
||||
include_comment_stream: 'Inclure la description du fil de commentaires pour les lecteurs'
|
||||
include_comment_stream_desc: 'Écrivez un message à ajouter au haut de votre flux de commentaires. Publiez un sujet de discussion, avec des suggestion sur la tenue des débats, etc.'
|
||||
code_of_conduct_summary: 'Inclure la description du fil de commentaires pour les lecteurs'
|
||||
code_of_conduct_summary_desc: 'Écrivez un message à ajouter au haut de votre flux de commentaires. Publiez un sujet de discussion, avec des suggestion sur la tenue des débats, etc.'
|
||||
include_question_here: 'Écrivez votre question ici.'
|
||||
include_text: 'Entrez votre texte ici.'
|
||||
moderate: Modérer
|
||||
@@ -191,6 +191,7 @@ fr:
|
||||
CANNOT_IGNORE_STAFF: 'Ne peut pas ignorer les membres de l''équipe.'
|
||||
COMMENT_PARENT_NOT_VISIBLE: 'Le commentaire auquel vous répondez a été supprimé ou n’existe plus.'
|
||||
COMMENT_TOO_SHORT: 'Votre commentaire doit contenir quelque chose'
|
||||
COMMENT_TOO_LONG: 'Le texte dépasse la longueur maximale'
|
||||
COMMENTING_CLOSED: 'Les commentaires sont déjà fermés'
|
||||
confirm_password: 'Les mots de passe ne correspondent pas. Vérifiez à nouveau'
|
||||
EDIT_USERNAME_NOT_AUTHORIZED: 'Vous n''avez pas la permission de mettre à jour votre nom d''utilisateur.'
|
||||
@@ -235,7 +236,6 @@ fr:
|
||||
reasons:
|
||||
comment:
|
||||
banned_word: 'Mot banni'
|
||||
body_count: 'Le texte dépasse la longueur maximale'
|
||||
comment_noagree: 'Pas d’accord'
|
||||
comment_offensive: Offensive
|
||||
comment_other: Autre
|
||||
|
||||
+574
@@ -0,0 +1,574 @@
|
||||
it:
|
||||
admin_sidebar:
|
||||
sort_comments: 'Ordina Commenti'
|
||||
view_options: 'Visualizza Opzioni'
|
||||
already_flagged_username: 'Hai già segnalato questo username.'
|
||||
bandialog:
|
||||
are_you_sure: 'Sei sicuro di voler bloccare {0}?'
|
||||
ban_user: 'Blocca Utente'
|
||||
banned_user: 'Utenti bloccati'
|
||||
cancel: Annulla
|
||||
email_message_ban: "Caro {0},\n\nQualcuno che ha accesso al tuo account ha violato le nostre linee guida per la community. Di conseguenza, il tuo account è stato bloccato. Non potrai più commentare, apprezzare o segnalare commenti. Se ritieni questo sia un errore, contatta i nostri moderatori."
|
||||
note: 'Nota: {0}'
|
||||
note_ban_user: 'Bloccare questo utente non gli permetterà di commentare, interagire, o segnalare commenti.'
|
||||
note_reject_comment: 'Bloccare questo utente inserirà inoltre questo commento tra quelli rifiutati.'
|
||||
notify_ban_description: 'Questo notificherà l''utente, tramite email, che è stato bloccato dalla comunità.'
|
||||
notify_ban_headline: 'Notifica l''utente della interdizione'
|
||||
send: Invia
|
||||
write_a_message: 'Scrivi un messaggio'
|
||||
yes_ban_user: 'Si, blocca utente'
|
||||
bio_offensive: 'Questa descrizione è offensiva'
|
||||
cancel: Annulla
|
||||
characters_remaining: 'caratteri rimanenti'
|
||||
comment:
|
||||
anon: Anonimo
|
||||
ban_user: 'Blocca Utente'
|
||||
comment: 'Pubblica un commento'
|
||||
edited: Modificato
|
||||
flagged: segnalato
|
||||
undo_reject: Annulla
|
||||
view_context: 'Visualizza il contesto'
|
||||
comment_box:
|
||||
cancel: Annulla
|
||||
characters_remaining: 'caratteri rimanenti'
|
||||
comment: 'Pubblica un commento'
|
||||
comment_post_banned_word: 'Il tuo commento contiene una o più parole non permesse, non sarà quindi pubblicato. Se ritieni questo sia un errore, contatta i nostri moderatori.'
|
||||
comment_post_notif: 'Il tuo commento è stato pubblicato.'
|
||||
comment_post_notif_premod: 'Grazie per il tuo contributo. Il nostro team di moderatori revisionerà presto il tuo commento.'
|
||||
name: Nome
|
||||
post: Invia
|
||||
reply: Rispondi
|
||||
comment_history_blank:
|
||||
info: 'La cronologia dei tuoi commenti apparirà qui'
|
||||
title: 'Non hai pubblicato nessun commento'
|
||||
comment_offensive: 'Questo commento è offensivo'
|
||||
comment_plural: Commenti
|
||||
comment_post_banned_word: 'Il tuo commento contiene una o più parole non permesse, non sarà quindi pubblicato. Se ritieni questo sia un errore, contatta i nostri moderatori.'
|
||||
comment_post_notif: 'Il tuo commento è stato pubblicato.'
|
||||
comment_post_notif_premod: 'Grazie per il tuo contributo. Il nostro team di moderatori revisionerà presto il tuo commento.'
|
||||
comment_singular: Commento
|
||||
common:
|
||||
copy: Copia
|
||||
copied: 'Copiato'
|
||||
notsupported: 'Non supportato'
|
||||
error: 'Si è verificato un errore.'
|
||||
reaction: reazione
|
||||
reactions: reazioni
|
||||
reply: 'rispondi' # noun, singular
|
||||
replies: 'risposte'
|
||||
story: 'Storia'
|
||||
community:
|
||||
account_creation_date: 'Data creazione account'
|
||||
active: Attivo
|
||||
admin: Amministratore
|
||||
ads_marketing: 'Questo sembra essere un annuncio pubblicitario'
|
||||
all: 'Tutti'
|
||||
are_you_sure: 'Sei sicuro di voler bloccare {0}?'
|
||||
ban_user: 'Blocca Utente?'
|
||||
banned: Bloccato
|
||||
banned_user: 'Utente bloccato'
|
||||
cancel: Annulla
|
||||
commenter: Utente
|
||||
dont_like_username: 'Username non adatto'
|
||||
filter_users: 'Filtra utenti'
|
||||
filter_role: Ruolo
|
||||
flaggedaccounts: 'Username segnalati'
|
||||
flags: Segnalazioni
|
||||
impersonating: 'Impersonare'
|
||||
loading: 'Caricamento risultati'
|
||||
moderator: Moderatore
|
||||
newsroom_role: 'Ruolo della sala stampa'
|
||||
no_flagged_accounts: 'Nessun utente segnalato per ora.'
|
||||
no_results: 'Nessun utente con quell''username o indirizzo email trovato.'
|
||||
offensive: Offensivo
|
||||
other: Altro
|
||||
people: Persone
|
||||
role: 'Seleziona ruolo...'
|
||||
select_status: 'Seleziona status...'
|
||||
spam_ads: Spam/pubblicità
|
||||
staff: Staff
|
||||
status: Status
|
||||
suspended: Sospeso
|
||||
username_and_email: 'Username e Email'
|
||||
yes_ban_user: 'Si, blocca utente'
|
||||
configure:
|
||||
access_message: 'Devi essere amministratore per accedere alle configurazioni. Perfavore contatta un amministratore e chiedi di promuoverti!'
|
||||
apply: Applica
|
||||
banned_word_text: 'Commenti che contengono queste parole o frasi, che siano in maiuscolo o minuscolo, saranno automaticamente rimossi. Inserisci una parola e premi Invio o Tab per aggiungerla. Oppure aggiungi una lista di parole separate da virgole.'
|
||||
banned_words_title: 'Lista di parole vietate'
|
||||
close: Chiudi
|
||||
close_after: 'Chiudi commenti successivi'
|
||||
close_stream: 'Chiudi il thread dei commenti'
|
||||
close_stream_configuration: 'Questo thread dei commenti è attualmente chiuso. Aprirlo per visulizzare nuovi commenti'
|
||||
closed_comments_desc: 'Scrivi un messaggio da visualizzare quando il tuo thread dei commenti viene chiuso senza accettarne nuovi.'
|
||||
closed_comments_label: 'Scrivi un messaggio...'
|
||||
closed_stream_settings: 'Thread dei messaggi chiusi'
|
||||
comment_count_error: 'Inserisci un numero valido.'
|
||||
comment_count_header: 'Limite lunghezza commento'
|
||||
comment_count_text_post: caratteri
|
||||
comment_count_text_pre: 'I commenti saranno limitati a'
|
||||
comment_settings: Impostazioni
|
||||
comment_stream: 'Thread dei commenti'
|
||||
comment_stream_will_close: 'Il thread dei commenti sarà chiuso'
|
||||
community: Comunità
|
||||
configure: Configura
|
||||
copy_and_paste: 'Copia e incolla il codice qui sotto nel tuo CMS per includere il box dei commenti nei tuoi articoli'
|
||||
custom_css_url: 'URL per il CSS personalizzato'
|
||||
custom_css_url_desc: 'URL del CSS che sostituirà lo stile predefinito del thread dei commenti. Può essere interno o esterno.'
|
||||
days: Giorni
|
||||
description: 'Modifica le impostazioni dei commenti in questa storia.'
|
||||
disable_commenting_desc: 'Scrivi il messaggio che sarà visualizzato quando i commenti saranno disattivati.'
|
||||
disable_commenting_title: 'Disattiva tutti i commenti del sito'
|
||||
domain_list_text: 'Inserisci i domini che vuoi autorizzare per Talk. Per esempio i tuoi ambienti di sviluppo, test o produzione (ex. localhost:3000 staging.domain.com domain.com).'
|
||||
domain_list_title: 'Domain permessi'
|
||||
edit_comment_timeframe_heading: 'Periodo di tempo disponibile per modificare i commenti'
|
||||
edit_comment_timeframe_text_post: 'secondi per modificare i commenti.'
|
||||
edit_comment_timeframe_text_pre: 'Gli utenti avranno'
|
||||
edit_info: 'Modifica informazioni'
|
||||
embed_comment_stream: 'Integra il thread dei commenti'
|
||||
enable_pre_moderation: 'Abilita pre-moderazione'
|
||||
enable_pre_moderation_text: 'I moderatori dovranno approvare tutti i commenti prima che vengano pubblicati.'
|
||||
enable_premod: 'Abilita pre-moderazione'
|
||||
enable_premod_description: 'I moderatori dovranno approvare tutti i commenti prima che vengano pubblicati.'
|
||||
enable_premod_links: 'Pre-Modera commenti contenenti link'
|
||||
enable_premod_links_description: 'I moderatori devono approvare tutti i commenti contenenti link prima di essere pubblicati.'
|
||||
enable_premod_links_text: 'I moderatori devono approvare tutti i commenti contenenti link prima di essere pubblicati.'
|
||||
enable_questionbox: 'Domanda qualcosa ai lettori'
|
||||
enable_questionbox_description: 'Questa domanda apparirà sopra al thread dei commenti. Chiedi ai lettori cosa ne pensano dell''articolo o poni domande per iniziare una conversazione etc.'
|
||||
hours: Ore
|
||||
include_comment_stream: 'Includi la descrizione del thread dei commenti'
|
||||
include_comment_stream_desc: 'Scrivi un messaggio che sarà aggiunto sopra il thread dei commenti. Poni una domanda, includi le linee guida della comunità etc.'
|
||||
include_question_here: 'Scrivi la tua domanda di seguito:'
|
||||
include_text: 'Includi il testo qui.'
|
||||
moderate: Modera
|
||||
moderation_settings: 'Impostazioni di moderazione'
|
||||
open: Apri
|
||||
open_stream: 'Apri il thread'
|
||||
open_stream_configuration: 'Questo thread dei commenti è attualmente aperto. Chiudendolo non saranno più accettati nuovi commenti, mentre tutti i commenti precedenti continueranno ad essere visibili.'
|
||||
organization_contact_email: 'Indirizzo email dell''organizzazione'
|
||||
organization_info_copy: 'Utilizziamo queste informazioni nelle email di notifica generate da Talk. Questo connette i messaggi alla tua organizzazione, permettendo agli utenti di contattarti se riscontrano problemi con il loro account.'
|
||||
organization_info_copy_2: 'Raccomandiamo di creare un indirizzo email generico (eg. community@yournewsroom.com) per questo scopo. Così da poter rimanere consistente nel tempo, senza rivelare il proprio nome che gli utenti potrebbero prendere di mira nel caso il loro account venga bloccato.'
|
||||
organization_information: 'Informazioni dell''organizzazione'
|
||||
organization_name: 'Nome dell''organizzazione'
|
||||
suspect_or_forbidden_words_placeholder: 'Parola o frase'
|
||||
product_guide_link: 'Guida all''uso del prodotto'
|
||||
report_bug_or_feedback: 'Segnala un bug o lascia un feedback'
|
||||
require_email_verification: 'Richiede la verifica dell''email'
|
||||
require_email_verification_text: 'I nuovi utenti devono verificare la loro email prima di poter commentare'
|
||||
save: Salva
|
||||
save_changes: 'Salva le modifiche'
|
||||
save_changes_dialog:
|
||||
cancel: Annulla
|
||||
copy: 'Hai apportato una o più modifiche senza salvare. Vuoi salvare o scartare le modifiche?'
|
||||
discard: Scarta
|
||||
save_settings: 'Salva impostazioni'
|
||||
unsaved_changes: 'Modifiche non salvate'
|
||||
shortcuts: Scorciatoie
|
||||
sign_out: Esci
|
||||
stories: Storie
|
||||
stream_settings: 'Impostazioni thread dei commenti'
|
||||
suspect_word_text: 'Commenti che contengono queste parole o frasi, che siano in maiuscolo o minuscolo, saranno evidenziate nel thread dei commenti. Inserisci una parola e premi Invio o Tab per aggiungerla. Oppure aggiungi una lista di parole separate da virgole.'
|
||||
suspect_word_title: 'Lista delle parole indiziate'
|
||||
tech_settings: 'Impostazioni tecniche'
|
||||
title: 'Configura il thread dei commenti'
|
||||
view_last_version: 'Visualizza ultima versione'
|
||||
weeks: Settimane
|
||||
wordlist: 'Parole vietate'
|
||||
confirm_email:
|
||||
click_to_confirm: 'Premi qui sotto per confermare il tuo indirizzo email.'
|
||||
confirm: Conferma
|
||||
email_confirmation: 'Conferma Email'
|
||||
continue: Continua
|
||||
createdisplay:
|
||||
check_the_form: 'Modulo non valido. Ricontrolla i campi'
|
||||
continue: 'Continua con lo stesso username di Facebook'
|
||||
error_create: 'Errore nel cambiamento dell''username'
|
||||
fake_comment_body: 'Questo è un commento esempio. I lettori possono condividere i loro pensieri e opinioni con le redazioni nella sezione dei commenti.'
|
||||
fake_comment_date: '1 minuto fa'
|
||||
if_you_dont_change_your_name: 'Se non modifichi il tuo username in questo momento, il tuo nome Facebook comparirà accanto a tutti i tuoi commenti.'
|
||||
required_field: 'Campo obbligatorio'
|
||||
save: Salva
|
||||
special_characters: 'Gli username possono contenere solo lettere numeri e _'
|
||||
username: Username
|
||||
write_your_username: 'Modifica il tuo username'
|
||||
your_username: 'Il tuo username appare in tutti i commenti che pubblichi.'
|
||||
done: Finito
|
||||
edit_comment:
|
||||
body_input_label: 'Modifica questo commento'
|
||||
edit_window_expired: 'Non puoi più modificare questo commento. Il periodo di tempo disponibile per modificarlo è terminato. Perchè non ne pubblichi uno nuovo?'
|
||||
edit_window_expired_close: Chiudi
|
||||
edit_window_timer_prefix: 'Modifica periodo di tempo: '
|
||||
minute: minuto
|
||||
minutes_plural: minuti
|
||||
save_button: 'Salva modifiche'
|
||||
second: secondo
|
||||
seconds_plural: secondi
|
||||
email:
|
||||
banned:
|
||||
body: 'In conformità con le linee guida della comunità The Coral Project, il tuo account è stato bloccato. Non ti è più permesso commentare, segnalare o interagire con la nostra comunità.'
|
||||
subject: 'Il tuo account è stato bloccato'
|
||||
confirm:
|
||||
confirm_email: 'Conferma Email'
|
||||
has_been_requested: 'Una email di conferma è stata richiesta per i seguenti account:'
|
||||
if_you_did_not: 'Se non sei stato tu a richiederla puoi tranquillamente ignorare questa email.'
|
||||
subject: 'Email di conferma'
|
||||
to_confirm: 'Per confermare l''account visita il seguente link:'
|
||||
password_change:
|
||||
body: "La password del tuo account è stata modificata.\n\nSe non sei stato tu a richiedere questa modifica, contattaci a {0}."
|
||||
subject: '{0} password modificata'
|
||||
password_reset:
|
||||
if_you_did: 'Se sei stato tu,'
|
||||
please_click: 'premi qui per reimpostare la password'
|
||||
subject: 'Reimposta Password'
|
||||
we_received_a_request: 'Abbiamo ricevuto una richiesta di reimpostare la password. Se non sei stato tu a richiedere la modifica puoi ignorare questa email.'
|
||||
suspended:
|
||||
subject: 'Il tuo account è stato sospeso'
|
||||
embed_comments_tab: Commenti
|
||||
embedlink:
|
||||
copy: 'Copiato negli appunti'
|
||||
copied: 'Copiato'
|
||||
error:
|
||||
ALREADY_EXISTS: 'Risorsa già esistente'
|
||||
AUTHENTICATION: 'Si è verificato un errore durante il tentativo di autenticazione del tuo account.'
|
||||
CANNOT_IGNORE_STAFF: 'Non puoi ignorare membri dello stuff.'
|
||||
COMMENT_PARENT_NOT_VISIBLE: 'Il commento al quale stai rispondendo è stato rimosso o non esiste.'
|
||||
COMMENT_TOO_SHORT: 'I commenti devono avere più di un carattere, ricontrolla il tuo commento e riprova.'
|
||||
COMMENT_TOO_LONG: 'Il testo eccede il limite permesso.'
|
||||
COMMENTING_CLOSED: 'I commenti sono stati chiusi.'
|
||||
COMMENTING_DISABLED: 'Attualmente non è possibile commentare in questo sito.'
|
||||
confirm_password: 'Le password non coincidono. Perfavore riprova.'
|
||||
DELETION_NOT_SCHEDULED: 'L''eliminazione non è stata pianificata.'
|
||||
EDIT_USERNAME_NOT_AUTHORIZED: 'Non hai l''autorizzazione per modificare il tuo username.'
|
||||
EDIT_WINDOW_ENDED: 'Non puoi più modificare questo commento. Il periodo di tempo disponibile per farlo è terminato.'
|
||||
email: 'Inserisci un indirizzo email valido.'
|
||||
EMAIL_ALREADY_VERIFIED: 'Indirizzo email già verificato.'
|
||||
EMAIL_IN_USE: 'Indirizzo email già in uso.'
|
||||
email_not_verified: 'L''indirizzo email {0} non è verificato.'
|
||||
EMAIL_NOT_VERIFIED: 'Indirizzo email non verificato.'
|
||||
email_password: 'Email e/o password errate/a.'
|
||||
EMAIL_REQUIRED: 'È richiesto un indirizzo email'
|
||||
EMAIL_VERIFICATION_TOKEN_INVALID: 'Il token di verifica dell''e-mail non è valido.'
|
||||
INCORRECT_PASSWORD: 'Password errata'
|
||||
INVALID_ASSET_URL: 'URL non valido'
|
||||
LOGIN_MAXIMUM_EXCEEDED: 'Hai effettuato troppi tentativi falliti. Si prega di attendere.'
|
||||
network_error: 'Errore durante la connessione con il server. Controlla la tua connessione internet e riprova.'
|
||||
NO_SPECIAL_CHARACTERS: 'L''username può contenere solo lettere numeri o _'
|
||||
NOT_AUTHORIZED: 'Non sei autorizzato a compiere questa azione.'
|
||||
NOT_FOUND: 'Risorsa non trovata'
|
||||
organization_contact_email: 'L''email dell''organizzazione è invalida.'
|
||||
organization_name: 'Il nome dell''organizzazione può contenere solo lettere o numeri.'
|
||||
password: 'La password deve avere almeno 8 caratteri'
|
||||
PAGE_NOT_AVAILABLE_ROLE: 'Questa pagina può essere utilizzata solo dal team. Contatta l''amministratore se vuoi entrare a far parte di questo team.'
|
||||
PASSWORD_INCORRECT: 'La password inserita non è corretta'
|
||||
PASSWORD_LENGTH: 'La password è troppo corta'
|
||||
PASSWORD_REQUIRED: 'Inserire una password'
|
||||
PASSWORD_RESET_TOKEN_INVALID: 'Il link per reimpostare la tua password non è valido.'
|
||||
PROFANITY_ERROR: 'Gli username non devono contenere volgarità. Contatta l''amministratore se ritieni ci sia stato un errore.'
|
||||
RATE_LIMIT_EXCEEDED: 'Limite di tentativi superato'
|
||||
required_field: 'Questo campo è obbligatorio'
|
||||
SAME_USERNAME_PROVIDED: 'Devi inserire un username diverso.'
|
||||
temporarily_suspended: 'Il tuo account è attualmente sospeso. Sarà riattivato {0}. Contattaci se hai qualche domanda.'
|
||||
unexpected: 'Si è verificato un errore imprevisto. Ci scusiamo!'
|
||||
username: 'L''username può contenere solo lettere numeri o _'
|
||||
USERNAME_IN_USE: 'Username già in uso'
|
||||
USERNAME_REQUIRED: 'Inserire un username'
|
||||
flag_comment: 'Segnala commento'
|
||||
flag_reason: 'Motivi segnalazione (Opzionale)'
|
||||
flag_reasons:
|
||||
username:
|
||||
impersonating: 'Questo utente sta impersonando'
|
||||
nolike: 'Non mi piace il suo username'
|
||||
offensive: 'Username offensivo'
|
||||
other: Altro
|
||||
spam: 'Sembra si tratti di pubblicità/marketing'
|
||||
flag_username: 'Segnala username'
|
||||
flagged_usernames:
|
||||
notify_approved: '{0} username approvato {1}'
|
||||
notify_changed: 'utente {0} ha cambiato il suo username in {1}'
|
||||
notify_flagged: '{0} ha segnalato l''username {1}'
|
||||
notify_rejected: '{0} ha rifiutato l''username {1}'
|
||||
flags:
|
||||
reasons:
|
||||
comment:
|
||||
banned_word: 'Parola vietata'
|
||||
comment_noagree: Disaccordo
|
||||
comment_offensive: Offensivo
|
||||
comment_other: Altro
|
||||
comment_spam: Spam
|
||||
links: Link
|
||||
suspect_word: 'Parola sospetta'
|
||||
trust: Karma
|
||||
user:
|
||||
username_impersonating: Impersonificazione
|
||||
username_nolike: 'Non mi piace'
|
||||
username_offensive: Offensivo
|
||||
username_other: Altro
|
||||
username_spam: Spam
|
||||
framework:
|
||||
banned_account_body: 'Significa che non potrai votare, segnalare o scrivere commenti.'
|
||||
banned_account_header: 'Il tuo account è attualmente bloccato.'
|
||||
changed_name:
|
||||
msg: 'Il tuo nuovo username è sotto esame da parte del nostro team di moderatori.'
|
||||
comment: commento
|
||||
comment_is_deleted: 'Questo utente ha eliminato il suo account.'
|
||||
comment_is_hidden: 'Questo commento non è disponibile.'
|
||||
comment_is_ignored: 'Questo commento è nascosto perchè hai ignorato questo utente.'
|
||||
comment_is_rejected: 'Hai rifiutato questo commento.'
|
||||
comments: commenti
|
||||
configure_stream: Configura
|
||||
content_not_available: 'Questo contenuto non è disponibile'
|
||||
edit_name:
|
||||
button: Invia
|
||||
error: 'L''username può contenere solo lettere numeri o _'
|
||||
label: 'Nuovo username'
|
||||
msg: 'Il tuo account è attualmente sospeso perchè il tuo username è considerato inappropriato. Per ripristinare il tuo account inserisci un nuovo username. Contattaci se hai qualche domanda.'
|
||||
my_comments: 'I miei commenti'
|
||||
my_profile: 'Il mio profilo'
|
||||
new_count: 'Visualizza {0} e {1}'
|
||||
profile: Profilo
|
||||
show_all_comments: 'Visualizza tutti i commenti'
|
||||
show_all_replies: 'Visualizza tutte le risposte'
|
||||
show_more_replies: 'Visualizza più risposte'
|
||||
success_bio_update: 'La tua descrizione è stata aggiornata'
|
||||
success_name_update: 'Il tuo username è stato aggiornato'
|
||||
success_update_settings: 'Le modifiche apportate sono state applicate al thread dei commenti in questo articolo'
|
||||
view_more_comments: 'visualizza più commenti'
|
||||
view_reply: 'visualizza risposta'
|
||||
from_settings_page: 'Dalla pagina del profilo puoi vedere la tua cronologia dei commenti.'
|
||||
install:
|
||||
add_organization:
|
||||
description: 'Inserisci il nome della tua organizzazione. Questa apparirà nelle email di invito ai nuovi membri.'
|
||||
label: 'Nome dell''organizzazione'
|
||||
save: Salva
|
||||
create:
|
||||
confirm_password: 'Conferma password'
|
||||
email: 'Indirizzo email'
|
||||
organization_contact_email: 'Indirizzo email dell''organizzazione'
|
||||
password: Password
|
||||
save: Salva
|
||||
username: Username
|
||||
final:
|
||||
close: 'Chiudi l''installer'
|
||||
description: 'Grazie per aver installato Talk! Ti abbiamo inviato una email per verificare il tuo indirizzo email. Mentre termini la configurazione del tuo account, puoi iniziare a interagire con i tuoi lettori.'
|
||||
launch: 'Avvia Talk'
|
||||
initial:
|
||||
description: 'Configura la tua comunità Talk in pochi passi.'
|
||||
submit: Inizia
|
||||
permitted_domains:
|
||||
description: 'Inserisci i domini che vuoi autorizzare per Talk. Per esempio i tuoi ambienti di sviluppo, test o produzione (ex. localhost:3000 staging.domain.com domain.com).'
|
||||
submit: 'Termina installazione'
|
||||
title: 'Domini autorizzati'
|
||||
like: 'Mi piace'
|
||||
loading_results: 'Caricamento risultati'
|
||||
login:
|
||||
email_address: 'Indirizzo email'
|
||||
forgot_password: 'Hai dimenticato la tua password?'
|
||||
go_back: Indietro
|
||||
sign_in: Accedi
|
||||
sign_in_button: Accedi
|
||||
sign_in_message: 'Accedi per interagire con la comunità.'
|
||||
password: Password
|
||||
reset_password_send_button: 'Reimposta Password'
|
||||
request_passowrd: 'Richiedi una nuova password.'
|
||||
team_sign_in: 'Accesso Team'
|
||||
marketing: 'Sembra si tratti di pubblicità/marketing'
|
||||
moderate_all_streams: 'Modera i commenti in Tutte le storie'
|
||||
moderate_this_stream: 'Modera questo thread dei commenti'
|
||||
modqueue:
|
||||
account: 'segnalazioni dell''account'
|
||||
actions: Azioni
|
||||
all: tutto
|
||||
all_streams: 'Tutti i thread di commenti'
|
||||
approve: Approva
|
||||
approved: Approvato
|
||||
ban_user: Bloccato
|
||||
ban_user_actions: 'Blocca utente'
|
||||
billion: M
|
||||
close: Chiudi
|
||||
empty_queue: 'Non ci sono più commenti da moderare.'
|
||||
flagged: contrassegnato
|
||||
jump_to_queue: 'Vai a una determinata coda'
|
||||
less_detail: 'Meno dettagli'
|
||||
likes: 'mi piace'
|
||||
million: m
|
||||
mod_faster: 'Modera più velocemente con le scorciatoie da tastiera'
|
||||
moderate: 'Modera →'
|
||||
more_detail: 'Più dettagli'
|
||||
navigation: Navigazione
|
||||
new: Nuovo
|
||||
newest_first: 'Nuovo primo'
|
||||
next_comment: 'Vai al prossimo commento'
|
||||
next_queue: 'Cambia coda'
|
||||
notify_accepted: '{0} ha accettato il commento "{1}"'
|
||||
notify_edited: '{0} ha modificato il commento "{1}"'
|
||||
notify_flagged: '{0} ha contrassegnato il commento "{1}"'
|
||||
notify_rejected: '{0} ha rifiutato il commento "{1}"'
|
||||
notify_reset: '{0} ha ripristinato lo stato del commento "{1}"'
|
||||
oldest_first: 'Primo più vecchio'
|
||||
premod: pre-moderazione
|
||||
prev_comment: 'Vai al commento precedente'
|
||||
reject: Rifiuta
|
||||
rejected: Rifiutato
|
||||
reply: Rispondi
|
||||
reported: Segnalato
|
||||
select_stream: 'Seleziona thread dei commenti'
|
||||
shift_key: ⇧
|
||||
shortcuts: Scorciatoie
|
||||
show_shortcuts: 'Visualizza scorciatoie'
|
||||
singleview: 'Modalità zen'
|
||||
sort: Ordina
|
||||
suspend: 'Sospendi utente'
|
||||
system_withheld: 'Sistema bloccato'
|
||||
thismenu: 'Apri questo menu'
|
||||
thousand: k
|
||||
toggle_search: 'Apri ricerca'
|
||||
try_these: 'Prova queste'
|
||||
view_more_shortcuts: 'Visualizza più scorciatoie'
|
||||
my_comment_history: 'La mia cronologia di commenti'
|
||||
name: Nome
|
||||
no_agree_comment: 'Non concordo con questo commento'
|
||||
no_like_bio: 'Non apprezzo questa descrizione'
|
||||
no_like_username: 'Non apprezzo questo username'
|
||||
other: Altro
|
||||
password_reset:
|
||||
change_password: 'Cambia password'
|
||||
change_password_help: 'Inserisci una nuova password per accedere'
|
||||
confirm_new_password: 'Conferma la nuova password'
|
||||
mail_sent: 'Se hai già un account ti è stata inviata una email con un link per reimpostare la password'
|
||||
new_password: 'Nuova password'
|
||||
new_password_help: 'La password deve avere almeno 8 caratteri'
|
||||
set_new_password: 'Cambia la tua password'
|
||||
permalink: Condividi
|
||||
personal_info: 'Questo commento contiene dati personali'
|
||||
post: Pubblica
|
||||
profile: Profilo
|
||||
profile_settings: Impostazioni
|
||||
reject_username:
|
||||
description_notify: 'La sospensione di questo utente disabiliterà temporaneamente il loro account.'
|
||||
description_reject: 'Sei sicuro di volere bloccare temporaneamente questo utente perchè {0}? Accettando sospenderai temporaneamente questo utente finché non riscriveranno il loro {0}.'
|
||||
email_message_reject: 'Un''altro membro della comunità ha recentemente segnalato il tuo username consigliando una revisione. A causa del suo contenuto, il tuo username è stato rifiutato. Significa che non potrai più commentare, apprezzare o segnalare contenuti fino a quando non modificherai il tuo username. Inviaci una email per qualsiasi domanda o dubbio.'
|
||||
no_cancel: 'Non annullare'
|
||||
send: Invia
|
||||
suspend_user: 'Sospendi utente'
|
||||
title_notify: 'Avvisa l''utente della sua temporanea sospensione'
|
||||
title_reject: 'Abbiamo notato che hai rifiutato un nome utente'
|
||||
username: username
|
||||
write_message: 'Scrivi un messaggio'
|
||||
yes_suspend: 'Si, sospendi'
|
||||
reject_username_dialog:
|
||||
cancel: Annulla
|
||||
description: 'Aiutaci a capire'
|
||||
message: 'Motivi per la segnalazione (Opzionale)'
|
||||
reason: Ragione
|
||||
reject_username: 'Rifiuta username'
|
||||
title: 'Rifiuta username'
|
||||
reply: Rispondi
|
||||
report: Segnala
|
||||
report_notif: 'Grazie per aver segnalato questo commento. Il nostro team di moderatori è stato avvisato e lo revisionerà presto.'
|
||||
report_notif_remove: 'La tua segnalazione è stata rimossa.'
|
||||
reported: Segnalato
|
||||
settings:
|
||||
from_settings_page: 'Dalla pagina del profilo puoi vedere la tua cronologia dei commenti.'
|
||||
my_comment_history: 'La mia cronologia dei commenti'
|
||||
profile: Profilo
|
||||
profile_settings: 'Impostazioni profilo'
|
||||
sign_in: Accedi
|
||||
to_access: 'per accedere al profilo'
|
||||
user_no_comment: 'Non hai ancora pubblicato un commento. Partecipa alla conversazione!'
|
||||
step_1_header: 'Segnala un problema'
|
||||
step_2_header: 'Aiutaci a capire'
|
||||
step_3_header: 'Grazie per la tua partecipazione'
|
||||
stream:
|
||||
all_comments: 'Tutti i commenti'
|
||||
comment_not_found: 'Questo commento è stato rimosso o non esiste.'
|
||||
no_comments: 'Non ci sono ancora commenti. Perchè non ne pubblichi uno?'
|
||||
no_comments_and_closed: 'Non c''era alcun commento in questo articolo.'
|
||||
temporarily_suspended: 'In conformità con le linee guida della comunità {0}, il tuo account è stato temporaneamente sospeso. Torna a partecipare alla conversazione {1}.'
|
||||
streams:
|
||||
all: Tutti
|
||||
article: Storia
|
||||
closed: Chiuso
|
||||
empty_result: 'Questa ricerca non ha ottenuto risultati. Prova ad amplicare la tua ricerca.'
|
||||
filter_streams: 'Filtra i thread dei commenti'
|
||||
most_recent_stories: 'Storie più recenti'
|
||||
newest: Nuovi
|
||||
no_results: 'Nessun risultato'
|
||||
oldest: Vecchi
|
||||
open: Apri
|
||||
pubdate: 'Data di pubblicazione'
|
||||
search: Cerca
|
||||
search_results: 'Risultati della ricerca'
|
||||
sort_by: 'Ordina per'
|
||||
status: 'Status del thread dei commenti'
|
||||
stream_status: 'Status del thread dei commenti'
|
||||
suspenduser:
|
||||
cancel: Annulla
|
||||
day: '{0} giorno'
|
||||
days: '{0} giorni'
|
||||
description_notify: 'La sospensione di questo utente disabiliterà temporaneamente il loro account.'
|
||||
description_suspend: 'Stai sospendendo {0}. Questo commento sarà inserito tra quelli rifiutati, e {0} non potrà apprezzare, segnalare, rispondere o pubblicare fino al termine del periodo di sospensione.'
|
||||
email_message_suspend: "Caro {0},\n\nIn conformità con le linee guida della comunità, il tuo account è stato temporaneamente sospenso. Durante il periodo di sospension non potrai commentare, segnalare o interagire con la comunità. Puoi tornare a partecipare dal {2}."
|
||||
hour: '{0} ora'
|
||||
hours: '{0} ore'
|
||||
notify_suspend_until: 'L''utente {0} è stato temporaneamente sospeso. Questa sospensione finirà automaticamente {1}.'
|
||||
one_hour: '1 ora'
|
||||
select_duration: 'Seleziona la durata della sospensione'
|
||||
send: Invia
|
||||
suspend_user: 'Sospendi utente'
|
||||
title_notify: 'Avvisa l''utente della sua temporanea sospensione'
|
||||
title_suspend: 'Sospendi utente'
|
||||
write_message: 'Scrivi un messaggio'
|
||||
thank_you: 'Apprezziamo il tuo feedback. Un moderatore revisionerà la tua segnalazione.'
|
||||
user:
|
||||
bio_flags: 'segnalazioni per questa descrizione'
|
||||
user_bio: 'Descrizione utente'
|
||||
username_flags: 'segnalazioni per questo utente'
|
||||
user_detail:
|
||||
all: Tutti
|
||||
ban: 'Blocca utente'
|
||||
banned: Bloccato
|
||||
email: Email
|
||||
id: ID
|
||||
karma: Karma
|
||||
karma_docs_link: 'https://docs.coralproject.net/talk/trust/#user-karma-score'
|
||||
learn_more: 'Maggiori informazioni'
|
||||
member_since: 'Membro dal'
|
||||
reject_rate: 'Tasso di rifiuto'
|
||||
reject_username: 'Username rifiutato'
|
||||
rejected: Rifiutato
|
||||
remove_ban: 'Ban rimosso'
|
||||
remove_suspension: 'Sospensione rimossa'
|
||||
suspend: 'Utente sospeso'
|
||||
suspended: Sospeso
|
||||
total_comments: 'Commenti totali'
|
||||
unreliable: Inaffidabile
|
||||
user_history: 'Cronologia utente'
|
||||
user_karma_score: 'Punteggio Karma dell''utente'
|
||||
username: Username
|
||||
username_needs_approval: 'L''username necessita di approvazione'
|
||||
username_rejected: 'Username rifiutato'
|
||||
user_history:
|
||||
action: Azione
|
||||
ban_removed: 'Ban rimosso'
|
||||
date: Data
|
||||
suspended: 'Sospeso, {0}'
|
||||
suspension_removed: 'Sospensione rimossa'
|
||||
system: Sistema
|
||||
taken_by: 'Preso da'
|
||||
user_banned: 'Utente bloccato'
|
||||
username_status: 'Username {0}'
|
||||
user_impersonating: 'Questo utente sta impersonando'
|
||||
user_no_comment: 'Non hai ancora pubblicato un commento. Partecipa alla discussione!'
|
||||
username_offensive: 'Questo username è offensivo'
|
||||
validators:
|
||||
confirm_email: 'Le email non coincidono. Perfavore riprova.'
|
||||
confirm_password: 'Le password non coincidono. Perfavore riprova.'
|
||||
required: 'Questo campo è obbligatorio'
|
||||
verify_email: 'Inserisci un email valida.'
|
||||
verify_organization_name: 'Il nome dell''organizzazione può contenere solo lettere o numeri.'
|
||||
verify_password: 'La password deve contenere almeno 8 caratteri'
|
||||
verify_username: 'Gli username possono contenere solo lettere numeri e _'
|
||||
view_conversation: 'Visualizza conversazione'
|
||||
your_account_has_been_banned: 'Il tuo account è stato bloccato.'
|
||||
your_account_has_been_suspended: 'Il tuo account è stato temporaneamente sospeso.'
|
||||
your_username_has_been_rejected: 'Il tuo account è stato sospeso perchè il tuo username è ritenuto inappropriato. Per ripristinare il tuo account inserisci un nuovo username.'
|
||||
+3
-3
@@ -123,8 +123,8 @@ nl_NL:
|
||||
enable_questionbox: 'Stel een vraag aan de lezers'
|
||||
enable_questionbox_description: 'Deze vraag zal bovenaan de conversatie verschijnen. Vraag lezers naar een probleem in het artikel, poneer discussie vragen, enzovoort.'
|
||||
hours: Uren
|
||||
include_comment_stream: 'Neem conversatie beschrijving op voor lezers.'
|
||||
include_comment_stream_desc: 'Schrijf een bericht voor boven je conversatie. Poneer een stelling, wijs op de community richtlijnen, etc.'
|
||||
code_of_conduct_summary: 'Neem conversatie beschrijving op voor lezers.'
|
||||
code_of_conduct_summary_desc: 'Schrijf een bericht voor boven je conversatie. Poneer een stelling, wijs op de community richtlijnen, etc.'
|
||||
include_question_here: 'Schrijf je vraag hier:'
|
||||
include_text: 'Schrijf hier je tekst.'
|
||||
moderate: Modereer
|
||||
@@ -197,6 +197,7 @@ nl_NL:
|
||||
CANNOT_IGNORE_STAFF: 'Kan geen Staff-leden negeren.'
|
||||
COMMENT_PARENT_NOT_VISIBLE: 'De reactie waarop je probeert te reageren bestaat niet of is inmiddels verwijderd.'
|
||||
COMMENT_TOO_SHORT: 'Reacties moeten meer dan één teken hebben. Herzie je reactie en probeer opnieuw.'
|
||||
COMMENT_TOO_LONG: 'Tekst is te lang'
|
||||
COMMENTING_CLOSED: 'Reageren is al afgesloten.'
|
||||
confirm_password: 'Wachtwoorden komen niet overeen. Controleer opnieuw.'
|
||||
EDIT_USERNAME_NOT_AUTHORIZED: 'Je bent niet gemachtigd om je gebruikersnaam te wijzigen.'
|
||||
@@ -239,7 +240,6 @@ nl_NL:
|
||||
reasons:
|
||||
comment:
|
||||
banned_word: 'Geblokeerd woord'
|
||||
body_count: 'Tekst is te lang'
|
||||
comment_noagree: 'Niet eens'
|
||||
comment_offensive: Aanstootgevend
|
||||
comment_other: Anders
|
||||
|
||||
+77
-9
@@ -38,6 +38,9 @@ pt_BR:
|
||||
name: Nome
|
||||
post: Enviar
|
||||
reply: Responder
|
||||
comment_history_blank:
|
||||
info: 'Uma história de seus comentários irá aparecer aqui'
|
||||
title: 'Você não escreveu nenhum comentário'
|
||||
comment_offensive: 'Este comentário é ofensivo'
|
||||
comment_plural: Comentários
|
||||
comment_post_banned_word: 'Seu comentário não foi publicado porque contém conteúdo inadequado.'
|
||||
@@ -83,6 +86,7 @@ pt_BR:
|
||||
username_and_email: 'Nome de usuário e email'
|
||||
yes_ban_user: 'Sim, banir este usuário'
|
||||
configure:
|
||||
access_message: 'Você deve ser um administrador para acessar as configurações. Por favor procure o administrador mais próximo e solicite acesso.’'
|
||||
apply: Aplicar
|
||||
banned_word_text: 'Os comentários que contenham essas palavras ou frases (não sensíveis a maiúsculas e minúsculas) serão automaticamente removidos da lista de comentários. Digite uma palavra e pressione Enter ou Tab para adicionar ou cole uma lista separada por vírgulas.'
|
||||
banned_words_title: 'Lista de palavras proibidas'
|
||||
@@ -126,8 +130,8 @@ pt_BR:
|
||||
enable_questionbox: 'Faça uma pergunta aos leitores'
|
||||
enable_questionbox_description: 'Esta pergunta aparecerá no topo da lista de comentários. Pergunte aos leitores sobre um determinado problema no artigo, abra o assunto para discussão, etc.'
|
||||
hours: Horas
|
||||
include_comment_stream: 'Incluir descrição da lista comentários para leitores'
|
||||
include_comment_stream_desc: 'Escreva uma mensagem para adicionar ao topo do seu hilo de comentários. Posicionar um tópico, incluem diretrizes comunitárias, etc.'
|
||||
code_of_conduct_summary: 'Incluir descrição da lista comentários para leitores'
|
||||
code_of_conduct_summary_desc: 'Escreva uma mensagem para adicionar ao topo do seu hilo de comentários. Posicionar um tópico, incluem diretrizes comunitárias, etc.'
|
||||
include_question_here: 'Escreva sua pergunta aqui:'
|
||||
include_text: 'Inclua seu texto aqui:'
|
||||
moderate: Moderar
|
||||
@@ -140,11 +144,19 @@ pt_BR:
|
||||
organization_info_copy_2: 'Recomendamos a criação de uma conta de e-mail genérica (por exemplo, comunidade@suaredacao.com) para essa finalidade. Isso significa que ele pode permanecer consistente ao longo do tempo e não expor um nome que os usuários pudessem segmentar se a conta fosse bloqueada.'
|
||||
organization_information: 'Informações da Organização'
|
||||
organization_name: 'Nome da Organização'
|
||||
suspect_or_forbidden_words_placeholder: 'Palavra ou frase'
|
||||
product_guide_link: 'Guia do Produto'
|
||||
report_bug_or_feedback: 'Relatar bug ou dar um feedback'
|
||||
require_email_verification: 'Requerer verificação de email'
|
||||
require_email_verification: 'Solicitar verificação de email'
|
||||
require_email_verification_text: 'Novos usuários devem verificar seu e-mail antes de comentar'
|
||||
save: Salvar
|
||||
save_changes: 'Salvar alterações'
|
||||
save_changes_dialog:
|
||||
cancel: Cancelar
|
||||
copy: 'Você fez uma ou mais alterações sem salvar. Gostaria de salvar ou descartar suas alterações?'
|
||||
discard: Discartar
|
||||
save_settings: 'Configurações salvas'
|
||||
unsaved_changes: 'Alterações não salvas'
|
||||
shortcuts: Atalhos
|
||||
sign_out: Sair
|
||||
stories: Histórias
|
||||
@@ -159,6 +171,7 @@ pt_BR:
|
||||
confirm_email:
|
||||
click_to_confirm: 'Clique abaixo para confirmar seu endereço de email'
|
||||
confirm: Confirmar
|
||||
email_confirmation: 'Confirmação de E-mail'
|
||||
continue: Continuar
|
||||
createdisplay:
|
||||
check_the_form: 'Formulário inválido. Verifique as entradas do formulário.'
|
||||
@@ -194,45 +207,60 @@ pt_BR:
|
||||
if_you_did_not: 'Se você não solicitou isso, você pode ignorar este e-mail.'
|
||||
subject: 'Confirmação de e-mail'
|
||||
to_confirm: 'Para confirmar a conta, visite este link: '
|
||||
password_change:
|
||||
body: "A sua senha foi alterada.\n\nSe você não solicitou essa alteracão, por favor nos contate em {0}"
|
||||
subject: '{0} password change'
|
||||
password_reset:
|
||||
if_you_did: 'Se você solicitou isso, '
|
||||
please_click: 'clique aqui para redefinir sua senha.'
|
||||
subject: 'Alteracao de Senha'
|
||||
we_received_a_request: 'Recebemos um pedido para redefinir sua senha. Se você não solicitou esta alteração, pode ignorar este e-mail.'
|
||||
suspended:
|
||||
subject: 'Sua conta foi suspensa'
|
||||
embed_comments_tab: Comentários
|
||||
embedlink:
|
||||
copy: 'Copiar para área de transferência'
|
||||
copy: 'Copiar conteúdo'
|
||||
copied: 'Copiado'
|
||||
error:
|
||||
ALREADY_EXISTS: 'O recurso já existe'
|
||||
AUTHENTICATION: ‘Ocorreu um erro durante a autenticação da sua conta’
|
||||
CANNOT_IGNORE_STAFF: 'Não é possível ignorar membros Staff.'
|
||||
COMMENT_PARENT_NOT_VISIBLE: 'O comentário que você está respondendo foi removido ou não existe.'
|
||||
COMMENT_TOO_SHORT: 'Seu comentário precisar ter mais de um caracter. Revise seu comentário e envie novamente'
|
||||
COMMENTING_CLOSED: 'Os comentários já estão fechados.'
|
||||
COMMENTING_DISABLED: 'Commenting is currently disabled on this site'
|
||||
confirm_password: 'Suas senhas não coincidem. Por favor, tente novamente.'
|
||||
DELETION_NOT_SCHEDULED: 'Deletion was not scheduled'
|
||||
EDIT_USERNAME_NOT_AUTHORIZED: 'Você não tem permissão para revisar seu nome de usuário.'
|
||||
EDIT_WINDOW_ENDED: 'Você não pode mais editar esse comentário. O tempo expirou.'
|
||||
email: 'Não é um e-mail válido'
|
||||
EMAIL_ALREADY_VERIFIED: 'Endereço de e-mail já verificado '
|
||||
EMAIL_IN_USE: 'Endereço de e-mail já está em uso.'
|
||||
email_not_verified: 'O endereço de e-mail {0} não é verificado.'
|
||||
EMAIL_NOT_VERIFIED: 'E-mail não verificado'
|
||||
email_password: 'Combinação de e-mail e/ou senha incorreta.'
|
||||
EMAIL_REQUIRED: 'É necessário o endereço de e-mail.'
|
||||
EMAIL_VERIFICATION_TOKEN_INVALID: 'O token de verificação do email é inválido.'
|
||||
INCORRECT_PASSWORD: 'Incorrect Password'
|
||||
INVALID_ASSET_URL: 'O URL do recurso é inválido'
|
||||
LOGIN_MAXIMUM_EXCEEDED: 'Você fez muitas tentativas de senha mal sucedidas. Espere alguns instantes.'
|
||||
network_error: 'Falha ao conectar-se ao servidor. Verifique a sua conexão com a internet e tente novamente.'
|
||||
NO_SPECIAL_CHARACTERS: 'Nomes de usuários podem conter números de letras e _ somente'
|
||||
NOT_AUTHORIZED: 'Você não está autorizado a executar esta ação.'
|
||||
NOT_FOUND: 'Recurso não encontrado'
|
||||
organization_contact_email: 'O Email da organização não é válido.'
|
||||
organization_name: 'O nome da organização só deve conter letras ou números.'
|
||||
password: 'A senha deve conter pelo menos 8 caracteres'
|
||||
PAGE_NOT_AVAILABLE_ROLE: 'Essa página só pode ser acessada para uso do time. Por favor entre em contato com um administrador caso queira fazer parte desse time.'
|
||||
PASSWORD_INCORRECT: 'A senha inserida está incorreta'
|
||||
PASSWORD_LENGTH: 'A senha é muito curta'
|
||||
PASSWORD_REQUIRED: 'Você deve inserir uma senha.'
|
||||
PASSWORD_RESET_TOKEN_INVALID: 'Seu link de redefinição de senha é inválido.'
|
||||
PROFANITY_ERROR: 'Os nomes de usuários não devem conter palavrões. Entre em contato com o administrador se você acredita que isso seja incorreto.'
|
||||
RATE_LIMIT_EXCEEDED: 'Tentativas excedidas'
|
||||
required_field: 'Esse campo é obrigatório'
|
||||
SAME_USERNAME_PROVIDED: 'Você deve enviar um nome de usuário diferente.'
|
||||
temporarily_suspended: 'Sua conta está suspensa. Ela será reativada {0}. Por favor entre em contato caso tenha dúvidas.'
|
||||
unexpected: 'Ocorreu um erro inesperado. Desculpa!'
|
||||
username: 'Nomes de usuários podem conter números de letras e _ somente'
|
||||
USERNAME_IN_USE: 'Nome de usuário já em uso'
|
||||
@@ -246,6 +274,7 @@ pt_BR:
|
||||
changed_name:
|
||||
msg: 'Sua alteração de nome de usuário está sendo analisada por nossa equipe de moderação.'
|
||||
comment: comentário
|
||||
comment_is_deleted: 'This commenter has deleted their account.'
|
||||
comment_is_hidden: 'Este comentário não está disponível.'
|
||||
comment_is_ignored: 'Este comentário está oculto porque você ignorou esse usuário.'
|
||||
comment_is_rejected: 'Você rejeitou este comentário.'
|
||||
@@ -303,6 +332,7 @@ pt_BR:
|
||||
sign_in_button: 'Entrar'
|
||||
sign_in_message: 'Entre para interagir com a comunidade.'
|
||||
password: Senha
|
||||
reset_password_send_button: 'Recuperar Senha'
|
||||
request_passowrd: 'Recupere-a clicando aqui.'
|
||||
team_sign_in: 'Team sign in'
|
||||
marketing: 'Isso parece um anúncio/marketing'
|
||||
@@ -316,6 +346,7 @@ pt_BR:
|
||||
approve: Aprovar
|
||||
approved: Aprovado
|
||||
ban_user: Banir
|
||||
ban_user_actions: 'Banir Usuário'
|
||||
billion: B
|
||||
close: Fechar
|
||||
empty_queue: 'Não há mais comentários para moderar! Aproveite para relaxar e esticar as pernas'
|
||||
@@ -336,6 +367,7 @@ pt_BR:
|
||||
notify_edited: '{0} editou o comentário "{1}"'
|
||||
notify_flagged: '{0} marcou o comentário "{1}"'
|
||||
notify_rejected: '{0} rejeitou o comentário "{1}"'
|
||||
notify_reset: '{0} resetar status do comentário "{1}"'
|
||||
oldest_first: 'Mais velhos primeiro'
|
||||
premod: pré-moderação
|
||||
prev_comment: 'Vá para o comentário anterior'
|
||||
@@ -349,6 +381,8 @@ pt_BR:
|
||||
show_shortcuts: 'Ver atalhos'
|
||||
singleview: 'Modo zen'
|
||||
sort: Ordenar
|
||||
suspend: 'Suspender Usuário'
|
||||
system_withheld: 'Sistema de Rejeição'
|
||||
thismenu: 'Abra este menu'
|
||||
thousand: k
|
||||
toggle_search: 'Abrir busca'
|
||||
@@ -362,7 +396,9 @@ pt_BR:
|
||||
other: Outro
|
||||
password_reset:
|
||||
change_password: 'Alterar senha'
|
||||
change_password_help: 'Please enter a new password to use to login. Make it secure!'
|
||||
confirm_new_password: 'Confirmar nova senha'
|
||||
mail_sent: 'Se você tem uma conta registrada, um link para alterar sua senha foi enviado para o e-mail informado'
|
||||
new_password: 'Nova senha'
|
||||
new_password_help: 'A senha deve ter mais de 8 caracteres'
|
||||
set_new_password: 'Alterar sua senha'
|
||||
@@ -383,6 +419,13 @@ pt_BR:
|
||||
username: 'nome de usuário'
|
||||
write_message: 'Escreve uma mensagem'
|
||||
yes_suspend: 'Sim suspender'
|
||||
reject_username_dialog:
|
||||
cancel: Cancel
|
||||
description: 'Nos ajude a entender'
|
||||
message: 'Motivo para reportar (Opcional)'
|
||||
reason: Motivo
|
||||
reject_username: 'Rejeitar nome de Usuário'
|
||||
title: 'Rejeitar nome de Usuário'
|
||||
reply: Responder
|
||||
report: Denunciar
|
||||
report_notif: 'Obrigado por denunciar este comentário. Nossa equipe de moderação foi notificada e irá revisá-la em breve.'
|
||||
@@ -398,7 +441,7 @@ pt_BR:
|
||||
user_no_comment: 'Você nunca deixou um comentário. Participe da conversa!'
|
||||
step_1_header: 'Relatar um problema'
|
||||
step_2_header: 'Ajude-nos a entender'
|
||||
step_3_header: 'Obrigdo por sua contribuição'
|
||||
step_3_header: 'Obrigado por sua contribuição'
|
||||
stream:
|
||||
all_comments: 'Todos os comentários'
|
||||
comment_not_found: 'Este comentário foi removido ou não existe.'
|
||||
@@ -406,16 +449,16 @@ pt_BR:
|
||||
no_comments_and_closed: 'Não houve comentários sobre este artigo.'
|
||||
temporarily_suspended: 'De acordo com as diretrizes da comunidade de {0}, sua conta foi temporariamente suspensa. Por favor, volte para a conversa {1}.'
|
||||
streams:
|
||||
all: Todos
|
||||
all: Todas
|
||||
article: História
|
||||
closed: Fechado
|
||||
closed: Fechada
|
||||
empty_result: 'Nenhum resultado encontrado para esta pesquisa. Que tal refazer a pesquisa com termos diferentes?'
|
||||
filter_streams: 'Filtra as listas'
|
||||
most_recent_stories: 'Matérias mais recentes'
|
||||
newest: 'O mais novo'
|
||||
no_results: 'No results'
|
||||
no_results: 'Nenhum resultado'
|
||||
oldest: 'O mais velho'
|
||||
open: Aberto
|
||||
open: Aberta
|
||||
pubdate: 'Data de publicação'
|
||||
search: Pesquisar
|
||||
search_results: 'Pesquisar Resultados'
|
||||
@@ -442,11 +485,36 @@ pt_BR:
|
||||
bio_flags: 'Marcadas para este perfil'
|
||||
user_bio: 'Perfil do usuário'
|
||||
username_flags: 'Marcadas para este usuário'
|
||||
user_detail:
|
||||
all: Todo
|
||||
ban: 'Banir usuário'
|
||||
banned: Banido
|
||||
email: Email
|
||||
id: ID
|
||||
karma: Karma
|
||||
karma_docs_link: 'https://docs.coralproject.net/talk/trust/#user-karma-score'
|
||||
learn_more: 'Saiba Mais'
|
||||
member_since: 'Membro desde'
|
||||
reject_rate: 'Taxa de rejeição'
|
||||
reject_username: 'Rejeitar Usuário'
|
||||
rejected: Rejeitado
|
||||
remove_ban: 'Remover Bloqueio'
|
||||
remove_suspension: 'Remover Suspensão'
|
||||
suspend: 'Suspender Ususário'
|
||||
suspended: Suspenso
|
||||
total_comments: 'Total de comentários'
|
||||
unreliable: Não confiável
|
||||
user_history: 'Histórico do usuário'
|
||||
user_karma_score: 'Nota Usuário do Karma'
|
||||
username: Usuário
|
||||
username_needs_approval: 'Usuário precisa de aprovação'
|
||||
username_rejected: 'Usuário rejeitado'
|
||||
user_impersonating: 'Este usuário está representando'
|
||||
user_no_comment: 'Você nunca deixou um comentário. Participe da conversa!'
|
||||
username_offensive: 'Esse nome de usuário é ofensivo'
|
||||
validators:
|
||||
confirm_password: 'Suas senhas não coincidem. Por favor, tente novamente.'
|
||||
required: 'Esse campo é obrigatório'
|
||||
verify_email: 'Não é um e-mail válido'
|
||||
verify_organization_name: 'O nome da organização só deve conter letras ou números.'
|
||||
verify_password: 'A senha deve conter pelo menos 8 caracteres'
|
||||
|
||||
+2
-2
@@ -114,8 +114,8 @@ zh_CN:
|
||||
enable_questionbox: 向读者提问
|
||||
enable_questionbox_description: 该问题将在评论流顶部出现。可以就文章中特定内容发问,也可以设置一个讨论问题,等等。
|
||||
hours: 小时
|
||||
include_comment_stream: 开启评论流描述
|
||||
include_comment_stream_desc: 填写将在评论流顶部出现的描述。可以写评论主题、社群指引方针,等等。
|
||||
code_of_conduct_summary: 开启评论流描述
|
||||
code_of_conduct_summary_desc: 填写将在评论流顶部出现的描述。可以写评论主题、社群指引方针,等等。
|
||||
include_question_here: 此处输入问题:
|
||||
include_text: 此处输入文本。
|
||||
moderate: 审查
|
||||
|
||||
+2
-2
@@ -113,8 +113,8 @@ zh_TW:
|
||||
enable_questionbox: 向讀者提問
|
||||
enable_questionbox_description: 該問題將會在評論流置頂。您可以詢問其他讀者有關文章中的具體時間或是提出討論等
|
||||
hours: 小時
|
||||
include_comment_stream: 包含讀者的評論流描述
|
||||
include_comment_stream_desc: 留言將在您的評論流中置頂。發布一個社區規則等
|
||||
code_of_conduct_summary: 包含讀者的評論流描述
|
||||
code_of_conduct_summary_desc: 留言將在您的評論流中置頂。發布一個社區規則等
|
||||
include_question_here: 請在此處輸入問題:
|
||||
include_text: 在此插入您的文本
|
||||
moderate: 審核
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const { logger } = require('../services/logging');
|
||||
const { ErrHTTPNotFound } = require('../errors');
|
||||
const now = require('performance-now');
|
||||
|
||||
const log = (req, res, next) => {
|
||||
@@ -33,7 +34,12 @@ const log = (req, res, next) => {
|
||||
};
|
||||
|
||||
const error = (err, req, res, next) => {
|
||||
logger.error({ err }, 'http error');
|
||||
// Don't log out an error for ErrHTTPNotFound as this is already
|
||||
// logged with the included request logger.
|
||||
if (!(err instanceof ErrHTTPNotFound)) {
|
||||
logger.error({ err }, 'http error');
|
||||
}
|
||||
|
||||
next(err);
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ const { merge } = require('lodash');
|
||||
|
||||
const {
|
||||
BASE_URL,
|
||||
BASE_ORIGIN,
|
||||
BASE_PATH,
|
||||
MOUNT_PATH,
|
||||
STATIC_URL,
|
||||
@@ -29,6 +30,7 @@ const TALK_CLIENT_ENV = Object.keys(process.env)
|
||||
LIVE_URI: WEBSOCKET_LIVE_URI,
|
||||
STATIC_URL,
|
||||
STATIC_ORIGIN,
|
||||
BASE_ORIGIN,
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
+5
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "talk",
|
||||
"version": "4.6.2",
|
||||
"version": "4.6.6",
|
||||
"description": "A better commenting experience from Mozilla, The New York Times, and the Washington Post. https://coralproject.net",
|
||||
"main": "app.js",
|
||||
"private": true,
|
||||
@@ -14,7 +14,7 @@
|
||||
"start": "NODE_ENV=production ./bin/cli-serve -j -w",
|
||||
"prebuild": "npm-run-all clean generate-introspection",
|
||||
"build": "NODE_ENV=production parallel-webpack --bail",
|
||||
"lint:yaml": "yamllint locales/*.yml",
|
||||
"lint:yaml": "yamllint locales/*.y{a,}ml plugins/**/*.y{a,}ml",
|
||||
"lint:js": "eslint bin/cli* .",
|
||||
"lint": "npm-run-all lint:*",
|
||||
"plugins:reconcile": "./bin/cli plugins reconcile",
|
||||
@@ -126,7 +126,6 @@
|
||||
"history": "^3.0.0",
|
||||
"hjson": "^3.1.1",
|
||||
"hjson-loader": "^1.0.0",
|
||||
"https-proxy-agent": "^2.2.0",
|
||||
"immutability-helper": "^2.2.0",
|
||||
"imports-loader": "^0.7.1",
|
||||
"inquirer": "^3.2.2",
|
||||
@@ -171,8 +170,9 @@
|
||||
"postcss-smart-import": "^0.5.1",
|
||||
"precss": "1.4.0",
|
||||
"prop-types": "^15.5.10",
|
||||
"proxy-agent": "^3.0.1",
|
||||
"pym.js": "^1.3.2",
|
||||
"query-string": "^5.0.0",
|
||||
"querystringify": "^2.0.0",
|
||||
"react": "^15.4.2",
|
||||
"react-apollo": "^1.4.12",
|
||||
"react-broadcast": "^0.6.2",
|
||||
@@ -209,6 +209,7 @@
|
||||
"uglifyjs-webpack-plugin": "^1.1.6",
|
||||
"url-join": "^2.0.2",
|
||||
"url-loader": "^0.6.0",
|
||||
"url-parse": "^1.4.3",
|
||||
"url-search-params": "^0.9.0",
|
||||
"uuid": "^3.1.0",
|
||||
"webpack": "^3.10.0",
|
||||
|
||||
@@ -10,4 +10,5 @@ export {
|
||||
getShallowChanges,
|
||||
createDefaultResponseFragments,
|
||||
handlePopupAuth,
|
||||
buildCommentURL,
|
||||
} from 'coral-framework/utils';
|
||||
|
||||
@@ -219,7 +219,7 @@ es:
|
||||
register: "Registrar"
|
||||
sign_up: "Registro"
|
||||
confirm_password: "Confirmar Contraseña"
|
||||
username: "Nombre"
|
||||
username: "Nombre de Usuario"
|
||||
already_have_an_account: "¿Ya tienes una cuenta?"
|
||||
recover_password: "Recuperar la contraseña"
|
||||
email_in_use: "Este correo se encuentra en uso"
|
||||
@@ -343,48 +343,48 @@ nl_NL:
|
||||
pt_BR:
|
||||
talk-plugin-auth:
|
||||
login:
|
||||
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: "Signed in as"
|
||||
facebook_sign_in: "Sign in with Facebook"
|
||||
facebook_sign_up: "Sign up with Facebook"
|
||||
logout: "Sign out"
|
||||
sign_in: "Sign in"
|
||||
sign_in_to_join: "Sign in to join the conversation"
|
||||
or: "Or"
|
||||
email: "Email 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"
|
||||
sign_in_to_comment: "Sign in to comment"
|
||||
check_the_form: "Invalid Form. Please, check the fields"
|
||||
already_have_an_account: "Já possui uma conta?"
|
||||
check_the_form: "Formulário inválido. Por favor confira os campos"
|
||||
confirm_password: "Confirmar senha"
|
||||
email: "Endereço de email"
|
||||
email_in_use: "Endereço de email já está em uso"
|
||||
email_or_username_in_use: "Endereço de email ou nome de usuário já em uso"
|
||||
email_verify_cta: "Por favor verifique seu endereço de email."
|
||||
facebook_sign_in: "Entrar com o Facebook"
|
||||
facebook_sign_up: "Cadastrar com o Facebook"
|
||||
forgot_your_pass: "Esqueceu sua senha?"
|
||||
request_new_verify_email: "Solicite outro email"
|
||||
verify_email: "Obrigado por criar uma conta! Enviamos um email para o endereço de email informado para verificar sua conta."
|
||||
verify_email2: "Você deve verificar sua conta antes de participar da comunidade."
|
||||
logged_in_as: "Logado como"
|
||||
logout: "Sair"
|
||||
need_an_account: "Precisa de uma conta?"
|
||||
not_you: "Não é você?"
|
||||
or: "Ou"
|
||||
password: "Senha"
|
||||
passwords_dont_match: "As senhas não conferem."
|
||||
recover_password: "Recuperar senha"
|
||||
register: "Registrar"
|
||||
required_field: "Esse campo é obrigatório"
|
||||
sign_in: "Entrar"
|
||||
sign_in_to_comment: "Entre para comentar"
|
||||
sign_in_to_join: "Entre para participar da conversa"
|
||||
sign_up: "Inscreva-se"
|
||||
special_characters: "Nome de usuário contem somente letras, números and _"
|
||||
username: "Nome de usuário"
|
||||
set_username_dialog:
|
||||
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."
|
||||
check_the_form: "Formulário inválido. Por favor confira os campos"
|
||||
continue: "Continue com o mesmo nome de usuário do Facebook"
|
||||
error_create: "Erro ao trocar o nome de usuário"
|
||||
fake_comment_body: "Esse é um comentário de exemplo. Leitores podem compartilhar pensamentos e opiniões na seção de comentários."
|
||||
fake_comment_date: "1 minuto atrás"
|
||||
if_you_dont_change_your_name: "Se você não mudar seu nome de usuário neste ponto do processo, o nome que está no seu Facebook irá aparecer junto de todos os seus comentários"
|
||||
required_field: "Campo obrigatório"
|
||||
save: Salvar
|
||||
special_characters: "Nome de usuários podem conter somente letras números e _"
|
||||
username: Nome de usuário
|
||||
write_your_username: "Edite seu nome de usuário"
|
||||
your_username: "Seu nome de usuário aparece em cada comentário feito."
|
||||
zh_CN:
|
||||
talk-plugin-auth:
|
||||
login:
|
||||
|
||||
@@ -5,7 +5,13 @@ import { t } from 'plugin-api/beta/client/services';
|
||||
import { Icon } from 'plugin-api/beta/client/components/ui';
|
||||
|
||||
export default ({ className = '' }) => (
|
||||
<div className={cn(styles.tooltip, className)}>
|
||||
<div
|
||||
className={cn(
|
||||
styles.tooltip,
|
||||
className,
|
||||
'talk-plugin-featured-comments-tooltip'
|
||||
)}
|
||||
>
|
||||
<Icon name="info_outline" className={styles.icon} />
|
||||
<h3 className={styles.headline}>
|
||||
{t('talk-plugin-featured-comments.featured_comments')}:
|
||||
|
||||
@@ -62,7 +62,7 @@ es:
|
||||
talk-plugin-featured-comments:
|
||||
un_feature: Desmarcar
|
||||
feature: Remarcar
|
||||
featured: Remarcado
|
||||
featured: Remarcados
|
||||
featured_comments: Comentarios Remarcados
|
||||
go_to_conversation: Ir al comentario
|
||||
tooltip_description: Comentarios seleccionados por nuestro equipo que valen la pena ser leidos
|
||||
@@ -102,19 +102,19 @@ nl_NL:
|
||||
yes_feature_comment: Ja, reactie uitlichten.
|
||||
pt_BR:
|
||||
talk-plugin-featured-comments:
|
||||
un_feature: Un-Feature
|
||||
feature: Feature
|
||||
featured: Featured
|
||||
featured_comments: Featured Comments
|
||||
go_to_conversation: Go to conversation
|
||||
tooltip_description: Comments selected by our team as worth reading
|
||||
notify_self_featured: 'The comment from {0} is now featured and approved'
|
||||
notify_featured: '{0} featured and approved comment "{1}"'
|
||||
notify_unfeatured: '{0} unfeatured comment "{1}"'
|
||||
feature_comment: Feature comment?
|
||||
are_you_sure: Are you sure you would like to feature this comment?
|
||||
cancel: Cancel
|
||||
yes_feature_comment: Yes, feature comment
|
||||
un_feature: Desfazer
|
||||
feature: Destacar
|
||||
featured: Destacado
|
||||
featured_comments: Comentários destacados
|
||||
go_to_conversation: Ir para conversa
|
||||
tooltip_description: Vale a pena ler os comentários selecionados pelo nosso time
|
||||
notify_self_featured: 'O comentário do {0} está em destaque e aprovado'
|
||||
notify_featured: '{0} destacou e aprovou o comentário "{1}"'
|
||||
notify_unfeatured: '{0} Desmarcar comentário "{1}"'
|
||||
feature_comment: Destacar comentário?
|
||||
are_you_sure: Você tem certeza que deseja destacar esse comentário?
|
||||
cancel: Cancelar
|
||||
yes_feature_comment: Sim, destacar comentário
|
||||
zh_CN:
|
||||
talk-plugin-featured-comments:
|
||||
un_feature: "取消精选"
|
||||
|
||||
@@ -8,17 +8,17 @@ en:
|
||||
sign_up: "Sign up with Google"
|
||||
es:
|
||||
talk-plugin-google-auth:
|
||||
google_sign_in: "Entrar con Google"
|
||||
google_sign_up: "Registrarse con Google"
|
||||
sign_in: "Entrar con Google"
|
||||
sign_up: "Registrarse con Google"
|
||||
fr:
|
||||
talk-plugin-google-auth:
|
||||
google_sign_in: "Connectez-vous avec Google"
|
||||
google_sign_up: "Inscrivez-vous avec Google"
|
||||
sign_in: "Connectez-vous avec Google"
|
||||
sign_up: "Inscrivez-vous avec Google"
|
||||
zh_CN:
|
||||
talk-plugin-google-auth:
|
||||
google_sign_in: "使用 Google 帐号"
|
||||
google_sign_up: "使用 Google 帐号"
|
||||
sign_in: "使用 Google 帐号"
|
||||
sign_up: "使用 Google 帐号"
|
||||
zh_TW:
|
||||
talk-plugin-google-auth:
|
||||
google_sign_in: "使用 Google 帳號"
|
||||
google_sign_up: "使用 Google 帳號"
|
||||
sign_in: "使用 Google 帳號"
|
||||
sign_up: "使用 Google 帳號"
|
||||
|
||||
@@ -52,16 +52,17 @@ de:
|
||||
es:
|
||||
talk-plugin-ignore-user:
|
||||
section_title: "Usuarios ignorados"
|
||||
section_info: Because you ignored the following commenters, their comments are hidden.
|
||||
blank_info: Actualmente no ignoras a ningún usuario
|
||||
section_info: Debido a que ignoró a los siguientes comentaristas, sus comentarios están ocultos.
|
||||
stop_ignoring: "No ignorar más"
|
||||
ignore_user: Ignore User
|
||||
cancel: Cancel
|
||||
ignore_user: Ignorar usuario
|
||||
cancel: Cancelar
|
||||
confirmation: |
|
||||
When you ignore a user, all comments they wrote on the site will be hidden from you. You can
|
||||
undo this later from My Profile.
|
||||
Cuando ignora a un usuario, todos los comentarios que escribió en el sitio estarán ocultos.
|
||||
Puede deshacer esto más tarde desde Mi Perfil.
|
||||
notify_success: |
|
||||
You are now ignoring {0}. You can undo this action from My Profile.
|
||||
confirmation_title: Ignore {0}?
|
||||
Ahora estás ignorando a {0}. Puede deshacer esta acción desde Mi Perfil.
|
||||
confirmation_title: Ignorar a {0}?
|
||||
fr:
|
||||
talk-plugin-ignore-user:
|
||||
section_title: "Utilisateurs ignorés"
|
||||
@@ -90,17 +91,18 @@ nl_NL:
|
||||
confirmation_title: Negeer {0}?
|
||||
pt_BR:
|
||||
talk-plugin-ignore-user:
|
||||
blank_info: Atualmente você não está ignorando nenhum usuário
|
||||
section_title: "Usuários ignorados"
|
||||
section_info: "Porque você ignorou os seguintes comentadores, seus comentários estão ocultos."
|
||||
stop_ignoring: "Pare de ignorar"
|
||||
ignore_user: Ignore User
|
||||
cancel: Cancel
|
||||
confirmation: |
|
||||
When you ignore a user, all comments they wrote on the site will be hidden from you. You can
|
||||
undo this later from My Profile.
|
||||
stop_ignoring: "Parar de ignorar"
|
||||
ignore_user: Ignorar usuário
|
||||
cancel: Cancelar
|
||||
confirmation:
|
||||
Quando você ignora um usuário, todos os comentários que ele ele(a) escreveu não serão exibidos para você. Você pode
|
||||
desfazer isso depois no Meu Perfil
|
||||
notify_success: |
|
||||
You are now ignoring {0}. You can undo this action from My Profile.
|
||||
confirmation_title: Ignore {0}?
|
||||
Agora você está ignorando {0}. Você pode desfazer essa ação em Meu Perfil.
|
||||
confirmation_title: Ignorar {0}?
|
||||
zh_CN:
|
||||
talk-plugin-ignore-user:
|
||||
section_title: "被忽略用户"
|
||||
|
||||
@@ -178,10 +178,12 @@ class Profile extends React.Component {
|
||||
},
|
||||
},
|
||||
notify,
|
||||
success: hasChangedUsername,
|
||||
} = this.props;
|
||||
const { editing, formData, showDialog } = this.state;
|
||||
|
||||
const usernameCanBeUpdated = canUsernameBeUpdated(status);
|
||||
const usernameCanBeUpdated =
|
||||
canUsernameBeUpdated(status) && !hasChangedUsername;
|
||||
|
||||
return (
|
||||
<section
|
||||
@@ -232,6 +234,7 @@ class Profile extends React.Component {
|
||||
validationType="username"
|
||||
disabled={!usernameCanBeUpdated}
|
||||
columnDisplay
|
||||
errorMsg={this.state.errors.newUsername}
|
||||
>
|
||||
<div className={styles.bottomText}>
|
||||
<span>
|
||||
@@ -307,6 +310,7 @@ Profile.propTypes = {
|
||||
notify: PropTypes.func.isRequired,
|
||||
username: PropTypes.string,
|
||||
emailAddress: PropTypes.string,
|
||||
success: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
export default Profile;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import { compose, gql } from 'react-apollo';
|
||||
import { bindActionCreators } from 'redux';
|
||||
@@ -23,6 +24,14 @@ class AddEmailAddressDialog extends React.Component {
|
||||
|
||||
componentDidMount() {
|
||||
this.props.startAttach();
|
||||
document.body.style.minHeight = `${
|
||||
document.getElementById('talk-plugin-local-auth-email-dialog')
|
||||
.clientHeight
|
||||
}px`;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.body.style.removeProperty('min-height');
|
||||
}
|
||||
|
||||
handleDone = () => {
|
||||
@@ -63,7 +72,7 @@ class AddEmailAddressDialog extends React.Component {
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Dialog open={true}>
|
||||
<Dialog open={true} id="talk-plugin-local-auth-email-dialog">
|
||||
{step === 0 && <AddEmailForm onSubmit={this.handleSubmit} />}
|
||||
{step === 1 &&
|
||||
!requireEmailConfirmation && (
|
||||
|
||||
@@ -150,6 +150,82 @@ en:
|
||||
description_2: "You can change your account settings by visiting"
|
||||
path: "My Profile > Settings"
|
||||
alert: "Email Added!"
|
||||
pt_BR:
|
||||
email:
|
||||
email_change_original:
|
||||
subject: Mudança de email
|
||||
body: Seu endereço de email foi alterado de {0} para {1}. Se você não solicitou essa alteração, por favor contate {2}.
|
||||
error:
|
||||
NO_LOCAL_PROFILE: Nenhum email existente está vinculado a essa conta.
|
||||
LOCAL_PROFILE: Já existe um endereço de email associado a essa conta.
|
||||
INCORRECT_PASSWORD: A senha informada está incorreta.
|
||||
talk-plugin-local-auth:
|
||||
change_password:
|
||||
change_password: "Mudar senha"
|
||||
passwords_dont_match: "Senhas não conferem"
|
||||
required_field: "Esse campo é obrigatório"
|
||||
forgot_password: "Esqueceu sua senha?"
|
||||
old_password: "Senha antiga"
|
||||
new_password: "Nova senha"
|
||||
confirm_new_password: "Confirme a nova senha"
|
||||
save: "Salvar"
|
||||
cancel: "Cancelar"
|
||||
edit: "Editar"
|
||||
changed_password_msg: "Senha alterada - Sua senha foi alterada com sucesso"
|
||||
forgot_password_sent: "Esqueceu a senha - Nós enviamos um email para recuperação da senha"
|
||||
change_username:
|
||||
change_username_note: "Nomes de usuários só podem ser alterados uma vez a cada 14 dias"
|
||||
is_not_eligible: "Seu nome de usuário não pode ser alterado."
|
||||
save: "Salvar"
|
||||
edit_profile: "Editar perfil"
|
||||
cancel: "Cancelar"
|
||||
confirm_username_change: "Confirmar alteração do nome de usuário"
|
||||
description: "Você está tentando alterar seu nome de usuário. Seu novo nome de usuário irá aparecer em todos os comentários antigos e novos."
|
||||
old_username: "Nome de usuário antigo"
|
||||
new_username: "Nome de usuário novo"
|
||||
re_enter: "Repita o novo usuário"
|
||||
bottom_note: "Atenção: Não será possível alterar seu nome de usuário por 14 dias"
|
||||
confirm_changes: "Confirmar mudanças"
|
||||
username_does_not_match: "Nome de usuário não confere"
|
||||
cant_be_equal: "Seu novo {0} deve ser diferente do atual"
|
||||
changed_username_success_msg: "Nome de usuário alterado - Nome de usuário alterado com sucesso. Não será possível alterar por 14 dias."
|
||||
change_username_attempt: "Usuário não pode ser alterado. Nome de usuário só pode ser alterado a cada 14 dias."
|
||||
change_email:
|
||||
confirm_email_change: "Confirmar alteração de email"
|
||||
description: "Você está tentando alterar seu endereço de email. Seu novo email será usado para entrar na plataforma e receber avisos da sua conta."
|
||||
old_email: "Endereço de email antigo"
|
||||
new_email: "Endereço de email novo"
|
||||
enter_password: "Digite a senha"
|
||||
incorrect_password: "Senha incorreta"
|
||||
confirm_change: "Confirmar alteração"
|
||||
cancel: "Cancelar"
|
||||
change_email_msg: "Endereço de email alterado. este endereço de email será usado para entrar e receber notificações de email."
|
||||
add_email:
|
||||
add_email_address: "Adicionar endereço de email"
|
||||
enter_email_address: "Entre com o endereço de email:"
|
||||
invalid_email_address: "Email inválido"
|
||||
confirm_email_address: "Confirmar endereço de email:"
|
||||
email_does_not_match: "Endereço de email não confere"
|
||||
insert_password: "Insira a senha:"
|
||||
confirm_password: "Confirmar senha:"
|
||||
required_field: "Esse campo é obrigatório"
|
||||
done: "Feito"
|
||||
content:
|
||||
title: "Adicione um endereço de email"
|
||||
description: "Para a sua segurança, exigimos que os usuários adicionem um endereço de email para suas contas. Seu email será usado para:"
|
||||
item_1: "Receba avisos de alterações na sua conta(endereço de email, usuário, senha, etc.)"
|
||||
item_2: "Permitir que você baixe seus comentários."
|
||||
item_3: "Envie notificações de comentários que você escolheu receber."
|
||||
verify:
|
||||
title: "Verifique seu endereço de email"
|
||||
description: "Enviamos um email para {0} para verificar sua conta. Ele pode ser usado para confirmar alterações na conta e notificações."
|
||||
added:
|
||||
title: "Endereço de email adicionado"
|
||||
description: "Seu endereço de email foi adicionado na sua conta."
|
||||
subtitle: "Precisa alterar seu endereço de email?"
|
||||
description_2: "Você pode alterar as configurações da sua conta em"
|
||||
path: "Meu Perfil > Configurações"
|
||||
alert: "Email adicionado!"
|
||||
de:
|
||||
email:
|
||||
email_change_original:
|
||||
@@ -226,17 +302,28 @@ de:
|
||||
path: "Mein Profil > Profil-Einstellungen"
|
||||
alert: "E-Mail-Adresse hinzugefügt!"
|
||||
es:
|
||||
email:
|
||||
email_change_original:
|
||||
subject: Cambio de correo electrónico
|
||||
body: Su dirección de correo electrónico ha cambiado de {0} a {1}. Si no solicitó este cambio, póngase en contacto con {2}.
|
||||
error:
|
||||
NO_LOCAL_PROFILE: No hay una dirección de correo electrónico asociada a esta cuenta.
|
||||
LOCAL_PROFILE: Una dirección de correo electrónico ya está asociada a esta cuenta.
|
||||
INCORRECT_PASSWORD: La contraseña dada fue incorrecta.
|
||||
talk-plugin-local-auth:
|
||||
change_password:
|
||||
save: "Salvar"
|
||||
cancel: "Cancelar"
|
||||
edit: "Editar"
|
||||
changed_password_msg: "Senha alterada - Sua senha foi alterada com sucesso"
|
||||
forgot_password_sent: "Esqueceu a senha - Nós enviamos um email para recuperação da senha"
|
||||
change_password: "Cambiar Contraseña"
|
||||
passwords_dont_match: "Las contraseñas no coinciden"
|
||||
required_field: "Este campo es requerido"
|
||||
forgot_password: "Olvidaste tu contraseña?"
|
||||
save: "Guardar"
|
||||
cancel: "Cancelar"
|
||||
edit: "Editar"
|
||||
changed_password_msg: "Contraseña Actualizada - Tu contraseña ha sido exitosamente actualizada"
|
||||
forgot_password_sent: "Contraseña Olvidada - Te enviamos un email para recuperar tu contraseña"
|
||||
old_password: "Contraseña anterior"
|
||||
new_password: "Contraseña nueva"
|
||||
confirm_new_password: "Confirme contraseña nueva"
|
||||
change_username:
|
||||
change_username_note: "El usuario puede ser cambiado cada 14 días."
|
||||
is_not_eligible: "Ahora mismo no se puede cambiar su nombre de usuario."
|
||||
@@ -245,10 +332,47 @@ es:
|
||||
cancel: "Cancelar"
|
||||
confirm_username_change: "Confirmar Cambio de Usuario"
|
||||
description: "Estás intentando cambiar tu usuario. Tu nuevo usuario aparecerá en todos tus pasados y futuros comentarios."
|
||||
old_username: "Usuario viejo"
|
||||
old_username: "Usuario anterior"
|
||||
new_username: "Usuario nuevo"
|
||||
re_enter: "Escriba usuario nuevo otra vez"
|
||||
bottom_note: "Nota: No podrás cambiar tu usuario por 14 días"
|
||||
confirm_changes: "Confirmar Cambios"
|
||||
username_does_not_match: "El usuario no coincide"
|
||||
cant_be_equal: "Tu nuev@ {0} tiene que ser diferente"
|
||||
changed_username_success_msg: "Usuario Actualizado - Tu usuario ha sido exitosamente actualizado. No podrás cambiar el usuario por 14 días."
|
||||
change_username_attempt: "El usuario no puede ser actualizado. Los usuarios pueden ser cambiados cada 14 días."
|
||||
change_email:
|
||||
confirm_email_change: "Confirmar cambio de dirección de correo electrónico"
|
||||
description: "Está intentando cambiar su dirección de correo electrónico. Su nueva dirección de correo electrónico se usará para iniciar sesión y recibir notificaciones de la cuenta."
|
||||
new_email: "Nueva dirección de correo electrónico"
|
||||
enter_password: "Introducir la contraseña"
|
||||
incorrect_password: "Contraseña incorrecta"
|
||||
confirm_change: "Confirmar cambio"
|
||||
cancel: "Cancelar"
|
||||
change_email_msg: "Dirección de correo electrónico modificada. Esta dirección de correo electrónico ahora se utilizará para iniciar sesión y notificaciones por correo electrónico."
|
||||
add_email:
|
||||
add_email_address: "Confirmar"
|
||||
enter_email_address: "Introducir la dirección de correo electrónico:"
|
||||
invalid_email_address: "Dirección de correo electrónico no válida"
|
||||
confirm_email_address: "Confirmar el correo:"
|
||||
email_does_not_match: "La dirección de Email no coincide"
|
||||
insert_password: "Insertar contraseña:"
|
||||
confirm_password: "Confirmar contraseña:"
|
||||
required_field: "Este campo es requerido"
|
||||
done: "Hecho"
|
||||
content:
|
||||
title: "Agregar una dirección de correo electrónico"
|
||||
description: "Para su seguridad adicional, solicitamos a los usuarios que agreguen una dirección de correo electrónico a sus cuentas. Su dirección de correo electrónico se usará para:"
|
||||
item_1: "Recibe actualizaciones sobre cualquier cambio en tu cuenta (dirección de correo electrónico, nombre de usuario, contraseña, etc.)"
|
||||
item_2: "Permitir que descargues tus comentarios."
|
||||
item_3: "Envía notificaciones de comentarios que hayas elegido recibir."
|
||||
verify:
|
||||
title: "Verificar su dirección de correo electrónico"
|
||||
description: "Hemos enviado un correo electrónico a {0} para verificar su cuenta. Debe verificar su dirección de correo electrónico para que se pueda usar para notificaciones y notificaciones de cambio de cuenta."
|
||||
added:
|
||||
title: "Dirección de correo electrónico agregada"
|
||||
description: "Su dirección de correo electrónico ha sido agregada a su cuenta."
|
||||
subtitle: "¿Necesita cambiar su dirección de correo electrónico?"
|
||||
description_2: "Puedes cambiar la configuración de tu cuenta visitando"
|
||||
path: "Mi perfil > Configuración"
|
||||
alert: "¡Correo electrónico agregado!"
|
||||
|
||||
@@ -21,7 +21,7 @@ nl_NL:
|
||||
member_since: "Gebruiker sinds"
|
||||
pt_BR:
|
||||
talk-plugin-member-since:
|
||||
member_since: "Member Since"
|
||||
member_since: "Membro desde"
|
||||
zh_CN:
|
||||
talk-plugin-member-since:
|
||||
member_since: "成员加入日期"
|
||||
|
||||
@@ -84,16 +84,16 @@ nl_NL:
|
||||
ban_user_dialog_headline: "Gebruiker verbannen?"
|
||||
pt_BR:
|
||||
talk-plugin-moderation-actions:
|
||||
reject_comment: "Reject"
|
||||
approve_comment: "Approve"
|
||||
approved_comment: "Approved"
|
||||
moderation_actions: "Moderation Actions"
|
||||
ban_user: "Ban User"
|
||||
ban_user_dialog_sub: "Are you sure you would like to ban this user?"
|
||||
ban_user_dialog_copy: "Note: Banning this user will also place this comment in the Rejected queue."
|
||||
ban_user_dialog_cancel: "Cancel"
|
||||
ban_user_dialog_yes: "Yes. Ban user"
|
||||
ban_user_dialog_headline: "Ban User?"
|
||||
reject_comment: "Rejeitar"
|
||||
approve_comment: "Aprovar"
|
||||
approved_comment: "Aprovado"
|
||||
moderation_actions: "Ações"
|
||||
ban_user: "Banir Usuário"
|
||||
ban_user_dialog_sub: "Tem certeza que deseja banir esse usuário?"
|
||||
ban_user_dialog_copy: "Nota: Banindo esse usuário também irá colocar esse comentário na fila de Rejeitado."
|
||||
ban_user_dialog_cancel: "Cancelar"
|
||||
ban_user_dialog_yes: "Sim. Banir usuário"
|
||||
ban_user_dialog_headline: "Banir usuário?"
|
||||
zh_CN:
|
||||
talk-plugin-moderation-actions:
|
||||
reject_comment: "拒绝"
|
||||
|
||||
@@ -4,6 +4,9 @@ ar:
|
||||
en:
|
||||
talk-plugin-notifications-category-featured:
|
||||
toggle_description: My comment is featured
|
||||
es:
|
||||
talk-plugin-notifications-category-featured:
|
||||
toggle_description: Mi comentario esta presentado
|
||||
de:
|
||||
talk-plugin-notifications-category-featured:
|
||||
toggle_description: Mein Kommentar wird empfohlen
|
||||
|
||||
@@ -11,6 +11,12 @@ en:
|
||||
featured:
|
||||
subject: "One of your comments was featured on {0}"
|
||||
body: "{0}\nA member of our team has selected this comment to be featured for other readers: {1}"
|
||||
es:
|
||||
talk-plugin-notifications:
|
||||
categories:
|
||||
featured:
|
||||
subject: "Uno de tus comentarios apareció en {0}"
|
||||
body: "{0}\nUn miembro de nuestro equipo ha seleccionado este comentario para ser presentado por otros lectores: {1}"
|
||||
de:
|
||||
talk-plugin-notifications:
|
||||
categories:
|
||||
|
||||
@@ -4,6 +4,9 @@ ar:
|
||||
en:
|
||||
talk-plugin-notifications-category-reply:
|
||||
toggle_description: My comment receives a reply
|
||||
es:
|
||||
talk-plugin-notifications-category-reply:
|
||||
toggle_description: Mi comentario recibe una respuesta
|
||||
de:
|
||||
talk-plugin-notifications-category-reply:
|
||||
toggle_description: Jemand antwortet auf meinen Kommentar
|
||||
|
||||
@@ -11,6 +11,12 @@ en:
|
||||
reply:
|
||||
subject: "Someone has replied to your comment on {0}"
|
||||
body: "{0}\n{1} replied to your comment: {2}"
|
||||
es:
|
||||
talk-plugin-notifications:
|
||||
categories:
|
||||
reply:
|
||||
subject: "Alguien ha respondido a tu comentario en {0}"
|
||||
body: "{0}\n{1} respondió a tu comentario: {2}"
|
||||
de:
|
||||
talk-plugin-notifications:
|
||||
categories:
|
||||
|
||||
@@ -4,6 +4,9 @@ ar:
|
||||
en:
|
||||
talk-plugin-notifications-category-staff:
|
||||
toggle_description: A staff member replies to my comment
|
||||
es:
|
||||
talk-plugin-notifications-category-staff:
|
||||
toggle_description: Un miembro del personal responde a mi comentario
|
||||
de:
|
||||
talk-plugin-notifications-category-staff:
|
||||
toggle_description: Ein Redaktionsmitglied antwortet auf meinen Kommentar
|
||||
|
||||
@@ -11,6 +11,12 @@ en:
|
||||
staff:
|
||||
subject: "Someone at {0} has replied to your comment"
|
||||
body: "{0}\n{1} works for {2} and has replied to your comment: {3}"
|
||||
es:
|
||||
talk-plugin-notifications:
|
||||
categories:
|
||||
staff:
|
||||
subject: "Alguien en {0} ha respondido a tu comentario"
|
||||
body: "{0}\n{1} trabaja para {2} y ha respondido a tu comentario: {3}"
|
||||
de:
|
||||
talk-plugin-notifications:
|
||||
categories:
|
||||
|
||||
@@ -6,6 +6,10 @@ en:
|
||||
talk-plugin-notifications:
|
||||
digest_enum:
|
||||
DAILY: In a daily digest
|
||||
es:
|
||||
talk-plugin-notifications:
|
||||
digest_enum:
|
||||
DAILY: En un resumen diario
|
||||
de:
|
||||
talk-plugin-notifications:
|
||||
digest_enum:
|
||||
|
||||
@@ -6,6 +6,10 @@ en:
|
||||
talk-plugin-notifications:
|
||||
digest_enum:
|
||||
HOURLY: In an hourly digest
|
||||
es:
|
||||
talk-plugin-notifications:
|
||||
digest_enum:
|
||||
HOURLY: En un resumen por hora
|
||||
de:
|
||||
talk-plugin-notifications:
|
||||
digest_enum:
|
||||
|
||||
@@ -34,6 +34,24 @@ en:
|
||||
digest_option: Send notifications
|
||||
digest_enum:
|
||||
NONE: Immediately
|
||||
es:
|
||||
talk-plugin-notifications:
|
||||
settings_title: Notificaciones
|
||||
settings_subtitle: Reciba notificaciones cuando
|
||||
turn_off_all: No quiero recibir notificaciones
|
||||
banner_info:
|
||||
title: Se requiere verificación de correo electrónico
|
||||
text: Para recibir notificaciones por correo electrónico, debe tener una dirección de correo electrónico verificada.
|
||||
verify_now: Verifica tu correo electrónico ahora.
|
||||
banner_success:
|
||||
title: Verificación del correo electrónico enviada
|
||||
text: Se envió un correo electrónico a {0} que contiene un enlace de verificación.
|
||||
banner_error:
|
||||
title: Error
|
||||
text: Ha habido un error al enviar su correo electrónico de verificación. Por favor, inténtelo de nuevo más tarde.
|
||||
digest_option: Enviar notificaciones
|
||||
digest_enum:
|
||||
NONE: Inmediatamente
|
||||
de:
|
||||
talk-plugin-notifications:
|
||||
settings_title: Benachrichtigungen
|
||||
|
||||
@@ -2,6 +2,7 @@ import React from 'react';
|
||||
import cn from 'classnames';
|
||||
import styles from './styles.css';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
import { buildCommentURL } from 'plugin-api/beta/client/utils';
|
||||
import { ClickOutside } from 'plugin-api/beta/client/components';
|
||||
import { Icon, Button } from 'plugin-api/beta/client/components/ui';
|
||||
|
||||
@@ -90,7 +91,7 @@ export default class PermalinkButton extends React.Component {
|
||||
className={cn(styles.input, `${name}-copy-field`)}
|
||||
type="text"
|
||||
ref={input => (this.permalinkInput = input)}
|
||||
defaultValue={`${asset.url}?commentId=${comment.id}`}
|
||||
defaultValue={buildCommentURL(asset.url, comment.id)}
|
||||
readOnly
|
||||
/>
|
||||
|
||||
@@ -105,9 +106,9 @@ export default class PermalinkButton extends React.Component {
|
||||
},
|
||||
])}
|
||||
>
|
||||
{!copyFailure && !copySuccessful && 'Copy'}
|
||||
{copySuccessful && 'Copied'}
|
||||
{copyFailure && 'Not supported'}
|
||||
{!copyFailure && !copySuccessful && t('common.copy')}
|
||||
{copySuccessful && t('common.copied')}
|
||||
{copyFailure && t('common.notsupported')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -100,6 +100,57 @@ en:
|
||||
subtitle: "Are you sure you want to delete your account?"
|
||||
description: "To confirm you would like to delete your account please type in the following phrase into the text box below:"
|
||||
type_to_confirm: "Type phrase below to confirm"
|
||||
es:
|
||||
download_request:
|
||||
section_title: "Descargar el historial de mis comentarios"
|
||||
you_will_get_a_copy: "Recibirás un correo electrónico con un enlace para descargar tu historial de comentarios. Puedes hacer"
|
||||
download_rate: "una solicitud de descarga cada {0} días"
|
||||
most_recent_request: "Tu solicitud más reciente"
|
||||
request: "Solicitar historial de comentarios"
|
||||
rate_limit: "Puedes enviar otra solicitud de historial de comentarios en {0}"
|
||||
hours: "{0} horas"
|
||||
days: "{0} dias"
|
||||
hour: "{0} hora"
|
||||
day: "{0} día"
|
||||
download_preparing: "Preparando para la descarga de la cuenta - Revises tu correo electrónico en breve para obtener un enlace de descarga"
|
||||
delete_request:
|
||||
account_deletion_cancelled: 'Solicitud de eliminación de cuenta cancelada - Tu solicitud para eliminar tu cuenta ha sido cancelada.'
|
||||
account_deletion_requested: 'Eliminación de cuenta solicitada'
|
||||
received_on: "Se recibió una solicitud para eliminar tu cuenta en "
|
||||
cancel_request_description: "Si deseas reactivar tu cuenta, puedes cancelar tu solicitud para eliminar tu cuenta a continuación"
|
||||
before: "antes"
|
||||
cancel_account_deletion_request: "Cancelar solicitud de eliminación de cuenta"
|
||||
delete_my_account: "Borrar mi cuenta"
|
||||
delete_my_account_description: "Al eliminar tu cuenta, se borrará definitivamente tu perfil y se eliminarán todos tus comentarios de este sitio."
|
||||
already_submitted_request_description: "Ya ha enviado una solicitud para eliminar tu cuenta. Tu cuenta será eliminada después de {0}. Puedes cancelar la solicitud hasta ese momento."
|
||||
your_request_submitted_description: "Tu solicitud ha sido enviada y la confirmación ha sido enviada a la dirección de correo electrónico asociada con tu cuenta."
|
||||
your_account_deletion_scheduled: "Tu cuenta está programada para ser eliminada después de:"
|
||||
changed_your_mind: "¿Has cambiado de opinión?"
|
||||
simply_go_to: "Simplemente acceda a su cuenta nuevamente antes de esta hora y haga clic en"
|
||||
tell_us_why: "Dinos por qué"
|
||||
feedback_copy: "Nos gustaría saber por qué eligió eliminar tu cuenta. Envíenos tus comentarios sobre nuestro sistema de comentarios por correo electrónico"
|
||||
done: "Hecho"
|
||||
cancel: "Cancelar"
|
||||
proceed: "Proceder"
|
||||
input_is_not_correct: "La entrada no es correcta"
|
||||
step_0:
|
||||
you_are_attempting: "Estás intentando eliminar tu cuenta. Esto significa:"
|
||||
item_1: "Todos tus comentarios son eliminados de este sitio"
|
||||
item_2: "Todos tus comentarios son eliminados de nuestra base de datos"
|
||||
item_3: "Tu nombre de usuario y dirección de correo electrónico se eliminan de nuestro sistema"
|
||||
step_1:
|
||||
subtitle: "¿Cuándo se eliminará mi cuenta?"
|
||||
description: "Tu cuenta se eliminará {0} horas después de que se hayas enviado su solicitud."
|
||||
subtitle_2: "¿Todavía puedo escribir comentarios hasta que mi cuenta se elimine?"
|
||||
description_2: "Sí, todavía puedes comentar, responder y reaccionar a los comentarios hasta que expire {0} horas."
|
||||
step_2:
|
||||
description: "Antes de que se elimine tu cuenta, te recomendamos que descargues su historial de comentarios para tus registros. Después de que se elimine su cuenta, no podrás solicitar su historial de comentarios."
|
||||
to_download: "Para descargar tu historial de comentarios, ve a:"
|
||||
path: "Mi perfil > Descargar historial de mis comentarios"
|
||||
step_3:
|
||||
subtitle: "¿Seguro que quieres eliminar tu cuenta?"
|
||||
description: "Para confirmar que deseas eliminar tu cuenta, escriba la siguiente frase en el cuadro de texto a continuación:"
|
||||
type_to_confirm: "Escriba la frase a continuación para confirmar"
|
||||
de:
|
||||
download_request:
|
||||
section_title: "Mein Kommentar-Archiv herunterladen"
|
||||
@@ -151,3 +202,54 @@ de:
|
||||
subtitle: "Sind Sie sicher, dass Sie Ihr Benutzerkonto löschen möchten?"
|
||||
description: "Um zu bestätigen, dass Sie Ihr Konto löschen möchten, geben Sie bitte folgende Zeichen in das Textfeld ein:"
|
||||
type_to_confirm: "Zur Bestätigung Zeichenfolge eingeben"
|
||||
pt_BR:
|
||||
download_request:
|
||||
section_title: "Baixar meu histórico de comentários"
|
||||
you_will_get_a_copy: "Você receberá um email com um link para baixar seu histórico de comentários. Você pode fazer"
|
||||
download_rate: "uma requisição de Download a cada {0} dias"
|
||||
most_recent_request: "Suas solicitações mais recentes"
|
||||
request: "Solicitar histórico de comentários"
|
||||
rate_limit: "Você pode solicitar outro histórico de comentários em {0}"
|
||||
hours: "{0} horas"
|
||||
days: "{0} dias"
|
||||
hour: "{0} hora"
|
||||
day: "{0} dia"
|
||||
download_preparing: "Preparando Download - Cheque seu email para acessar um link de download"
|
||||
delete_request:
|
||||
account_deletion_cancelled: 'Solicitação de exclusão de conta cancelada - Sua solicitação de exclusão cancelada.'
|
||||
account_deletion_requested: 'Exclusão de conta solicitada'
|
||||
received_on: "Uma solicitação para deletar sua conta foi recebida "
|
||||
cancel_request_description: "Se você deseja reativar sua conta, você pode cancelar a solicitação de exclusão abaixo"
|
||||
before: "antes"
|
||||
cancel_account_deletion_request: "Cancelar requisiçao de exclusão da conta"
|
||||
delete_my_account: "Deletar minha conta"
|
||||
delete_my_account_description: "Deletando sua conta seu perfil será excluído permanentemente e todos os seus comentários serão removidos desse site."
|
||||
already_submitted_request_description: "Você já enviou uma solicitação de exclusão da conta. Sua conta será deletada depois de {0}. Você pode cancelar até a data informada"
|
||||
your_request_submitted_description: "Sua solicitação foi enviada e uma confirmação foi enviada para o endereço de email associado a sua conta."
|
||||
your_account_deletion_scheduled: "Sua conta está programada para ser deletada depois de:"
|
||||
changed_your_mind: "Mudou de ideia?"
|
||||
simply_go_to: "Simplesmente volte para sua conta novamente e clique"
|
||||
tell_us_why: "Nos diga porque"
|
||||
feedback_copy: "Gostariámos de saber porque você deseja excluir sua conta. Nos envie um feedback através do nosso sistema de comentário"
|
||||
done: "Feito"
|
||||
cancel: "Cancelar"
|
||||
proceed: "Proceder"
|
||||
input_is_not_correct: "A entrada está incorreta"
|
||||
step_0:
|
||||
you_are_attempting: "Você está tentando deletar sua conta. Isso significa:"
|
||||
item_1: "Todos os seus comentários estão removidos desse site"
|
||||
item_2: "Todos os seus comentários estão removidos dos nossos bancos de dado"
|
||||
item_3: "Seu usuário e endereço de email estão removidos do nosso sistema"
|
||||
step_1:
|
||||
subtitle: "Quando minha conta será deletada?"
|
||||
description: "Sua conta será deletada {0} horas depois que sua solicitação for enviada."
|
||||
subtitle_2: "Ainda posso comentar antes da minha conta ser deletada?"
|
||||
description_2: "Sim, você ainda pode comentar, responder, e reagir aos comentários até as {0} horas expirarem."
|
||||
step_2:
|
||||
description: "Antes da sua conta ser deletada, nós recomendamos você a baixar seu histórico de comentários. Depois que sua conta for deletada, não será possível solicitar seu histórico de comentários."
|
||||
to_download: "Para baixar seu histórico de comentários, vá em:"
|
||||
path: "Meu Perfil > Baixar meu histórico de comentários"
|
||||
step_3:
|
||||
subtitle: "Você tem certeza que deseja deletar sua conta?"
|
||||
description: "Para confirmar que você deseja deletar sua conta por favor digite a frase a seguir na caixa de texto abaixo:"
|
||||
type_to_confirm: "Digite a frase abaixo para confirmar"
|
||||
|
||||
@@ -73,6 +73,43 @@ en:
|
||||
body: "You have cancelled your account deletion request for {0}. Your account is now reactivated."
|
||||
error:
|
||||
DOWNLOAD_TOKEN_INVALID: "Your download link is not valid."
|
||||
es:
|
||||
download_landing:
|
||||
download_your_account: "Descargue su historial de comentarios"
|
||||
download_details: "Su historial de comentarios se descargará en un archivo .zip. Después de descomprimir el historial de comentarios, tendrá un archivo de valores separados por comas (o .csv) que podrá importar fácilmente en su aplicación de hoja de cálculo favorita."
|
||||
all_information_included: "Para cada uno de sus comentarios se incluye la siguiente información:"
|
||||
information_included:
|
||||
date: "Cuando escribiste el comentario"
|
||||
url: "La URL del enlace permanente para el comentario"
|
||||
body: "El texto de comentario"
|
||||
asset_url: "La URL del artículo o historia donde aparece el comentario"
|
||||
confirm: "Descargar el historial de mis comentarios"
|
||||
email:
|
||||
download:
|
||||
subject: "Sus comentarios están listos para su descarga desde {0}"
|
||||
download_link_ready: "Haga clic aquí para descargar sus comentarios de {0} a partir de {1}:"
|
||||
download_archive: "Descargar archivo"
|
||||
delete:
|
||||
subject: "Su cuenta para {0} está programada para ser eliminada"
|
||||
body: |
|
||||
Se recibió una solicitud para eliminar su cuenta. Su cuenta está programada para ser eliminada {1}.
|
||||
|
||||
Después de ese momento, todos sus comentarios serán eliminados del sitio, todos sus comentarios serán eliminados de nuestra base de datos y su nombre de usuario y dirección de correo electrónico serán eliminados de nuestro sistema.
|
||||
|
||||
Si cambia de opinión, puede iniciar sesión en su cuenta y cancelar la solicitud antes de la hora programada para la eliminación de su cuenta.
|
||||
deleted:
|
||||
subject: "Su cuenta para {0} ha sido eliminada"
|
||||
body: |
|
||||
Su cuenta de comentarista para {0} ahora se borró. ¡Sentimos verte partir!
|
||||
|
||||
Si desea volver a unirse a la discusión en el futuro, puede registrarse para obtener una nueva cuenta.
|
||||
|
||||
Si desea darnos su opinión sobre por qué se fue y qué podemos hacer para mejorar la experiencia de comentarios, envíenos un correo electrónico a {1}.
|
||||
cancelDelete:
|
||||
subject: "La solicitud de eliminación de su cuenta para {0} ha sido cancelada"
|
||||
body: "Ha cancelado la solicitud de eliminación de cuenta para {0}. Su cuenta ahora está reactivada."
|
||||
error:
|
||||
DOWNLOAD_TOKEN_INVALID: "Su enlace de descarga no es válido."
|
||||
de:
|
||||
download_landing:
|
||||
download_your_account: "Mein Kommentar-Archiv herunterladen"
|
||||
|
||||
@@ -28,8 +28,8 @@ nl_NL:
|
||||
respected: Gerespecteerd
|
||||
pt_BR:
|
||||
talk-plugin-respect:
|
||||
respect: Respect
|
||||
respected: Respected
|
||||
respect: Respeitar
|
||||
respected: Respeitado
|
||||
zh_CN:
|
||||
talk-plugin-respect:
|
||||
respect: "赞"
|
||||
|
||||
@@ -21,7 +21,7 @@ nl_NL:
|
||||
label: Meest beantwoord eerst
|
||||
pt_BR:
|
||||
talk-plugin-sort-most-replied:
|
||||
label: Most replied first
|
||||
label: Mais respondidos primeiro
|
||||
zh_CN:
|
||||
talk-plugin-sort-most-replied:
|
||||
label: "最多回复在前"
|
||||
|
||||
@@ -21,7 +21,7 @@ nl_NL:
|
||||
label: Meest gerespecteerd eerst
|
||||
pt_BR:
|
||||
talk-plugin-sort-most-respected:
|
||||
label: Most respected first
|
||||
label: Mais respeitados primeiro
|
||||
zh_CN:
|
||||
talk-plugin-sort-most-respected:
|
||||
label: "最多被赞在前"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
en:
|
||||
talk-plugin-sort-most-upvoted:
|
||||
label: Most upvoted first
|
||||
de:
|
||||
talk-plugin-sort-most-upvoted:
|
||||
label: Am besten bewertet
|
||||
es:
|
||||
talk-plugin-sort-oldest:
|
||||
label: Más votadas primero
|
||||
|
||||
@@ -21,7 +21,7 @@ nl_NL:
|
||||
label: Nieuwste eerst
|
||||
pt_BR:
|
||||
talk-plugin-sort-newest:
|
||||
label: Newest first
|
||||
label: Mais novos primeiro
|
||||
zh_CN:
|
||||
talk-plugin-sort-newest:
|
||||
label: "最新发表在前"
|
||||
|
||||
@@ -21,7 +21,7 @@ nl_NL:
|
||||
label: Oudste eerst
|
||||
pt_BR:
|
||||
talk-plugin-sort-oldest:
|
||||
label: Oldest first
|
||||
label: Mais antigos primeiro
|
||||
zh_CN:
|
||||
talk-plugin-sort-oldest:
|
||||
label: "最早发表在前"
|
||||
|
||||
@@ -10,9 +10,10 @@ plugin:
|
||||
---
|
||||
|
||||
Using the [Perspective API](http://perspectiveapi.com/), this
|
||||
plugin will warn users and reject comments that exceed the predefined toxicity
|
||||
threshold. For more information on what Toxic Comments are, check out the
|
||||
[Toxic Comments](/talk/toxic-comments/) documentation.
|
||||
plugin will warn users when comments exceed the predefined toxicity
|
||||
threshold. Toxic comments will be flagged and are held back from being posted until reviewed by a moderator.
|
||||
|
||||
For more information on what Toxic Comments are, check out the [Toxic Comments](/talk/toxic-comments/) documentation, and you can see how the plugin works on [this blog post](https://coralproject.net/blog/toxic-avenging/).
|
||||
|
||||
Configuration:
|
||||
|
||||
@@ -25,4 +26,5 @@ Configuration:
|
||||
- `TALK_PERSPECTIVE_TIMEOUT` - The timeout for sending a comment to
|
||||
be processed before it will skip the toxicity analysis, parsed by
|
||||
[ms](https://www.npmjs.com/package/ms). (Default `300ms`)
|
||||
- `TALK_PERSPECTIVE_DO_NOT_STORE` - Whether the API is permitted to store comment and context from this request. Stored comments will be used for future research and community model building purposes to improve the API over time. (Default `true`) [Perspective API - Analize Comment Request](https://github.com/conversationai/perspectiveapi/blob/master/api_reference.md#analyzecomment-request)
|
||||
- `TALK_PERSPECTIVE_DO_NOT_STORE` - Whether the API stores or deletes the comment text and context from this request after it has been evaluated. Stored comments will be used for future research and community model building purposes to improve the API over time. (Default `true`) [Perspective API - Analyze Comment Request](https://github.com/conversationai/perspectiveapi/blob/master/api_reference.md#analyzecomment-request)
|
||||
- `TALK_PERSPECTIVE_SEND_FEEDBACK` - If set to `TRUE`, this plugin will send back moderation actions as feedback to [Perspective](http://perspectiveapi.com/) to improve their model. (Default `FALSE`)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user