mirror of
https://github.com/wassname/talk.git
synced 2026-09-09 11:38:08 +08:00
Fix lint
This commit is contained in:
@@ -5,4 +5,7 @@ import CheckSpamHook from '../components/CheckSpamHook';
|
||||
|
||||
const mapDispatchToProps = dispatch => bindActionCreators({ notify }, dispatch);
|
||||
|
||||
export default connect(null, mapDispatchToProps)(CheckSpamHook);
|
||||
export default connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
)(CheckSpamHook);
|
||||
|
||||
@@ -25,82 +25,104 @@ let enabled = true;
|
||||
// }
|
||||
// });
|
||||
|
||||
async function checkForSpam(ctx, { asset_id, body }) {
|
||||
const req = ctx.parent.parent;
|
||||
const loaders = ctx.loaders;
|
||||
|
||||
//If the key validation failed, then we can't run with the client.
|
||||
if (!enabled) {
|
||||
debug('not enabled, passing');
|
||||
return;
|
||||
}
|
||||
|
||||
let spam = false;
|
||||
try {
|
||||
const user_ip = get(req, 'ip', false);
|
||||
if (!user_ip) {
|
||||
debug('no ip on request');
|
||||
return;
|
||||
}
|
||||
|
||||
// Get some headers from the request.
|
||||
const user_agent = req.get('User-Agent');
|
||||
if (!user_agent || user_agent.length === 0) {
|
||||
debug('no user agent on request');
|
||||
return;
|
||||
}
|
||||
|
||||
const referrer = req.get('Referrer');
|
||||
if (!referrer || referrer.length === 0) {
|
||||
debug('no referrer on request');
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the Asset that the comment is being made against.
|
||||
const asset = await loaders.Assets.getByID.load(asset_id);
|
||||
if (!asset) {
|
||||
debug('asset not found for new comment');
|
||||
return;
|
||||
}
|
||||
|
||||
// Send off the comment to Akismet to check to see what they say.
|
||||
spam = await client.checkSpam({
|
||||
user_ip,
|
||||
user_agent,
|
||||
referrer,
|
||||
permalink: asset.url,
|
||||
comment_type: 'comment',
|
||||
comment_content: body,
|
||||
is_test: false,
|
||||
});
|
||||
|
||||
debug(`comment analyzed as ${spam ? 'being' : 'not being'} spam`);
|
||||
|
||||
return spam;
|
||||
} catch (err) {
|
||||
console.trace(err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function handlePositiveSpam(input) {
|
||||
// Attach reason information for the flag being added.
|
||||
input.status = 'SYSTEM_WITHHELD';
|
||||
input.actions =
|
||||
input.actions && input.actions.length >= 0 ? input.actions : [];
|
||||
input.actions.push({
|
||||
action_type: 'FLAG',
|
||||
user_id: null,
|
||||
group_id: 'SPAM_COMMENT',
|
||||
metadata: {},
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
RootMutation: {
|
||||
createComment: {
|
||||
async pre(_, { input }, { loaders, parent: req }) {
|
||||
// If the key validation failed, then we can't run with the client.
|
||||
if (!enabled) {
|
||||
debug('not enabled, passing');
|
||||
return;
|
||||
editComment: {
|
||||
pre: async (_, { asset_id, edit: { body }, edit }, ctx) => {
|
||||
const spam = await checkForSpam(ctx, { asset_id, body });
|
||||
if (spam) {
|
||||
// Mark the comment as positive spam.
|
||||
handlePositiveSpam(edit);
|
||||
}
|
||||
|
||||
let spam = false;
|
||||
try {
|
||||
const user_ip = get(req, 'ip', false);
|
||||
if (!user_ip) {
|
||||
debug('no ip on request');
|
||||
return;
|
||||
},
|
||||
},
|
||||
createComment: {
|
||||
pre: async (_, { input }, ctx) => {
|
||||
const spam = await checkForSpam(ctx, input);
|
||||
if (spam) {
|
||||
if (input.checkSpam) {
|
||||
throw new ErrSpam();
|
||||
}
|
||||
|
||||
// Get some headers from the request.
|
||||
const user_agent = req.get('User-Agent');
|
||||
if (!user_agent || user_agent.length === 0) {
|
||||
debug('no user agent on request');
|
||||
return;
|
||||
}
|
||||
|
||||
const referrer = req.get('Referrer');
|
||||
if (!referrer || referrer.length === 0) {
|
||||
debug('no referrer on request');
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the Asset that the comment is being made against.
|
||||
const asset = await loaders.Assets.getByID.load(input.asset_id);
|
||||
if (!asset) {
|
||||
debug('asset not found for new comment');
|
||||
return;
|
||||
}
|
||||
|
||||
// Send off the comment to Akismet to check to see what they say.
|
||||
spam = await client.checkSpam({
|
||||
user_ip,
|
||||
user_agent,
|
||||
referrer,
|
||||
permalink: asset.url,
|
||||
comment_type: 'comment',
|
||||
comment_content: input.body,
|
||||
is_test: true,
|
||||
});
|
||||
|
||||
debug(`comment analyzed as ${spam ? 'being' : 'not being'} spam`);
|
||||
} catch (err) {
|
||||
console.trace(err);
|
||||
return;
|
||||
// Mark the comment as positive spam.
|
||||
handlePositiveSpam(input);
|
||||
}
|
||||
|
||||
// Attach scores to metadata.
|
||||
input.metadata = merge({}, input.metadata || {}, {
|
||||
akismet: spam,
|
||||
});
|
||||
|
||||
if (spam) {
|
||||
if (input.checkSpam) {
|
||||
throw new ErrSpam();
|
||||
}
|
||||
|
||||
// Attach reason information for the flag being added.
|
||||
input.status = 'SYSTEM_WITHHELD';
|
||||
input.actions =
|
||||
input.actions && input.actions.length >= 0 ? input.actions : [];
|
||||
input.actions.push({
|
||||
action_type: 'FLAG',
|
||||
user_id: null,
|
||||
group_id: 'SPAM_COMMENT',
|
||||
metadata: {},
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -75,7 +75,7 @@ class SignUp extends React.Component {
|
||||
showErrors={!!emailError}
|
||||
errorMsg={emailError}
|
||||
onChange={this.handleEmailChange}
|
||||
autocomplete="off"
|
||||
autoComplete="off"
|
||||
/>
|
||||
<TextField
|
||||
id="username"
|
||||
@@ -86,8 +86,8 @@ class SignUp extends React.Component {
|
||||
showErrors={!!usernameError}
|
||||
errorMsg={usernameError}
|
||||
onChange={this.handleUsernameChange}
|
||||
autocomplete="off"
|
||||
autocapitalize="none"
|
||||
autoComplete="off"
|
||||
autoCapitalize="none"
|
||||
/>
|
||||
<TextField
|
||||
id="password"
|
||||
@@ -99,7 +99,7 @@ class SignUp extends React.Component {
|
||||
errorMsg={passwordError}
|
||||
onChange={this.handlePasswordChange}
|
||||
minLength="8"
|
||||
autocomplete="off"
|
||||
autoComplete="off"
|
||||
/>
|
||||
{passwordError && (
|
||||
<span className={styles.hint}>
|
||||
@@ -116,7 +116,7 @@ class SignUp extends React.Component {
|
||||
errorMsg={passwordRepeatError}
|
||||
onChange={this.handlePasswordRepeatChange}
|
||||
minLength="8"
|
||||
autocomplete="off"
|
||||
autoComplete="off"
|
||||
/>
|
||||
<Slot
|
||||
fill="talkPluginAuth.formField"
|
||||
|
||||
@@ -58,6 +58,9 @@ const mapDispatchToProps = dispatch =>
|
||||
);
|
||||
|
||||
export default compose(
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withForgotPassword
|
||||
)(ForgotPasswordContainer);
|
||||
|
||||
@@ -50,4 +50,7 @@ const mapDispatchToProps = dispatch =>
|
||||
dispatch
|
||||
);
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(MainContainer);
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(MainContainer);
|
||||
|
||||
@@ -59,6 +59,9 @@ const mapDispatchToProps = dispatch =>
|
||||
);
|
||||
|
||||
export default compose(
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withResendEmailConfirmation
|
||||
)(ResendEmailConfirmatonContainer);
|
||||
|
||||
@@ -89,6 +89,9 @@ const mapDispatchToProps = dispatch =>
|
||||
);
|
||||
|
||||
export default compose(
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withSignIn
|
||||
)(SignInContainer);
|
||||
|
||||
@@ -145,6 +145,9 @@ const mapDispatchToProps = dispatch =>
|
||||
);
|
||||
|
||||
export default compose(
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withSignUp
|
||||
)(SignUpContainer);
|
||||
|
||||
@@ -58,7 +58,10 @@ const mapStateToProps = state => ({
|
||||
});
|
||||
|
||||
export default compose(
|
||||
connect(mapStateToProps, null),
|
||||
connect(
|
||||
mapStateToProps,
|
||||
null
|
||||
),
|
||||
withSetUsername,
|
||||
branch(props => !props.username, renderNothing)
|
||||
)(SetUsernameDialogContainer);
|
||||
|
||||
@@ -11,4 +11,7 @@ const mapStateToProps = state => ({
|
||||
const mapDispatchToProps = dispatch =>
|
||||
bindActionCreators({ showSignInDialog }, dispatch);
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(SignInButton);
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(SignInButton);
|
||||
|
||||
@@ -10,4 +10,7 @@ const mapStateToProps = state => ({
|
||||
|
||||
const mapDispatchToProps = dispatch => bindActionCreators({ logout }, dispatch);
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(UserBox);
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(UserBox);
|
||||
|
||||
@@ -15,6 +15,7 @@ ar:
|
||||
or: "أو"
|
||||
email: "البريد الإلكتروني"
|
||||
password: "كلمة المرور"
|
||||
password_error: "يجب أن تكون كلمة المرور 8 أحرف على الأقل."
|
||||
forgot_your_pass: "نسيت كلمة المرور؟"
|
||||
need_an_account: "تحتاج الى حساب؟"
|
||||
register: "تسجيل"
|
||||
@@ -43,6 +44,15 @@ ar:
|
||||
username: اسم المستخدم
|
||||
write_your_username: "عدل اسم المستخدم"
|
||||
your_username: "يظهر اسم المستخدم في كل تعليق تنشره."
|
||||
change_password:
|
||||
change_password: "تغيير كلمة المرور"
|
||||
passwords_dont_match: "كلمات المرور غير متطابقة"
|
||||
required_field: "هذه الخانة مطلوبه"
|
||||
forgot_password: "نسيت كلمة المرور؟"
|
||||
save: "حفظ"
|
||||
cancel: "إلغاء"
|
||||
edit: "تصحيح"
|
||||
changed_password_msg: "كلمة المرور الخاصة بك تم تغييرها بنجاح"
|
||||
da:
|
||||
talk-plugin-auth:
|
||||
login:
|
||||
@@ -135,39 +145,13 @@ en:
|
||||
your_username: "Your username appears on every comment you post."
|
||||
change_password:
|
||||
change_password: "Change Password"
|
||||
passwords_dont_match: "Passwords don`t match"
|
||||
passwords_dont_match: "Passwords don't match"
|
||||
required_field: "This field is required"
|
||||
forgot_password: "Forgot your password?"
|
||||
save: "Save"
|
||||
cancel: "Cancel"
|
||||
edit: "Edit"
|
||||
changed_password_msg: "Changed Password - Your password has been successfully changed"
|
||||
change_username:
|
||||
change_username_note: "Usernames can be changed every 14 days"
|
||||
save: "Save"
|
||||
edit_profile: "Edit Profile"
|
||||
cancel: "Cancel"
|
||||
confirm_username_change: "Confirm Username Change"
|
||||
description: "You are attempting to change your username. Your new username will appear on all of your past and future comments."
|
||||
old_username: "Old Username"
|
||||
new_username: "New Username"
|
||||
bottom_note: "Note: You will not be able to change your username again for 14 days"
|
||||
confirm_changes: "Confirm Changes"
|
||||
username_does_not_match: "Username does not match"
|
||||
cant_be_equal: "Your new {0} must be different to your current one"
|
||||
change_username_attempt: "Username can't be updated. Usernames can be changed every 14 days"
|
||||
change_email:
|
||||
confirm_email_change: "Confirm Email Address Change"
|
||||
description: "You are attempting to change your email address. Your new email address will be used for your login and to receive account notifications."
|
||||
old_email: "Old Email Address"
|
||||
new_email: "New Email Address"
|
||||
enter_password: "Enter Password"
|
||||
incorrect_password: "Incorrect Password"
|
||||
confirm_change: "Confirm Change"
|
||||
cancel: "Cancel"
|
||||
change_email_msg: "Email Address Changed - Your email address has been successfully changed. This email address will now be used for signing in and email notifications."
|
||||
changed_username_success_msg: "Username Changed - Your username has been successfully changed. You will not be able to change your user name for 14 days."
|
||||
change_username_attempt: "Username can't be updated. Usernames can only be changed every 14 days."
|
||||
changed_password_msg: "Your password has been successfully changed"
|
||||
de:
|
||||
talk-plugin-auth:
|
||||
login:
|
||||
@@ -235,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"
|
||||
@@ -269,20 +253,6 @@ es:
|
||||
cancel: "Cancelar"
|
||||
edit: "Editar"
|
||||
changed_password_msg: "Contraseña Actualizada - Tu contraseña ha sido exitosamente actualizada"
|
||||
change_username:
|
||||
change_username_note: "El usuario puede ser cambiado cada 14 días"
|
||||
save: "Guardar"
|
||||
edit_profile: "Editar Perfil"
|
||||
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"
|
||||
new_username: "Usuario nuevo"
|
||||
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"
|
||||
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."
|
||||
fr:
|
||||
talk-plugin-auth:
|
||||
login:
|
||||
@@ -370,94 +340,103 @@ he:
|
||||
write_your_username: "ערוך את שם המשתמש שלך"
|
||||
your_username: "שם המשתמש שלך מופיע בכל תגובה שתפרסם."
|
||||
nl_NL:
|
||||
sign_in:
|
||||
email_verify_cta: "Controleer je e-mailadres."
|
||||
request_new_verify_email: "Vraag nieuwe bevestigingsemail aan"
|
||||
verify_email: "Bedankt voor het aanmaken van een account! We hebben een email verstuurd naar het adres dat je hebt opgegeven om je account te verifiëren."
|
||||
verify_email2: "Je account moet worden geverifiëerd voordat je kunt deelnemen in de community."
|
||||
not_you: "Ben je dit niet?"
|
||||
logged_in_as: "Ingelogd als"
|
||||
facebook_sign_in: "Inloggen met Facebook"
|
||||
facebook_sign_up: "Registreren met Facebook"
|
||||
logout: "Uitloggen"
|
||||
sign_in: "Inloggen"
|
||||
sign_in_to_join: "Log in om deel te nemen"
|
||||
or: "Of"
|
||||
email: "E-mailadres"
|
||||
password: "Wachtwoord"
|
||||
forgot_your_pass: "Wachtwoord vergeten?"
|
||||
need_an_account: "Heb je een account nodig?"
|
||||
register: "Registreren"
|
||||
sign_up: "Aanmelden"
|
||||
confirm_password: "Bevestig wachtwoord"
|
||||
username: "Gebruikersnaam"
|
||||
already_have_an_account: "Heb je al een account?"
|
||||
recover_password: "Wachtwoord herstellen"
|
||||
email_in_use: "E-mailadres is al in gebruik"
|
||||
email_or_username_in_use: "E-mailadres of gebruikersnaam is al in gebruik"
|
||||
required_field: "Dit is een vereist veld"
|
||||
passwords_dont_match: "Wachtwoorden komen niet overeen"
|
||||
special_characters: "Gebruikersnamen kunnen alleen letters, cijfers en _ bevatten"
|
||||
sign_in_to_comment: "Aanmelden om te reageren"
|
||||
check_the_form: "Het formulier bevat ongeldige invoer, controleer je invoer"
|
||||
createdisplay:
|
||||
check_the_form: "Het formulier bevat ongeldige invoer, controleer je invoer"
|
||||
continue: "Doorgaan met dezelfde Facebook gebruikersnaam"
|
||||
error_create: "Fout opgetreden bij het wijzigen van de gebruikersnaam"
|
||||
fake_comment_body: "Dit is een voorbeeldreactie. Lezers kunnen hun gedachten en meningen met newsrooms delen in het reactie-gedeelte"
|
||||
fake_comment_date: "1 minuut geleden"
|
||||
if_you_dont_change_your_name: "Wanneer je je gebruikersnaam nu niet wijzigt, zal je Facebook naam bij al je reacties komen te staan."
|
||||
required_field: "Vereist veld"
|
||||
save: Opslaan
|
||||
special_characters: "Gebruikersnamen kunnen alleen letters, cijfers en _ bevatten"
|
||||
username: Gebruikersnaam
|
||||
write_your_username: "Wijzig je gebruikersnaam"
|
||||
your_username: "Je gebruikersnaam verschijnt bij al je reacties."
|
||||
talk-plugin-auth:
|
||||
login:
|
||||
email_verify_cta: "Controleer je e-mailadres."
|
||||
request_new_verify_email: "Vraag nieuwe bevestigingsemail aan"
|
||||
verify_email: "Bedankt voor het aanmaken van een account! We hebben een email verstuurd naar het adres dat je hebt opgegeven om je account te verifiëren."
|
||||
verify_email2: "Je account moet worden geverifiëerd voordat je kunt deelnemen in de community."
|
||||
not_you: "Ben je dit niet?"
|
||||
logged_in_as: "Ingelogd als"
|
||||
logout: "Uitloggen"
|
||||
sign_in: "Inloggen"
|
||||
sign_in_to_join: "Log in om deel te nemen"
|
||||
or: "Of"
|
||||
email: "E-mailadres"
|
||||
password: "Wachtwoord"
|
||||
password_error: "Wachtwoord moet minstens 8 karakters bevatten."
|
||||
forgot_your_pass: "Wachtwoord vergeten?"
|
||||
need_an_account: "Heb je een account nodig?"
|
||||
register: "Registreren"
|
||||
sign_up: "Aanmelden"
|
||||
confirm_password: "Bevestig wachtwoord"
|
||||
username: "Gebruikersnaam"
|
||||
already_have_an_account: "Heb je al een account?"
|
||||
recover_password: "Wachtwoord herstellen"
|
||||
email_in_use: "E-mailadres is al in gebruik"
|
||||
email_or_username_in_use: "E-mailadres of gebruikersnaam is al in gebruik"
|
||||
required_field: "Dit is een vereist veld"
|
||||
passwords_dont_match: "Wachtwoorden komen niet overeen"
|
||||
special_characters: "Gebruikersnamen kunnen alleen letters, cijfers en _ bevatten"
|
||||
sign_in_to_comment: "Aanmelden om te reageren"
|
||||
check_the_form: "Het formulier bevat ongeldige invoer, controleer je invoer"
|
||||
set_username_dialog:
|
||||
check_the_form: "Het formulier bevat ongeldige invoer, controleer je invoer"
|
||||
continue: "Doorgaan met dezelfde Facebook gebruikersnaam"
|
||||
error_create: "Fout opgetreden bij het wijzigen van de gebruikersnaam"
|
||||
fake_comment_body: "Dit is een voorbeeldreactie. Lezers kunnen hun gedachten en meningen met newsrooms delen in het reactie-gedeelte"
|
||||
fake_comment_date: "1 minuut geleden"
|
||||
if_you_dont_change_your_name: "Wanneer je je gebruikersnaam nu niet wijzigt, zal je Facebook naam bij al je reacties komen te staan."
|
||||
required_field: "Vereist veld"
|
||||
save: Opslaan
|
||||
special_characters: "Gebruikersnamen kunnen alleen letters, cijfers en _ bevatten"
|
||||
username: Gebruikersnaam
|
||||
write_your_username: "Wijzig je gebruikersnaam"
|
||||
your_username: "Je gebruikersnaam verschijnt bij al je reacties."
|
||||
change_password:
|
||||
change_password: "Wachtwoord Wijzigen"
|
||||
passwords_dont_match: "Wachtwoorden komen niet overeen"
|
||||
required_field: "Dit veld is verplicht"
|
||||
forgot_password: "Wachtwoord vergeten?"
|
||||
save: "Opslaan"
|
||||
cancel: "Annuleren"
|
||||
edit: "Wijzigen"
|
||||
changed_password_msg: "Je wachtwoord is succesvol gewijzigd"
|
||||
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:
|
||||
|
||||
@@ -122,7 +122,10 @@ const withAuthorNameFragments = withFragments({
|
||||
});
|
||||
|
||||
const enhance = compose(
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withAuthorNameFragments
|
||||
);
|
||||
|
||||
|
||||
@@ -85,7 +85,13 @@ module.exports = {
|
||||
}),
|
||||
resolvers: {
|
||||
Comment: {
|
||||
deepReplyCount({ id }, args, { loaders: { Comments } }) {
|
||||
deepReplyCount(
|
||||
{ id },
|
||||
args,
|
||||
{
|
||||
loaders: { Comments },
|
||||
}
|
||||
) {
|
||||
return Comments.getDeepCount.load(id);
|
||||
},
|
||||
},
|
||||
|
||||
@@ -29,6 +29,8 @@ Configuration:
|
||||
guide. This is only required while the `talk-plugin-facebook-auth` plugin is
|
||||
enabled.
|
||||
|
||||
_NOTE: FabceBook auth requires your site to use `https` (SSL) not `http`. If your site is not `https` you can not use this plugin!_
|
||||
|
||||
## GDPR Compliance
|
||||
|
||||
In order to facilitate compliance with the
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { handlePopupAuth } from 'plugin-api/beta/client/utils';
|
||||
|
||||
export const loginWithFacebook = () => (dispatch, _, { rest }) => {
|
||||
window.location = `${rest.uri}/auth/facebook`;
|
||||
handlePopupAuth(`${rest.uri}/auth/facebook`);
|
||||
};
|
||||
|
||||
@@ -6,4 +6,7 @@ import FacebookButton from '../components/FacebookButton';
|
||||
const mapDispatchToProps = dispatch =>
|
||||
bindActionCreators({ onClick: loginWithFacebook }, dispatch);
|
||||
|
||||
export default connect(null, mapDispatchToProps)(FacebookButton);
|
||||
export default connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
)(FacebookButton);
|
||||
|
||||
@@ -5,6 +5,7 @@ import translations from './translations.yml';
|
||||
export default {
|
||||
translations,
|
||||
slots: {
|
||||
authExternalAdminSignIn: [SignIn],
|
||||
authExternalSignIn: [SignIn],
|
||||
authExternalSignUp: [SignUp],
|
||||
},
|
||||
|
||||
@@ -2,6 +2,10 @@ ar:
|
||||
talk-plugin-facebook-auth:
|
||||
sign_in: "تسجيل الدخول عبر حساب الفيسبوك"
|
||||
sign_up: "اشترك عبر حساب الفيسبوك"
|
||||
de:
|
||||
talk-plugin-facebook-auth:
|
||||
sign_in: "Mit Facebook anmelden"
|
||||
sign_up: "Mit Facebook registrieren"
|
||||
en:
|
||||
talk-plugin-facebook-auth:
|
||||
sign_in: "Sign in with Facebook"
|
||||
@@ -18,6 +22,10 @@ he:
|
||||
talk-plugin-facebook-auth:
|
||||
sign_in: "התחבר עם פייסבוק"
|
||||
sign_up: "הרשם עם פייסבוק"
|
||||
nl_NL:
|
||||
talk-plugin-facebook-auth:
|
||||
sign_in: "Inloggen met Facebook"
|
||||
sign_up: "Registreren met Facebook"
|
||||
zh_CN:
|
||||
talk-plugin-facebook-auth:
|
||||
sign_in: "使用 Facebook 帐号"
|
||||
@@ -26,7 +34,3 @@ zh_TW:
|
||||
talk-plugin-facebook-auth:
|
||||
sign_in: "使用 Facebook 帳號"
|
||||
sign_up: "使用 Facebook 帳號"
|
||||
de:
|
||||
talk-plugin-facebook-auth:
|
||||
sign_in: "Mit Facebook anmelden"
|
||||
sign_up: "Mit Facebook registrieren"
|
||||
|
||||
@@ -27,7 +27,7 @@ module.exports = passport => {
|
||||
try {
|
||||
const { id, provider, displayName } = profile;
|
||||
|
||||
user = await UsersService.findOrCreateExternalUser(
|
||||
user = await UsersService.upsertSocialUser(
|
||||
req.context,
|
||||
id,
|
||||
provider,
|
||||
|
||||
@@ -5,7 +5,11 @@ module.exports = router => {
|
||||
*/
|
||||
router.get('/api/v1/auth/facebook', (req, res, next) => {
|
||||
const {
|
||||
connectors: { services: { Passport: { passport } } },
|
||||
connectors: {
|
||||
services: {
|
||||
Passport: { passport },
|
||||
},
|
||||
},
|
||||
} = req.context;
|
||||
|
||||
return passport.authenticate('facebook', {
|
||||
@@ -22,7 +26,9 @@ module.exports = router => {
|
||||
router.get('/api/v1/auth/facebook/callback', (req, res, next) => {
|
||||
const {
|
||||
connectors: {
|
||||
services: { Passport: { passport, HandleAuthPopupCallback } },
|
||||
services: {
|
||||
Passport: { passport, HandleAuthPopupCallback },
|
||||
},
|
||||
},
|
||||
} = req.context;
|
||||
|
||||
|
||||
@@ -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')}:
|
||||
|
||||
@@ -19,7 +19,10 @@ const mapDispatchToProps = dispatch =>
|
||||
);
|
||||
|
||||
const enhance = compose(
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withTags('featured')
|
||||
);
|
||||
|
||||
|
||||
@@ -13,7 +13,10 @@ const mapDispatchToProps = dispatch =>
|
||||
);
|
||||
|
||||
const enhance = compose(
|
||||
connect(null, mapDispatchToProps),
|
||||
connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withTags('featured')
|
||||
);
|
||||
|
||||
|
||||
+14
-2
@@ -12,7 +12,13 @@ class ModIndicatorSubscription extends React.Component {
|
||||
document: COMMENT_FEATURED_SUBSCRIPTION,
|
||||
updateQuery: (
|
||||
prev,
|
||||
{ subscriptionData: { data: { commentFeatured: { comment } } } }
|
||||
{
|
||||
subscriptionData: {
|
||||
data: {
|
||||
commentFeatured: { comment },
|
||||
},
|
||||
},
|
||||
}
|
||||
) => {
|
||||
return this.props.handleCommentChange(prev, comment);
|
||||
},
|
||||
@@ -21,7 +27,13 @@ class ModIndicatorSubscription extends React.Component {
|
||||
document: COMMENT_UNFEATURED_SUBSCRIPTION,
|
||||
updateQuery: (
|
||||
prev,
|
||||
{ subscriptionData: { data: { commentUnfeatured: { comment } } } }
|
||||
{
|
||||
subscriptionData: {
|
||||
data: {
|
||||
commentUnfeatured: { comment },
|
||||
},
|
||||
},
|
||||
}
|
||||
) => {
|
||||
return this.props.handleCommentChange(prev, comment);
|
||||
},
|
||||
|
||||
@@ -28,7 +28,13 @@ class ModSubscription extends React.Component {
|
||||
},
|
||||
updateQuery: (
|
||||
prev,
|
||||
{ subscriptionData: { data: { commentFeatured: { user, comment } } } }
|
||||
{
|
||||
subscriptionData: {
|
||||
data: {
|
||||
commentFeatured: { user, comment },
|
||||
},
|
||||
},
|
||||
}
|
||||
) => {
|
||||
const notifyText =
|
||||
this.props.user.id === user.id
|
||||
@@ -50,7 +56,9 @@ class ModSubscription extends React.Component {
|
||||
prev,
|
||||
{
|
||||
subscriptionData: {
|
||||
data: { commentUnfeatured: { user, comment } },
|
||||
data: {
|
||||
commentUnfeatured: { user, comment },
|
||||
},
|
||||
},
|
||||
}
|
||||
) => {
|
||||
@@ -117,7 +125,10 @@ const mapStateToProps = state => ({
|
||||
});
|
||||
|
||||
export default compose(
|
||||
connect(mapStateToProps, null),
|
||||
connect(
|
||||
mapStateToProps,
|
||||
null
|
||||
),
|
||||
withVariables,
|
||||
withSubscribeToMore
|
||||
)(ModSubscription);
|
||||
|
||||
@@ -22,7 +22,10 @@ const fragments = {
|
||||
`,
|
||||
};
|
||||
const enhance = compose(
|
||||
connect(null, mapDispatchToProps),
|
||||
connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withTags('featured', { fragments })
|
||||
);
|
||||
|
||||
|
||||
@@ -90,7 +90,10 @@ const mapDispatchToProps = dispatch =>
|
||||
);
|
||||
|
||||
const enhance = compose(
|
||||
connect(null, mapDispatchToProps),
|
||||
connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withFetchMore,
|
||||
withVariables,
|
||||
withFragments({
|
||||
|
||||
@@ -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
|
||||
@@ -117,19 +117,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: "取消精选"
|
||||
|
||||
@@ -59,8 +59,14 @@ module.exports = {
|
||||
addTag: {
|
||||
async post(
|
||||
obj,
|
||||
{ tag: { name, id, item_type } },
|
||||
{ user, mutators: { Comment }, pubsub }
|
||||
{
|
||||
tag: { name, id, item_type },
|
||||
},
|
||||
{
|
||||
user,
|
||||
mutators: { Comment },
|
||||
pubsub,
|
||||
}
|
||||
) {
|
||||
if (name === 'FEATURED' && item_type === 'COMMENTS') {
|
||||
const comment = await Comment.setStatus({
|
||||
@@ -76,8 +82,14 @@ module.exports = {
|
||||
removeTag: {
|
||||
async post(
|
||||
obj,
|
||||
{ tag: { name, id, item_type } },
|
||||
{ user, loaders: { Comments }, pubsub }
|
||||
{
|
||||
tag: { name, id, item_type },
|
||||
},
|
||||
{
|
||||
user,
|
||||
loaders: { Comments },
|
||||
pubsub,
|
||||
}
|
||||
) {
|
||||
if (name === 'FEATURED' && item_type === 'COMMENTS') {
|
||||
const comment = await Comments.get.load(id);
|
||||
|
||||
@@ -10,7 +10,12 @@ import {
|
||||
|
||||
class FlagDetails extends Component {
|
||||
render() {
|
||||
const { comment: { actions }, more, root, comment } = this.props;
|
||||
const {
|
||||
comment: { actions },
|
||||
more,
|
||||
root,
|
||||
comment,
|
||||
} = this.props;
|
||||
|
||||
const flagActions =
|
||||
actions && actions.filter(a => a.__typename === 'FlagAction');
|
||||
|
||||
@@ -5,7 +5,10 @@ import styles from './UserFlagDetails.css';
|
||||
|
||||
class UserFlagDetails extends Component {
|
||||
render() {
|
||||
const { comment: { actions }, viewUserDetail } = this.props;
|
||||
const {
|
||||
comment: { actions },
|
||||
viewUserDetail,
|
||||
} = this.props;
|
||||
|
||||
const flagActions =
|
||||
actions && actions.filter(a => a.__typename === 'FlagAction');
|
||||
|
||||
@@ -15,7 +15,10 @@ const mapDispatchToProps = dispatch => ({
|
||||
});
|
||||
|
||||
const enhance = compose(
|
||||
connect(null, mapDispatchToProps),
|
||||
connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withFragments({
|
||||
comment: gql`
|
||||
fragment CoralAdmin_UserFlagDetails_comment on Comment {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { handlePopupAuth } from 'plugin-api/beta/client/utils';
|
||||
|
||||
export const loginWithGoogle = () => (dispatch, _, { rest }) => {
|
||||
window.location = `${rest.uri}/auth/google`;
|
||||
handlePopupAuth(`${rest.uri}/auth/google`);
|
||||
};
|
||||
|
||||
@@ -6,4 +6,7 @@ import GoogleButton from '../components/GoogleButton';
|
||||
const mapDispatchToProps = dispatch =>
|
||||
bindActionCreators({ onClick: loginWithGoogle }, dispatch);
|
||||
|
||||
export default connect(null, mapDispatchToProps)(GoogleButton);
|
||||
export default connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
)(GoogleButton);
|
||||
|
||||
@@ -5,6 +5,7 @@ import translations from './translations.yml';
|
||||
export default {
|
||||
translations,
|
||||
slots: {
|
||||
authExternalAdminSignIn: [SignIn],
|
||||
authExternalSignIn: [SignIn],
|
||||
authExternalSignUp: [SignUp],
|
||||
},
|
||||
|
||||
@@ -8,21 +8,25 @@ 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"
|
||||
en:
|
||||
sign_in: "Connectez-vous avec Google"
|
||||
sign_up: "Inscrivez-vous avec Google"
|
||||
he:
|
||||
talk-plugin-google-auth:
|
||||
sign_in: "התחבר עם גוגל"
|
||||
sign_up: "הרשם עם גוגל"
|
||||
nl_NL:
|
||||
talk-plugin-google-auth:
|
||||
sign_in: "Inloggen met Google"
|
||||
sign_up: "Registeren met 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 帳號"
|
||||
|
||||
@@ -26,7 +26,7 @@ module.exports = passport => {
|
||||
try {
|
||||
const { id, provider, displayName } = profile;
|
||||
|
||||
user = await UsersService.findOrCreateExternalUser(
|
||||
user = await UsersService.upsertSocialUser(
|
||||
req.context,
|
||||
id,
|
||||
provider,
|
||||
|
||||
@@ -45,7 +45,10 @@ const withIgnoreUserActionFragments = withFragments({
|
||||
});
|
||||
|
||||
const enhance = compose(
|
||||
connect(null, mapDispatchToProps),
|
||||
connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withIgnoreUserActionFragments,
|
||||
excludeIf(({ root: { me }, comment }) => !me || me.id === comment.user.id)
|
||||
);
|
||||
|
||||
@@ -65,7 +65,10 @@ const withIgnoreUserConfirmationFragments = withFragments({
|
||||
});
|
||||
|
||||
const enhance = compose(
|
||||
connect(null, mapDispatchToProps),
|
||||
connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withIgnoreUserConfirmationFragments,
|
||||
withIgnoreUser
|
||||
);
|
||||
|
||||
@@ -37,6 +37,9 @@ const withIgnoredUserSectionFragments = withFragments({
|
||||
`,
|
||||
});
|
||||
|
||||
const enhance = compose(withIgnoredUserSectionFragments, withStopIgnoringUser);
|
||||
const enhance = compose(
|
||||
withIgnoredUserSectionFragments,
|
||||
withStopIgnoringUser
|
||||
);
|
||||
|
||||
export default enhance(IgnoredUserSectionContainer);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
ar:
|
||||
talk-plugin-ignore-user:
|
||||
blank_info: أنت لا تتجاهل حاليًا أي مستخدم
|
||||
section_title: المستخدمون الذين تم تجاهلهم
|
||||
section_info: لأنك تجاهلت المعلقين التاليين، يتم إخفاء تعليقاتهم.
|
||||
stop_ignoring: إيقاف التجاهل
|
||||
@@ -25,6 +26,7 @@ da:
|
||||
confirmation_title: Ignore {0}?
|
||||
de:
|
||||
talk-plugin-ignore-user:
|
||||
blank_info: Sie ignorieren derzeit keine Nutzer
|
||||
section_title: Ignorierte Nutzer
|
||||
section_info: Weil Sie die folgenden Nutzer ignorieren, sind deren Kommentare versteckt.
|
||||
stop_ignoring: Ignorieren beenden
|
||||
@@ -35,30 +37,32 @@ de:
|
||||
confirmation_title: "{0} ignorieren?"
|
||||
en:
|
||||
talk-plugin-ignore-user:
|
||||
blank_info: You are currently not ignoring any users
|
||||
section_title: Ignored users
|
||||
section_info: Because you ignored the following commenters, their comments are hidden.
|
||||
stop_ignoring: Stop ignoring
|
||||
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.
|
||||
notify_success: |
|
||||
You are now ignoring {0}. You can undo this action from My Profile.
|
||||
confirmation_title: Ignore {0}?
|
||||
es:
|
||||
talk-plugin-ignore-user:
|
||||
section_title: "Usuarios ignorados"
|
||||
section_info: Because you ignored the following commenters, their comments are hidden.
|
||||
stop_ignoring: "No ignorar más"
|
||||
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.
|
||||
notify_success: |
|
||||
You are now ignoring {0}. You can undo this action from My Profile.
|
||||
confirmation_title: Ignore {0}?
|
||||
es:
|
||||
talk-plugin-ignore-user:
|
||||
section_title: "Usuarios ignorados"
|
||||
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: Ignorar usuario
|
||||
cancel: Cancelar
|
||||
confirmation: |
|
||||
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: |
|
||||
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"
|
||||
@@ -99,17 +103,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: "被忽略用户"
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import * as actions from './constants';
|
||||
|
||||
export const startAttach = () => ({
|
||||
type: actions.START_ATTACH,
|
||||
});
|
||||
|
||||
export const finishAttach = () => ({
|
||||
type: actions.FINISH_ATTACH,
|
||||
});
|
||||
+5
-33
@@ -1,15 +1,3 @@
|
||||
.dialog {
|
||||
border: none;
|
||||
box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2);
|
||||
width: 320px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
padding: 20px;
|
||||
border-radius: 4px;
|
||||
font-family: Helvetica,Helvetica Neue,Verdana,sans-serif;
|
||||
color:#3B4A53;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.3em;
|
||||
margin: 15px 0;
|
||||
@@ -28,7 +16,7 @@
|
||||
margin: 20px 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
@@ -46,37 +34,21 @@
|
||||
font-size: 1.3em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.button {
|
||||
color: #787D80;
|
||||
border-radius: 2px;
|
||||
background-color: transparent;
|
||||
height: 30px;
|
||||
font-size: 0.9em;
|
||||
line-height: normal;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
font-size: 1em;
|
||||
background-color: #3498DB;
|
||||
color: white;
|
||||
|
||||
&:hover {
|
||||
background-color: #eaeaea;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.cancel {
|
||||
background-color: transparent;
|
||||
color: #787D80;
|
||||
}
|
||||
|
||||
&.proceed {
|
||||
background-color: #3498DB;
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.danger {
|
||||
background-color: #FA4643;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './AddEmailForm.css';
|
||||
import { Icon } from 'plugin-api/beta/client/components/ui';
|
||||
import InputField from '../InputField';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
import {
|
||||
composeValidators,
|
||||
required,
|
||||
verifyEmail,
|
||||
confirmEmail,
|
||||
verifyPassword,
|
||||
confirmPassword,
|
||||
} from 'coral-framework/lib/validation';
|
||||
import { Form, Field } from 'react-final-form';
|
||||
|
||||
const AddEmailContent = ({ onSubmit }) => (
|
||||
<div>
|
||||
<h4 className={styles.title}>
|
||||
{t('talk-plugin-local-auth.add_email.content.title')}
|
||||
</h4>
|
||||
<p className={styles.description}>
|
||||
{t('talk-plugin-local-auth.add_email.content.description')}
|
||||
</p>
|
||||
<ul className={styles.list}>
|
||||
<li className={styles.item}>
|
||||
<Icon name="done" className={styles.itemIcon} />
|
||||
<span className={styles.text}>
|
||||
{t('talk-plugin-local-auth.add_email.content.item_1')}
|
||||
</span>
|
||||
</li>
|
||||
<li className={styles.item}>
|
||||
<Icon name="done" className={styles.itemIcon} />
|
||||
<span className={styles.text}>
|
||||
{t('talk-plugin-local-auth.add_email.content.item_2')}
|
||||
</span>
|
||||
</li>
|
||||
<li className={styles.item}>
|
||||
<Icon name="done" className={styles.itemIcon} />
|
||||
<span className={styles.text}>
|
||||
{t('talk-plugin-local-auth.add_email.content.item_3')}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<Form onSubmit={onSubmit}>
|
||||
{({ handleSubmit, submitting }) => (
|
||||
<form autoComplete="off" onSubmit={handleSubmit}>
|
||||
<Field
|
||||
name="email"
|
||||
validate={composeValidators(required, verifyEmail)}
|
||||
>
|
||||
{({ input, meta }) => (
|
||||
<InputField
|
||||
label={t(
|
||||
'talk-plugin-local-auth.add_email.enter_email_address'
|
||||
)}
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
errorMsg={meta.error}
|
||||
showError={meta.touched}
|
||||
columnDisplay
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
<Field name="confirmEmail" validate={confirmEmail('email')}>
|
||||
{({ input, meta }) => (
|
||||
<InputField
|
||||
label={t(
|
||||
'talk-plugin-local-auth.add_email.confirm_email_address'
|
||||
)}
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
errorMsg={meta.error}
|
||||
showError={meta.touched}
|
||||
columnDisplay
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
<Field
|
||||
name="password"
|
||||
validate={composeValidators(required, verifyPassword)}
|
||||
>
|
||||
{({ input, meta }) => (
|
||||
<InputField
|
||||
label={t('talk-plugin-local-auth.add_email.insert_password')}
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
errorMsg={meta.error}
|
||||
showError={meta.touched}
|
||||
type="password"
|
||||
columnDisplay
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
<Field name="confirmPassword" validate={confirmPassword('password')}>
|
||||
{({ input, meta }) => (
|
||||
<InputField
|
||||
label={t('talk-plugin-local-auth.add_email.confirm_password')}
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
errorMsg={meta.error}
|
||||
showError={meta.touched}
|
||||
type="password"
|
||||
columnDisplay
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
<div>
|
||||
<button className={styles.button} disabled={submitting}>
|
||||
{t('talk-plugin-local-auth.add_email.add_email_address')}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
|
||||
AddEmailContent.propTypes = {
|
||||
onSubmit: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default AddEmailContent;
|
||||
@@ -0,0 +1,11 @@
|
||||
.root {
|
||||
border: none;
|
||||
box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2);
|
||||
width: 320px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
padding: 20px;
|
||||
border-radius: 4px;
|
||||
font-family: Helvetica,Helvetica Neue,Verdana,sans-serif;
|
||||
color:#3B4A53;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Dialog } from 'plugin-api/beta/client/components/ui';
|
||||
import styles from './Dialog.css';
|
||||
|
||||
export default props => <Dialog className={styles.root} {...props} />;
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
.title {
|
||||
font-size: 1.3em;
|
||||
margin: 15px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1em;
|
||||
line-height: 20px;
|
||||
margin: 0;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.button {
|
||||
color: #787D80;
|
||||
border-radius: 2px;
|
||||
height: 30px;
|
||||
font-size: 0.9em;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
font-size: 1em;
|
||||
background-color: #3498DB;
|
||||
color: white;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
+6
-7
@@ -1,10 +1,9 @@
|
||||
import React from 'react';
|
||||
import cn from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './AddEmailAddressDialog.css';
|
||||
import styles from './EmailAddressAdded.css';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
|
||||
const EmailAddressAdded = ({ done }) => (
|
||||
const EmailAddressAdded = ({ onDone }) => (
|
||||
<div>
|
||||
<h4 className={styles.title}>
|
||||
{t('talk-plugin-local-auth.add_email.added.title')}
|
||||
@@ -17,16 +16,16 @@ const EmailAddressAdded = ({ done }) => (
|
||||
{t('talk-plugin-local-auth.add_email.added.description_2')}{' '}
|
||||
<strong>{t('talk-plugin-local-auth.add_email.added.path')}</strong>.
|
||||
</p>
|
||||
<div className={styles.actions}>
|
||||
<a className={cn(styles.button, styles.proceed)} onClick={done}>
|
||||
<div>
|
||||
<button className={styles.button} onClick={onDone}>
|
||||
{t('talk-plugin-local-auth.add_email.done')}
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
EmailAddressAdded.propTypes = {
|
||||
done: PropTypes.func.isRequired,
|
||||
onDone: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default EmailAddressAdded;
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
.title {
|
||||
font-size: 1.3em;
|
||||
margin: 15px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1em;
|
||||
line-height: 20px;
|
||||
margin: 0;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.button {
|
||||
color: #787D80;
|
||||
border-radius: 2px;
|
||||
height: 30px;
|
||||
font-size: 0.9em;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
font-size: 1em;
|
||||
background-color: #3498DB;
|
||||
color: white;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
+6
-7
@@ -1,10 +1,9 @@
|
||||
import React from 'react';
|
||||
import cn from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './AddEmailAddressDialog.css';
|
||||
import styles from './VerifyEmailAddress.css';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
|
||||
const VerifyEmailAddress = ({ emailAddress, done }) => (
|
||||
const VerifyEmailAddress = ({ emailAddress, onDone }) => (
|
||||
<div>
|
||||
<h4 className={styles.title}>
|
||||
{t('talk-plugin-local-auth.add_email.verify.title')}
|
||||
@@ -12,17 +11,17 @@ const VerifyEmailAddress = ({ emailAddress, done }) => (
|
||||
<p className={styles.description}>
|
||||
{t('talk-plugin-local-auth.add_email.verify.description', emailAddress)}
|
||||
</p>
|
||||
<div className={styles.actions}>
|
||||
<a className={cn(styles.button, styles.proceed)} onClick={done}>
|
||||
<div>
|
||||
<button className={styles.button} onClick={onDone}>
|
||||
{t('talk-plugin-local-auth.add_email.done')}
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
VerifyEmailAddress.propTypes = {
|
||||
emailAddress: PropTypes.string.isRequired,
|
||||
done: PropTypes.func.isRequired,
|
||||
onDone: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default VerifyEmailAddress;
|
||||
@@ -0,0 +1,4 @@
|
||||
export { default as AddEmailForm } from './AddEmailForm';
|
||||
export { default as Dialog } from './Dialog';
|
||||
export { default as EmailAddressAdded } from './EmailAddressAdded';
|
||||
export { default as VerifyEmailAddress } from './VerifyEmailAddress';
|
||||
@@ -1,166 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Dialog } from 'plugin-api/beta/client/components/ui';
|
||||
import validate from 'coral-framework/helpers/validate';
|
||||
import { getErrorMessages } from 'coral-framework/utils';
|
||||
import styles from './AddEmailAddressDialog.css';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
|
||||
import AddEmailContent from './AddEmailContent';
|
||||
import VerifyEmailAddress from './VerifyEmailAddress';
|
||||
import EmailAddressAdded from './EmailAddressAdded';
|
||||
|
||||
const initialState = {
|
||||
step: 0,
|
||||
showErrors: false,
|
||||
errors: {},
|
||||
formData: {
|
||||
emailAddress: '',
|
||||
confirmPassword: '',
|
||||
confirmEmailAddress: '',
|
||||
},
|
||||
};
|
||||
|
||||
const validateRequired = v =>
|
||||
v ? '' : t('talk-plugin-local-auth.add_email.required_field');
|
||||
|
||||
const validateRepeat = (key, msg) => (v, data) => (v !== data[key] ? msg : '');
|
||||
|
||||
const validateEmail = v =>
|
||||
validateRequired(v) || !validate.email(v)
|
||||
? t('talk-plugin-local-auth.add_email.invalid_email_address')
|
||||
: '';
|
||||
|
||||
const validatePassword = v => validateRequired(v);
|
||||
|
||||
class AddEmailAddressDialog extends React.Component {
|
||||
state = initialState;
|
||||
|
||||
fields = {
|
||||
emailAddress: validateEmail,
|
||||
confirmPassword: validatePassword,
|
||||
confirmEmailAddress: validateRepeat(
|
||||
'emailAddress',
|
||||
t('talk-plugin-local-auth.add_email.confirm_email_address')
|
||||
),
|
||||
};
|
||||
|
||||
onChange = e => {
|
||||
const { name, value } = e.target;
|
||||
this.setState(
|
||||
state => ({
|
||||
formData: {
|
||||
...state.formData,
|
||||
[name]: value,
|
||||
},
|
||||
}),
|
||||
() => {
|
||||
this.validate();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
validateField = (value, name) => {
|
||||
const error = this.fields[name](value, this.state.formData);
|
||||
if (error) {
|
||||
this.addError({ [name]: error });
|
||||
return false;
|
||||
}
|
||||
this.removeError(name);
|
||||
return true;
|
||||
};
|
||||
|
||||
addError = err => {
|
||||
this.setState(({ errors }) => ({
|
||||
errors: { ...errors, ...err },
|
||||
}));
|
||||
};
|
||||
|
||||
validate() {
|
||||
let hasErrors = false;
|
||||
Object.keys(this.state.formData).forEach(k => {
|
||||
hasErrors = !this.validateField(this.state.formData[k], k) || hasErrors;
|
||||
});
|
||||
return !hasErrors;
|
||||
}
|
||||
|
||||
removeError = errKey => {
|
||||
this.setState(state => {
|
||||
const { [errKey]: _, ...errors } = state.errors;
|
||||
return {
|
||||
errors,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
showErrors = () => {
|
||||
this.setState({
|
||||
showErrors: true,
|
||||
});
|
||||
};
|
||||
|
||||
confirmChanges = async () => {
|
||||
if (!this.validate()) {
|
||||
this.showErrors();
|
||||
return;
|
||||
}
|
||||
|
||||
const { emailAddress, confirmPassword } = this.state.formData;
|
||||
const { attachLocalAuth } = this.props;
|
||||
|
||||
try {
|
||||
await attachLocalAuth({
|
||||
email: emailAddress,
|
||||
password: confirmPassword,
|
||||
});
|
||||
this.props.notify('success', 'Email Added!');
|
||||
this.goToNextStep();
|
||||
} catch (err) {
|
||||
this.props.notify('error', getErrorMessages(err));
|
||||
}
|
||||
};
|
||||
|
||||
goToNextStep = () => {
|
||||
this.setState(({ step }) => ({
|
||||
step: step + 1,
|
||||
}));
|
||||
};
|
||||
|
||||
render() {
|
||||
const { errors, formData, showErrors, step } = this.state;
|
||||
const { root: { settings } } = this.props;
|
||||
|
||||
return (
|
||||
<Dialog className={styles.dialog} open={true}>
|
||||
{step === 0 && (
|
||||
<AddEmailContent
|
||||
formData={formData}
|
||||
errors={errors}
|
||||
showErrors={showErrors}
|
||||
confirmChanges={this.confirmChanges}
|
||||
onChange={this.onChange}
|
||||
/>
|
||||
)}
|
||||
{step === 1 &&
|
||||
!settings.requireEmailConfirmation && (
|
||||
<EmailAddressAdded done={() => {}} />
|
||||
)}
|
||||
{step === 1 &&
|
||||
settings.requireEmailConfirmation && (
|
||||
<VerifyEmailAddress
|
||||
emailAddress={formData.emailAddress}
|
||||
done={() => {}}
|
||||
/>
|
||||
)}
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AddEmailAddressDialog.propTypes = {
|
||||
attachLocalAuth: PropTypes.func.isRequired,
|
||||
notify: PropTypes.func.isRequired,
|
||||
root: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default AddEmailAddressDialog;
|
||||
@@ -1,104 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './AddEmailAddressDialog.css';
|
||||
import { Icon } from 'plugin-api/beta/client/components/ui';
|
||||
import cn from 'classnames';
|
||||
import InputField from './InputField';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
|
||||
const AddEmailContent = ({
|
||||
formData,
|
||||
errors,
|
||||
showErrors,
|
||||
confirmChanges,
|
||||
onChange,
|
||||
}) => (
|
||||
<div>
|
||||
<h4 className={styles.title}>
|
||||
{t('talk-plugin-local-auth.add_email.content.title')}
|
||||
</h4>
|
||||
<p className={styles.description}>
|
||||
{t('talk-plugin-local-auth.add_email.content.description')}
|
||||
</p>
|
||||
<ul className={styles.list}>
|
||||
<li className={styles.item}>
|
||||
<Icon name="done" className={styles.itemIcon} />
|
||||
<span className={styles.text}>
|
||||
{t('talk-plugin-local-auth.add_email.content.item_1')}
|
||||
</span>
|
||||
</li>
|
||||
<li className={styles.item}>
|
||||
<Icon name="done" className={styles.itemIcon} />
|
||||
<span className={styles.text}>
|
||||
{t('talk-plugin-local-auth.add_email.content.item_2')}
|
||||
</span>
|
||||
</li>
|
||||
<li className={styles.item}>
|
||||
<Icon name="done" className={styles.itemIcon} />
|
||||
<span className={styles.text}>
|
||||
{t('talk-plugin-local-auth.add_email.content.item_3')}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<form autoComplete="off">
|
||||
<InputField
|
||||
id="emailAddress"
|
||||
label={t('talk-plugin-local-auth.add_email.enter_email_address')}
|
||||
name="emailAddress"
|
||||
type="email"
|
||||
onChange={onChange}
|
||||
value={formData.emailAddress}
|
||||
hasError={!!errors.emailAddress}
|
||||
errorMsg={errors.emailAddress}
|
||||
showError={showErrors}
|
||||
columnDisplay
|
||||
showSuccess={false}
|
||||
/>
|
||||
<InputField
|
||||
id="confirmEmailAddress"
|
||||
label={t('talk-plugin-local-auth.add_email.confirm_email_address')}
|
||||
name="confirmEmailAddress"
|
||||
type="email"
|
||||
onChange={onChange}
|
||||
value={formData.confirmEmailAddress}
|
||||
hasError={!!errors.confirmEmailAddress}
|
||||
errorMsg={errors.confirmEmailAddress}
|
||||
showError={showErrors}
|
||||
columnDisplay
|
||||
showSuccess={false}
|
||||
/>
|
||||
<InputField
|
||||
id="confirmPassword"
|
||||
label={t('talk-plugin-local-auth.add_email.insert_password')}
|
||||
name="confirmPassword"
|
||||
type="password"
|
||||
onChange={onChange}
|
||||
value={formData.confirmPassword}
|
||||
hasError={!!errors.confirmPassword}
|
||||
errorMsg={errors.confirmPassword}
|
||||
showError={showErrors}
|
||||
columnDisplay
|
||||
showSuccess={false}
|
||||
/>
|
||||
<div className={styles.actions}>
|
||||
<a
|
||||
className={cn(styles.button, styles.proceed)}
|
||||
onClick={confirmChanges}
|
||||
>
|
||||
{t('talk-plugin-local-auth.add_email.add_email_address')}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
|
||||
AddEmailContent.propTypes = {
|
||||
formData: PropTypes.object.isRequired,
|
||||
errors: PropTypes.object.isRequired,
|
||||
showErrors: PropTypes.bool.isRequired,
|
||||
confirmChanges: PropTypes.func.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default AddEmailContent;
|
||||
@@ -4,10 +4,74 @@ import styles from './ChangeEmailContentDialog.css';
|
||||
import InputField from './InputField';
|
||||
import { Button } from 'plugin-api/beta/client/components/ui';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
import validate from 'coral-framework/helpers/validate';
|
||||
import errorMsj from 'coral-framework/helpers/error';
|
||||
|
||||
const initialState = {
|
||||
showError: false,
|
||||
formData: {
|
||||
confirmPassword: '',
|
||||
},
|
||||
errors: {},
|
||||
};
|
||||
|
||||
class ChangeEmailContentDialog extends React.Component {
|
||||
state = {
|
||||
showError: false,
|
||||
state = initialState;
|
||||
|
||||
clearForm = () => {
|
||||
this.setState(initialState);
|
||||
};
|
||||
|
||||
addError = err => {
|
||||
this.setState(({ errors }) => ({
|
||||
errors: { ...errors, ...err },
|
||||
}));
|
||||
};
|
||||
|
||||
removeError = errKey => {
|
||||
this.setState(state => {
|
||||
const { [errKey]: _, ...errors } = state.errors;
|
||||
return {
|
||||
errors,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
fieldValidation = (value, type, name) => {
|
||||
if (!value.length) {
|
||||
this.addError({
|
||||
[name]: t('talk-plugin-local-auth.change_password.required_field'),
|
||||
});
|
||||
} else if (!validate[type](value)) {
|
||||
this.addError({ [name]: errorMsj[type] });
|
||||
} else {
|
||||
this.removeError(name);
|
||||
}
|
||||
};
|
||||
|
||||
onChange = e => {
|
||||
const { name, value, type, dataset } = e.target;
|
||||
const validationType = dataset.validationType || type;
|
||||
|
||||
this.setState(
|
||||
state => ({
|
||||
formData: {
|
||||
...state.formData,
|
||||
[name]: value,
|
||||
},
|
||||
}),
|
||||
() => {
|
||||
this.fieldValidation(value, validationType, name);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
hasError = err => {
|
||||
return Object.keys(this.state.errors).indexOf(err) !== -1;
|
||||
};
|
||||
|
||||
getError = errorKey => {
|
||||
return this.state.errors[errorKey];
|
||||
};
|
||||
|
||||
showError = () => {
|
||||
@@ -16,24 +80,31 @@ class ChangeEmailContentDialog extends React.Component {
|
||||
});
|
||||
};
|
||||
|
||||
cancel = () => {
|
||||
this.clearForm();
|
||||
this.props.closeDialog();
|
||||
};
|
||||
|
||||
confirmChanges = async e => {
|
||||
e.preventDefault();
|
||||
|
||||
const { confirmPassword = '' } = this.state.formData;
|
||||
|
||||
if (this.formHasError()) {
|
||||
this.showError();
|
||||
return;
|
||||
}
|
||||
|
||||
await this.props.save();
|
||||
await this.props.save(confirmPassword);
|
||||
this.props.next();
|
||||
};
|
||||
|
||||
formHasError = () => this.props.hasError('confirmPassword');
|
||||
formHasError = () => this.hasError('confirmPassword');
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<span className={styles.close} onClick={this.props.cancel}>
|
||||
<span className={styles.close} onClick={this.cancel}>
|
||||
×
|
||||
</span>
|
||||
<h1 className={styles.title}>
|
||||
@@ -59,17 +130,17 @@ class ChangeEmailContentDialog extends React.Component {
|
||||
label={t('talk-plugin-local-auth.change_email.enter_password')}
|
||||
name="confirmPassword"
|
||||
type="password"
|
||||
onChange={this.props.onChange}
|
||||
defaultValue=""
|
||||
hasError={this.props.hasError('confirmPassword')}
|
||||
errorMsg={this.props.getError('confirmPassword')}
|
||||
onChange={this.onChange}
|
||||
value={this.state.formData.confirmPassword}
|
||||
hasError={this.hasError('confirmPassword')}
|
||||
errorMsg={this.getError('confirmPassword')}
|
||||
showError={this.state.showError}
|
||||
columnDisplay
|
||||
/>
|
||||
<div className={styles.bottomActions}>
|
||||
<Button
|
||||
className={styles.cancel}
|
||||
onClick={this.props.cancel}
|
||||
onClick={this.cancel}
|
||||
type="button"
|
||||
>
|
||||
{t('talk-plugin-local-auth.change_email.cancel')}
|
||||
@@ -86,14 +157,11 @@ class ChangeEmailContentDialog extends React.Component {
|
||||
}
|
||||
|
||||
ChangeEmailContentDialog.propTypes = {
|
||||
save: PropTypes.func,
|
||||
next: PropTypes.func,
|
||||
cancel: PropTypes.func,
|
||||
onChange: PropTypes.func,
|
||||
save: PropTypes.func,
|
||||
formData: PropTypes.object,
|
||||
email: PropTypes.string,
|
||||
hasError: PropTypes.func,
|
||||
getError: PropTypes.func,
|
||||
closeDialog: PropTypes.func,
|
||||
};
|
||||
|
||||
export default ChangeEmailContentDialog;
|
||||
|
||||
@@ -135,7 +135,11 @@ class ChangePassword extends React.Component {
|
||||
};
|
||||
|
||||
onForgotPassword = async () => {
|
||||
const { root: { me: { email } } } = this.props;
|
||||
const {
|
||||
root: {
|
||||
me: { email },
|
||||
},
|
||||
} = this.props;
|
||||
|
||||
try {
|
||||
await this.props.forgotPassword(email);
|
||||
@@ -185,7 +189,7 @@ class ChangePassword extends React.Component {
|
||||
>
|
||||
<InputField
|
||||
id="oldPassword"
|
||||
label="Old Password"
|
||||
label={t('talk-plugin-local-auth.change_password.old_password')}
|
||||
name="oldPassword"
|
||||
type="password"
|
||||
onChange={this.onChange}
|
||||
@@ -205,7 +209,7 @@ class ChangePassword extends React.Component {
|
||||
</InputField>
|
||||
<InputField
|
||||
id="newPassword"
|
||||
label="New Password"
|
||||
label={t('talk-plugin-local-auth.change_password.new_password')}
|
||||
name="newPassword"
|
||||
type="password"
|
||||
onChange={this.onChange}
|
||||
@@ -216,7 +220,9 @@ class ChangePassword extends React.Component {
|
||||
/>
|
||||
<InputField
|
||||
id="confirmNewPassword"
|
||||
label="Confirm New Password"
|
||||
label={t(
|
||||
'talk-plugin-local-auth.change_password.confirm_new_password'
|
||||
)}
|
||||
name="confirmNewPassword"
|
||||
type="password"
|
||||
onChange={this.onChange}
|
||||
|
||||
@@ -65,7 +65,7 @@ class ChangeUsernameContentDialog extends React.Component {
|
||||
<form onSubmit={this.confirmChanges}>
|
||||
<InputField
|
||||
id="confirmNewUsername"
|
||||
label="Re-enter new username"
|
||||
label={t('talk-plugin-local-auth.change_username.re_enter')}
|
||||
name="confirmNewUsername"
|
||||
type="text"
|
||||
onChange={this.props.onChange}
|
||||
|
||||
@@ -4,6 +4,7 @@ import cn from 'classnames';
|
||||
import styles from './InputField.css';
|
||||
import ErrorMessage from './ErrorMessage';
|
||||
import { Icon } from 'plugin-api/beta/client/components/ui';
|
||||
import uuid from 'uuid/v4';
|
||||
|
||||
const InputField = ({
|
||||
id = '',
|
||||
@@ -12,7 +13,6 @@ const InputField = ({
|
||||
name = '',
|
||||
onChange = () => {},
|
||||
showError = true,
|
||||
hasError = false,
|
||||
errorMsg = '',
|
||||
children,
|
||||
columnDisplay = false,
|
||||
@@ -27,12 +27,13 @@ const InputField = ({
|
||||
...(value !== undefined ? { value } : {}),
|
||||
...(defaultValue !== undefined ? { defaultValue } : {}),
|
||||
};
|
||||
const computedId = id || (label && uuid());
|
||||
|
||||
return (
|
||||
<div className={styles.detailItem}>
|
||||
<div className={cn(styles.detailItemContainer)}>
|
||||
{label && (
|
||||
<label className={styles.detailLabel} id={id}>
|
||||
<label className={styles.detailLabel} id={computedId}>
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
@@ -44,13 +45,13 @@ const InputField = ({
|
||||
<div
|
||||
className={cn(
|
||||
styles.detailInput,
|
||||
{ [styles.error]: hasError && showError },
|
||||
{ [styles.error]: errorMsg && showError },
|
||||
{ [styles.disabled]: disabled }
|
||||
)}
|
||||
>
|
||||
{icon && <Icon name={icon} className={styles.detailIcon} />}
|
||||
<input
|
||||
id={id}
|
||||
id={computedId}
|
||||
type={type}
|
||||
name={name}
|
||||
className={styles.detailValue}
|
||||
@@ -62,12 +63,12 @@ const InputField = ({
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.detailItemMessage}>
|
||||
{!hasError &&
|
||||
{!errorMsg &&
|
||||
showSuccess &&
|
||||
value && (
|
||||
<Icon className={styles.checkIcon} name="check_circle" />
|
||||
)}
|
||||
{hasError && showError && <ErrorMessage>{errorMsg}</ErrorMessage>}
|
||||
{errorMsg && showError && <ErrorMessage>{errorMsg}</ErrorMessage>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -87,7 +88,6 @@ InputField.propTypes = {
|
||||
defaultValue: PropTypes.string,
|
||||
icon: PropTypes.string,
|
||||
showError: PropTypes.bool,
|
||||
hasError: PropTypes.bool,
|
||||
errorMsg: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
columnDisplay: PropTypes.bool,
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
import * as React from 'react';
|
||||
|
||||
const Label = props => <div {...props} />;
|
||||
export default Label;
|
||||
@@ -114,7 +114,11 @@ class Profile extends React.Component {
|
||||
|
||||
isSaveEnabled = () => {
|
||||
const { formData } = this.state;
|
||||
const { root: { me: { username, email } } } = this.props;
|
||||
const {
|
||||
root: {
|
||||
me: { username, email },
|
||||
},
|
||||
} = this.props;
|
||||
const formHasErrors = !!Object.keys(this.state.errors).length;
|
||||
const validUsername =
|
||||
formData.newUsername && formData.newUsername !== username;
|
||||
@@ -138,8 +142,8 @@ class Profile extends React.Component {
|
||||
}
|
||||
};
|
||||
|
||||
saveEmail = async () => {
|
||||
const { newEmail, confirmPassword } = this.state.formData;
|
||||
saveEmail = async confirmPassword => {
|
||||
const { newEmail } = this.state.formData;
|
||||
|
||||
try {
|
||||
await this.props.updateEmailAddress({
|
||||
@@ -166,12 +170,20 @@ class Profile extends React.Component {
|
||||
|
||||
render() {
|
||||
const {
|
||||
root: { me: { username, email, state: { status } } },
|
||||
root: {
|
||||
me: {
|
||||
username,
|
||||
email,
|
||||
state: { status },
|
||||
},
|
||||
},
|
||||
notify,
|
||||
success: hasChangedUsername,
|
||||
} = this.props;
|
||||
const { editing, formData, showDialog } = this.state;
|
||||
|
||||
const usernameCanBeUpdated = canUsernameBeUpdated(status);
|
||||
const usernameCanBeUpdated =
|
||||
canUsernameBeUpdated(status) && !hasChangedUsername;
|
||||
|
||||
return (
|
||||
<section
|
||||
@@ -202,12 +214,10 @@ class Profile extends React.Component {
|
||||
)}
|
||||
<ChangeEmailContentDialog
|
||||
save={this.saveEmail}
|
||||
onChange={this.onChange}
|
||||
formData={this.state.formData}
|
||||
email={email}
|
||||
enable={formData.newEmail && email !== formData.newEmail}
|
||||
hasError={this.hasError}
|
||||
getError={this.getError}
|
||||
closeDialog={this.closeDialog}
|
||||
/>
|
||||
</ConfirmChangesDialog>
|
||||
|
||||
@@ -224,12 +234,23 @@ class Profile extends React.Component {
|
||||
validationType="username"
|
||||
disabled={!usernameCanBeUpdated}
|
||||
columnDisplay
|
||||
errorMsg={this.state.errors.newUsername}
|
||||
>
|
||||
<span className={styles.bottomText}>
|
||||
{t(
|
||||
'talk-plugin-local-auth.change_username.change_username_note'
|
||||
<div className={styles.bottomText}>
|
||||
<span>
|
||||
{t(
|
||||
'talk-plugin-local-auth.change_username.change_username_note'
|
||||
)}
|
||||
</span>
|
||||
{!usernameCanBeUpdated && (
|
||||
<b>
|
||||
{' '}
|
||||
{t(
|
||||
'talk-plugin-local-auth.change_username.is_not_eligible'
|
||||
)}
|
||||
</b>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
</InputField>
|
||||
<InputField
|
||||
icon="email"
|
||||
@@ -289,6 +310,7 @@ Profile.propTypes = {
|
||||
notify: PropTypes.func.isRequired,
|
||||
username: PropTypes.string,
|
||||
emailAddress: PropTypes.string,
|
||||
success: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
export default Profile;
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
const prefix = 'TALK_LOCAL_AUTH';
|
||||
|
||||
export const START_ATTACH = `${prefix}_START_ATTACH`;
|
||||
export const FINISH_ATTACH = `${prefix}_FINISH_ATTACH`;
|
||||
@@ -1,12 +1,106 @@
|
||||
import React from 'react';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import { compose, gql } from 'react-apollo';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { connect, withFragments, excludeIf } from 'plugin-api/beta/client/hocs';
|
||||
import AddEmailAddressDialog from '../components/AddEmailAddressDialog';
|
||||
import { notify } from 'coral-framework/actions/notification';
|
||||
|
||||
import { withAttachLocalAuth } from '../hocs';
|
||||
import { startAttach, finishAttach } from '../actions';
|
||||
import get from 'lodash/get';
|
||||
import { getErrorMessages } from 'coral-framework/utils';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
import {
|
||||
Dialog,
|
||||
AddEmailForm,
|
||||
VerifyEmailAddress,
|
||||
EmailAddressAdded,
|
||||
} from '../components/AddEmailAddress';
|
||||
|
||||
const mapDispatchToProps = dispatch => bindActionCreators({ notify }, dispatch);
|
||||
class AddEmailAddressDialog extends React.Component {
|
||||
state = {
|
||||
step: 0,
|
||||
};
|
||||
|
||||
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 = () => {
|
||||
this.props.finishAttach();
|
||||
};
|
||||
|
||||
handleSubmit = async ({ email, password }) => {
|
||||
const { attachLocalAuth } = this.props;
|
||||
try {
|
||||
await attachLocalAuth({
|
||||
email,
|
||||
password,
|
||||
});
|
||||
|
||||
this.props.notify(
|
||||
'success',
|
||||
t('talk-plugin-local-auth.add_email.added.alert')
|
||||
);
|
||||
this.goToNextStep();
|
||||
} catch (err) {
|
||||
this.props.notify('error', getErrorMessages(err));
|
||||
}
|
||||
};
|
||||
|
||||
goToNextStep = () => {
|
||||
this.setState(({ step }) => ({
|
||||
step: step + 1,
|
||||
}));
|
||||
};
|
||||
|
||||
render() {
|
||||
const { step } = this.state;
|
||||
const {
|
||||
root: {
|
||||
me: { email },
|
||||
settings: { requireEmailConfirmation },
|
||||
},
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Dialog open={true} id="talk-plugin-local-auth-email-dialog">
|
||||
{step === 0 && <AddEmailForm onSubmit={this.handleSubmit} />}
|
||||
{step === 1 &&
|
||||
!requireEmailConfirmation && (
|
||||
<EmailAddressAdded onDone={this.handleDone} />
|
||||
)}
|
||||
{step === 1 &&
|
||||
requireEmailConfirmation && (
|
||||
<VerifyEmailAddress emailAddress={email} onDone={this.handleDone} />
|
||||
)}
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AddEmailAddressDialog.propTypes = {
|
||||
attachLocalAuth: PropTypes.func.isRequired,
|
||||
notify: PropTypes.func.isRequired,
|
||||
startAttach: PropTypes.func.isRequired,
|
||||
finishAttach: PropTypes.func.isRequired,
|
||||
root: PropTypes.object,
|
||||
};
|
||||
|
||||
const mapStateToProps = ({ talkPluginLocalAuth: state }) => ({
|
||||
inProgress: state.inProgress,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch =>
|
||||
bindActionCreators({ notify, startAttach, finishAttach }, dispatch);
|
||||
|
||||
const withData = withFragments({
|
||||
root: gql`
|
||||
@@ -14,6 +108,13 @@ const withData = withFragments({
|
||||
me {
|
||||
id
|
||||
email
|
||||
state {
|
||||
status {
|
||||
username {
|
||||
status
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
settings {
|
||||
requireEmailConfirmation
|
||||
@@ -23,8 +124,16 @@ const withData = withFragments({
|
||||
});
|
||||
|
||||
export default compose(
|
||||
connect(null, mapDispatchToProps),
|
||||
connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withAttachLocalAuth,
|
||||
withData,
|
||||
excludeIf(({ root: { me } }) => !me || me.email)
|
||||
excludeIf(
|
||||
({ root: { me }, inProgress }) =>
|
||||
!me ||
|
||||
get(me, 'state.status.username.status') === 'UNSET' ||
|
||||
(me.email && !inProgress)
|
||||
)
|
||||
)(AddEmailAddressDialog);
|
||||
|
||||
@@ -21,7 +21,10 @@ const withData = withFragments({
|
||||
});
|
||||
|
||||
export default compose(
|
||||
connect(null, mapDispatchToProps),
|
||||
connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withChangePassword,
|
||||
withForgotPassword,
|
||||
withData
|
||||
|
||||
@@ -32,7 +32,10 @@ const withData = withFragments({
|
||||
});
|
||||
|
||||
export default compose(
|
||||
connect(null, mapDispatchToProps),
|
||||
connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withSetUsername,
|
||||
withUpdateEmailAddress,
|
||||
withData
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import ChangePassword from './containers/ChangePassword';
|
||||
import AddEmailAddressDialog from './containers/AddEmailAddressDialog';
|
||||
import Profile from './containers/Profile';
|
||||
import translations from './translations.yml';
|
||||
import translations from '../translations.yml';
|
||||
import graphql from './graphql';
|
||||
import reducer from './reducer';
|
||||
|
||||
export default {
|
||||
reducer,
|
||||
translations,
|
||||
slots: {
|
||||
profileHeader: [Profile],
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import * as actions from './constants';
|
||||
|
||||
const initialState = {
|
||||
inProgress: false,
|
||||
};
|
||||
|
||||
export default function reducer(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case actions.START_ATTACH:
|
||||
return {
|
||||
inProgress: true,
|
||||
};
|
||||
case actions.FINISH_ATTACH:
|
||||
return {
|
||||
inProgress: false,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
en:
|
||||
talk-plugin-local-auth:
|
||||
change_password:
|
||||
change_password: "Change Password"
|
||||
passwords_dont_match: "Passwords don`t match"
|
||||
required_field: "This field is required"
|
||||
forgot_password: "Forgot your password?"
|
||||
save: "Save"
|
||||
cancel: "Cancel"
|
||||
edit: "Edit"
|
||||
changed_password_msg: "Changed Password - Your password has been successfully changed"
|
||||
forgot_password_sent: "Forgot Password - We sent you an email to recover your password"
|
||||
change_username:
|
||||
change_username_note: "Usernames can only be changed once every 14 days. Your username is not currently eligible to be updated."
|
||||
save: "Save"
|
||||
edit_profile: "Edit Profile"
|
||||
cancel: "Cancel"
|
||||
confirm_username_change: "Confirm Username Change"
|
||||
description: "You are attempting to change your username. Your new username will appear on all of your past and future comments."
|
||||
old_username: "Old Username"
|
||||
new_username: "New Username"
|
||||
bottom_note: "Note: You will not be able to change your username again for 14 days"
|
||||
confirm_changes: "Confirm Changes"
|
||||
username_does_not_match: "Username does not match"
|
||||
cant_be_equal: "Your new {0} must be different to your current one"
|
||||
changed_username_success_msg: "Username Changed - Your username has been successfully changed. You will not be able to change your user name for 14 days."
|
||||
change_username_attempt: "Username can't be updated. Usernames can only be changed every 14 days."
|
||||
change_email:
|
||||
confirm_email_change: "Confirm Email Address Change"
|
||||
description: "You are attempting to change your email address. Your new email address will be used for your login and to receive account notifications."
|
||||
old_email: "Old Email Address"
|
||||
new_email: "New Email Address"
|
||||
enter_password: "Enter Password"
|
||||
incorrect_password: "Incorrect Password"
|
||||
confirm_change: "Confirm Change"
|
||||
cancel: "Cancel"
|
||||
change_email_msg: "Email Address Changed - Your email address has been successfully changed. This email address will now be used for signing in and email notifications."
|
||||
add_email:
|
||||
add_email_address: "Add Email Address"
|
||||
enter_email_address: "Enter Email Address:"
|
||||
invalid_email_address: "Invalid Email address"
|
||||
confirm_email_address: "Confirm Email Address:"
|
||||
email_does_not_match: "Email Address does not match"
|
||||
insert_password: "Insert Password:"
|
||||
required_field: "This field is required"
|
||||
done: "done"
|
||||
content:
|
||||
title: "Add an Email Address"
|
||||
description: "For your added security, we require users to add an email address to their accounts. Your email address will be used to:"
|
||||
item_1: "Receive updates regarding any changes to your account (email address, username, password, etc.)"
|
||||
item_2: "Allow you to download your comments."
|
||||
item_3: "Send comment notifications that you have chosen to receive."
|
||||
verify:
|
||||
title: "Verify Your Email Address"
|
||||
description: "We’ve sent an email to {0} to verify your account. You must verify your email address so that it can be used for account change confirmations and notifications."
|
||||
added:
|
||||
title: "Email Address Added"
|
||||
description: "Your email address has been added to your account."
|
||||
subtitle: "Need to change your email address?"
|
||||
description_2: "You can change your account settings by visiting"
|
||||
path: "My Profile > Settings"
|
||||
es:
|
||||
talk-plugin-local-auth:
|
||||
change_password:
|
||||
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"
|
||||
change_username:
|
||||
change_username_note: "El usuario puede ser cambiado cada 14 días"
|
||||
save: "Guardar"
|
||||
edit_profile: "Editar Perfil"
|
||||
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"
|
||||
new_username: "Usuario nuevo"
|
||||
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"
|
||||
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."
|
||||
@@ -4,7 +4,7 @@ const mutators = require('./server/mutators');
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
translations: path.join(__dirname, 'server', 'translations.yml'),
|
||||
translations: path.join(__dirname, 'translations.yml'),
|
||||
typeDefs,
|
||||
mutators,
|
||||
resolvers,
|
||||
|
||||
@@ -18,7 +18,15 @@ async function updateUserEmailAddress(ctx, email, confirmPassword) {
|
||||
const {
|
||||
user,
|
||||
loaders: { Settings },
|
||||
connectors: { models: { User }, services: { Mailer, I18n, Users } },
|
||||
connectors: {
|
||||
models: { User },
|
||||
services: {
|
||||
Mailer,
|
||||
I18n,
|
||||
Users,
|
||||
Utils: { getRedirectUri },
|
||||
},
|
||||
},
|
||||
} = ctx;
|
||||
|
||||
// Ensure that the user has a local profile associated with their account.
|
||||
@@ -27,7 +35,7 @@ async function updateUserEmailAddress(ctx, email, confirmPassword) {
|
||||
}
|
||||
|
||||
// Ensure that the password provided matches what we have on file.
|
||||
if (!await user.verifyPassword(confirmPassword)) {
|
||||
if (!(await user.verifyPassword(confirmPassword))) {
|
||||
throw new ErrIncorrectPassword();
|
||||
}
|
||||
|
||||
@@ -74,14 +82,26 @@ async function updateUserEmailAddress(ctx, email, confirmPassword) {
|
||||
subject: I18n.t('email.email_change_original.subject'),
|
||||
});
|
||||
|
||||
// Try to get the root parent, and their redirect uri.
|
||||
const redirectUri = getRedirectUri(ctx.rootParent);
|
||||
|
||||
// Send off the email to the new email address that we need to verify the new
|
||||
// address.
|
||||
await Users.sendEmailConfirmation(user, email);
|
||||
await Users.sendEmailConfirmation(user, email, redirectUri);
|
||||
}
|
||||
|
||||
// attachUserLocalAuth will attach a new local profile to an existing user.
|
||||
async function attachUserLocalAuth(ctx, email, password) {
|
||||
const { user, connectors: { models: { User }, services: { Users } } } = ctx;
|
||||
const {
|
||||
user,
|
||||
connectors: {
|
||||
models: { User },
|
||||
services: {
|
||||
Users,
|
||||
Utils: { getRedirectUri },
|
||||
},
|
||||
},
|
||||
} = ctx;
|
||||
|
||||
// Ensure that the current user doesn't already have a local account
|
||||
// associated with them.
|
||||
@@ -132,9 +152,12 @@ async function attachUserLocalAuth(ctx, email, password) {
|
||||
throw new Error('local auth attachment failed due to unexpected reason');
|
||||
}
|
||||
|
||||
// Try to get the root parent, and their redirect uri.
|
||||
const redirectUri = getRedirectUri(ctx.rootParent);
|
||||
|
||||
// Send off the email to the new email address that we need to verify the
|
||||
// new address.
|
||||
await Users.sendEmailConfirmation(updatedUser, email);
|
||||
await Users.sendEmailConfirmation(updatedUser, email, redirectUri);
|
||||
} catch (err) {
|
||||
if (err.code === 11000) {
|
||||
throw new ErrEmailTaken();
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
en:
|
||||
email:
|
||||
email_change_original:
|
||||
subject: Email change
|
||||
body: Your email address has been changed from {0} to {1}. If you did not initiate this change, please contact {2}. # TODO: update translation
|
||||
error:
|
||||
NO_LOCAL_PROFILE: No existing email address is associated with this account.
|
||||
LOCAL_PROFILE: An email address is already associated with this account.
|
||||
INCORRECT_PASSWORD: Provided password was incorrect.
|
||||
@@ -0,0 +1,454 @@
|
||||
ar:
|
||||
email:
|
||||
email_change_original:
|
||||
subject: تغيير البريد الإلكتروني
|
||||
body: تم تغيير عنوان بريدك الإلكتروني من {0} إلى {1}. إذا لم تطلب هذا التغيير ، فيرجى الاتصال {2}.
|
||||
error:
|
||||
NO_LOCAL_PROFILE: لا يوجد عنوان بريد إلكتروني حالي مقترن بهذا الحساب.
|
||||
LOCAL_PROFILE: هناك بريد إلكتروني مرتبط بهذا الحساب.
|
||||
INCORRECT_PASSWORD: كلمة المرور المقدمة غير صحيحة.
|
||||
talk-plugin-local-auth:
|
||||
change_password:
|
||||
change_password: "تغيير كلمة المرور"
|
||||
passwords_dont_match: "كلمات المرور لا تتطابق"
|
||||
required_field: "هذه الخانة مطلوبه"
|
||||
forgot_password: "نسيت كلمة المرور؟"
|
||||
old_password: "كلمة المرور القديمة"
|
||||
new_password: "كلمة المرور الجديدة"
|
||||
confirm_new_password: "تأكيد كلمة المرور الجديدة"
|
||||
save: "حفظ"
|
||||
cancel: "إلغاء"
|
||||
edit: "تعديل"
|
||||
changed_password_msg: "تغيير كلمة المرور - تم تغيير كلمة المرور الخاصة بك بنجاح"
|
||||
forgot_password_sent: "نسيت كلمة المرور - لقد أرسلنا إليك رسالة بريد إلكتروني لاسترداد كلمة المرور الخاصة بك"
|
||||
change_username:
|
||||
change_username_note: "لا يمكن تغيير أسماء المستخدمين إلا مرة واحدة كل 14 يومًا."
|
||||
is_not_eligible: "لا يمكنك حاليا تغيير اسم المستخدم الخاص بك."
|
||||
save: "حفظ"
|
||||
edit_profile: "تعديل الملف الشخصي"
|
||||
cancel: "إلغاء"
|
||||
confirm_username_change: "تأكيد تغيير اسم المستخدم"
|
||||
description: "أنت تحاول تغيير اسم المستخدم الخاص بك. سوف يظهر اسم المستخدم الجديد الخاص بك على جميع تعليقاتك الماضية والتعليقات المستقبلية."
|
||||
old_username: "اسم المستخدم القديم"
|
||||
new_username: "اسم المستخدم الجديد"
|
||||
re_enter: "أعد إدخال اسم مستخدم جديد"
|
||||
bottom_note: "ملاحظة: لن تتمكن من تغيير اسم المستخدم الخاص بك مرة أخرى لمدة 14 يومًا"
|
||||
confirm_changes: "تأكيد التغييرات"
|
||||
username_does_not_match: "اسم المستخدم غير متطابق"
|
||||
cant_be_equal: "يجب أن يكون {0} الجديد الخاص بك مختلفًا عن الحالي"
|
||||
changed_username_success_msg: "اسم المستخدم تم تغييره - تم تغيير اسم المستخدم الخاص بك بنجاح. لن تتمكن من تغيير اسم المستخدم الخاص بك لمدة 14 يومًا."
|
||||
change_username_attempt: "لا يمكن تحديث اسم المستخدم. لا يمكن تغيير أسماء المستخدمين إلا كل 14 يومًا."
|
||||
change_email:
|
||||
confirm_email_change: "تأكيد تغيير عنوان البريد الإلكتروني"
|
||||
description: "أنت تحاول تغيير عنوان بريدك الإلكتروني. سيتم استخدام عنوان بريدك الإلكتروني الجديد لتسجيل الدخول ولتلقي إشعارات الحساب."
|
||||
old_email: "عنوان البريد الإلكتروني القديم"
|
||||
new_email: "عنوان البريد الإلكتروني الجديد"
|
||||
enter_password: "أدخل كلمة المرور"
|
||||
incorrect_password: "كلمة مرور خاطئة"
|
||||
confirm_change: "تأكيد التغيير"
|
||||
cancel: "إلغاء"
|
||||
change_email_msg: "تم تغيير عنوان البريد الإلكتروني. سيتم استخدام عنوان البريد الإلكتروني هذا الآن لتسجيل الدخول ولإشعارات البريد الإلكتروني."
|
||||
add_email:
|
||||
add_email_address: "إضافة البريد الإلكتروني"
|
||||
enter_email_address: "أدخل البريد الالكتروني:"
|
||||
invalid_email_address: "البريد الإلكتروني غير صالح"
|
||||
confirm_email_address: "أكد عنوان بريدك الإلكتروني:"
|
||||
email_does_not_match: "عنوان البريد الإلكتروني غير مطابق"
|
||||
insert_password: "إدخال كلمة المرور:"
|
||||
confirm_password: "تأكيد كلمة المرور:"
|
||||
required_field: "هذه الخانة مطلوبه"
|
||||
done: "تم"
|
||||
content:
|
||||
title: "أضف عنوان بريد إلكتروني"
|
||||
description: "لمزيد من الأمان ، نطلب من المستخدمين إضافة عنوان بريد إلكتروني إلى حساباتهم. سيتم استخدام عنوان بريدك الإلكتروني في:"
|
||||
item_1: "تلقي التحديثات المتعلقة بأي تغييرات في حسابك (عنوان البريد الإلكتروني ، اسم المستخدم ، كلمة المرور ، إلخ.)"
|
||||
item_2: "السماح لك بتنزيل تعليقاتك."
|
||||
item_3: "إرسال إشعارات التعليقات التي اخترت استلامها."
|
||||
verify:
|
||||
title: "تحقق من عنوان البريد الإلكتروني الخاص بك"
|
||||
description: "لقد أرسلنا رسالة إلكترونية إلى {0} لإثبات ملكية حسابك. يجب عليك التحقق من عنوان بريدك الإلكتروني حتى يمكن استخدامه لتأكيد تعديلات الحساب والإشعارات."
|
||||
added:
|
||||
title: "تمت إضافة عنوان البريد الالكتروني"
|
||||
description: "تمت إضافة عنوان بريدك الإلكتروني إلى حسابك."
|
||||
subtitle: "هل تحتاج إلى تغيير عنوان بريدك الإلكتروني؟"
|
||||
description_2: "يمكنك تغيير إعدادات حسابك من خلال زيارة"
|
||||
path: "ملفي > الإعدادات"
|
||||
alert: "تمت إضافة البريد الإلكتروني!"
|
||||
en:
|
||||
email:
|
||||
email_change_original:
|
||||
subject: Email change
|
||||
body: Your email address has been changed from {0} to {1}. If you did not request this change, please contact {2}.
|
||||
error:
|
||||
NO_LOCAL_PROFILE: No existing email address is associated with this account.
|
||||
LOCAL_PROFILE: An email address is already associated with this account.
|
||||
INCORRECT_PASSWORD: Provided password was incorrect.
|
||||
talk-plugin-local-auth:
|
||||
change_password:
|
||||
change_password: "Change Password"
|
||||
passwords_dont_match: "Passwords don`t match"
|
||||
required_field: "This field is required"
|
||||
forgot_password: "Forgot your password?"
|
||||
old_password: "Old Password"
|
||||
new_password: "New Password"
|
||||
confirm_new_password: "Confirm New Password"
|
||||
save: "Save"
|
||||
cancel: "Cancel"
|
||||
edit: "Edit"
|
||||
changed_password_msg: "Changed Password - Your password has been successfully changed"
|
||||
forgot_password_sent: "Forgot Password - We sent you an email to recover your password"
|
||||
change_username:
|
||||
change_username_note: "Usernames can only be changed once every 14 days."
|
||||
is_not_eligible: "You cannot currently change your username."
|
||||
save: "Save"
|
||||
edit_profile: "Edit Profile"
|
||||
cancel: "Cancel"
|
||||
confirm_username_change: "Confirm Username Change"
|
||||
description: "You are attempting to change your username. Your new username will appear on all of your past and future comments."
|
||||
old_username: "Old Username"
|
||||
new_username: "New Username"
|
||||
re_enter: "Re-enter new username"
|
||||
bottom_note: "Note: You will not be able to change your username again for 14 days"
|
||||
confirm_changes: "Confirm Changes"
|
||||
username_does_not_match: "Username does not match"
|
||||
cant_be_equal: "Your new {0} must be different to your current one"
|
||||
changed_username_success_msg: "Username Changed - Your username has been successfully changed. You will not be able to change your user name for 14 days."
|
||||
change_username_attempt: "Username can't be updated. Usernames can only be changed every 14 days."
|
||||
change_email:
|
||||
confirm_email_change: "Confirm Email Address Change"
|
||||
description: "You are attempting to change your email address. Your new email address will be used for your login and to receive account notifications."
|
||||
old_email: "Old Email Address"
|
||||
new_email: "New Email Address"
|
||||
enter_password: "Enter Password"
|
||||
incorrect_password: "Incorrect Password"
|
||||
confirm_change: "Confirm Change"
|
||||
cancel: "Cancel"
|
||||
change_email_msg: "Email Address Changed. This email address will now be used for signing in and email notifications."
|
||||
add_email:
|
||||
add_email_address: "Add Email Address"
|
||||
enter_email_address: "Enter Email Address:"
|
||||
invalid_email_address: "Invalid Email address"
|
||||
confirm_email_address: "Confirm Email Address:"
|
||||
email_does_not_match: "Email Address does not match"
|
||||
insert_password: "Insert Password:"
|
||||
confirm_password: "Confirm Password:"
|
||||
required_field: "This field is required"
|
||||
done: "Done"
|
||||
content:
|
||||
title: "Add an Email Address"
|
||||
description: "For your added security, we require users to add an email address to their accounts. Your email address will be used to:"
|
||||
item_1: "Receive updates regarding any changes to your account (email address, username, password, etc.)"
|
||||
item_2: "Allow you to download your comments."
|
||||
item_3: "Send comment notifications that you have chosen to receive."
|
||||
verify:
|
||||
title: "Verify Your Email Address"
|
||||
description: "We’ve sent an email to {0} to verify your account. You must verify your email address so that it can be used for account change confirmations and notifications."
|
||||
added:
|
||||
title: "Email Address Added"
|
||||
description: "Your email address has been added to your account."
|
||||
subtitle: "Need to change your email address?"
|
||||
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:
|
||||
subject: Änderung Ihrer E-Mail-Adresse
|
||||
body: Ihre E-Mail-Adresse wurde von {0} zu {1} geändert. Falls Sie diese Änderung nicht selbst vorgenommen haben, kontaktieren Sie bitte zur Sicherheit {2}.
|
||||
error:
|
||||
NO_LOCAL_PROFILE: Mit diesem Benutzerkonto ist keine E-Mail-Adresse verbunden.
|
||||
LOCAL_PROFILE: Es ist bereits eine bestätigte E-Mail-Adresse mit diesem Benutzerkonto verbunden.
|
||||
INCORRECT_PASSWORD: Das Passwort war nicht korrekt.
|
||||
talk-plugin-local-auth:
|
||||
change_password:
|
||||
change_password: "Passwort ändern"
|
||||
passwords_dont_match: "Die Passwörter stimmen nicht überein"
|
||||
required_field: "Diese Angabe ist erforderlich"
|
||||
forgot_password: "Passwort vergessen?"
|
||||
old_password: "Altes Passwort"
|
||||
new_password: "Neues Passwort"
|
||||
confirm_new_password: "Neues Passwort bestätigen"
|
||||
save: "Speichern"
|
||||
cancel: "Abbrechen"
|
||||
edit: "Ändern"
|
||||
changed_password_msg: "Passwort geändert - Ihr Passwort wurde erfolgreich geändert"
|
||||
forgot_password_sent: "Passwort vergessen - Wir haben Ihnen eine E-Mail zum Zurücksetzen des Passwortes geschickt"
|
||||
change_username:
|
||||
change_username_note: "Nutzernamen können nur alle 14 Tage geändert werden."
|
||||
is_not_eligible: "Sie können Ihren Nutzernamen derzeit nicht ändern."
|
||||
save: "Speichern"
|
||||
edit_profile: "Profil ändern"
|
||||
cancel: "Abbrechen"
|
||||
confirm_username_change: "Änderung des Nutzernamens bestätigen"
|
||||
description: "Sie möchten Ihren Nutzernamen ändern: der neue Nutzername wird an allen alten und neuen Kommentaren erscheinen."
|
||||
old_username: "Alter Nutzername"
|
||||
new_username: "Neuer Nutzername"
|
||||
re_enter: "Neuen Nutzernamen bestätigen"
|
||||
bottom_note: "Achtung: die nächste Änderung des Nutzernamens ist erst nach 14 Tagen möglich"
|
||||
confirm_changes: "Änderung bestätigen"
|
||||
username_does_not_match: "Die Nutzernamen stimmen nicht überein"
|
||||
cant_be_equal: "Der neue Nutzername {0} muss sich vom alten unterscheiden."
|
||||
changed_username_success_msg: "Nutzername geändert - Ihr Nutzername wurde erfolgreich aktualisiert. Die nächste Änderung des Nutzernamens ist erst nach 14 Tagen möglich."
|
||||
change_username_attempt: "Der Nutzername kann zur Zeit nicht aktualisiert werden. Änderungen sind nur nach jeweils 14 Tagen möglich."
|
||||
change_email:
|
||||
confirm_email_change: "Änderung der E-Mail-Adresse bestätigen"
|
||||
description: "Sie versuchen, Ihre E-Mail-Adresse ändern: die neue E-Mail-Adresse wird zum Login sowie für Benachrichtigungen bzgl. Ihres Benutzerkontos verwendet."
|
||||
old_email: "Alte E-Mail-Adresse"
|
||||
new_email: "Neue E-Mail-Adresse"
|
||||
enter_password: "Passwort"
|
||||
incorrect_password: "Passwort nicht korrekt"
|
||||
confirm_change: "Änderung bestätigen"
|
||||
cancel: "Abbrechen"
|
||||
change_email_msg: "E-Mail-Adresse erfolgreich aktualisiert - die neue E-Mail-Adresse ab sofort zum Anmelden und für Benachrichtigungen verwendet."
|
||||
add_email:
|
||||
add_email_address: "E-Mail-Adresse hinzufügen"
|
||||
enter_email_address: "E-Mail-Adresse:"
|
||||
invalid_email_address: "Ungültige E-Mail-Adresse"
|
||||
confirm_email_address: "Bestätigung der E-Mail-Adresse:"
|
||||
email_does_not_match: "Die E-Mail-Adressen stimmen nicht überein"
|
||||
insert_password: "Passwort auswählen:"
|
||||
required_field: "Dieses Feld ist erforderlich"
|
||||
done: "Fertig"
|
||||
content:
|
||||
title: "E-Mail-Adresse hinzufügen"
|
||||
description: "Aus Sicherheitsgründen benötigen wir eine E-Mail-Adresse zu jedem Benutzerkonto. Ihre E-Mail-Adresse wird für folgendes verwendet:"
|
||||
item_1: "Benachrichtigungen über Änderungen am Benutzerkonto (Nutzername, E-Mail-Adresse, Passwort)"
|
||||
item_2: "Ermöglicht den Download des eigenen Kommentar-Archivs"
|
||||
item_3: "Kommentar-Benachrichtigungen erhalten, die Sie explizit angefordert haben"
|
||||
verify:
|
||||
title: "E-Mail-Adresse bestätigen"
|
||||
description: "Wir haben eine E-Mail an {0} geschickt. Bitte bestätigen Sie Ihre E-Mail-Adresse, um damit Benachrichtigungen über Änderungen am Benutzerkonto zu erhalten."
|
||||
added:
|
||||
title: "E-Mail-Adresse hinzugefügt"
|
||||
description: "Ihre E-Mail-Adresse wurde dem Benutzerkonto hinzugefügt."
|
||||
subtitle: "Sie möchten Ihre E-Mail-Adresse ändern?"
|
||||
description_2: "Sie können Ihre Konto-Einstellugen ändern unter"
|
||||
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: "Contraseña cambiada - Su contraseña ha sido cambiado"
|
||||
forgot_password_sent: "Contraseña olvidada - Enviamos un email para recuperar la contraseña"
|
||||
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?"
|
||||
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."
|
||||
save: "Guardar"
|
||||
edit_profile: "Editar Perfil"
|
||||
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 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!"
|
||||
nl_NL:
|
||||
email:
|
||||
email_change_original:
|
||||
subject: E-mailadres wijziging
|
||||
body: "Je e-mailadres is gewijzigd van {0} naar {1}. Als je deze wijziging niet hebt aangevraagd, neem dan s.v.p. contact op: {2}."
|
||||
error:
|
||||
NO_LOCAL_PROFILE: Er is geen bestaand e-mailadres geassocieerd met dit account.
|
||||
LOCAL_PROFILE: Er is reeds een e-mailadres geassocieerd met dit account.
|
||||
INCORRECT_PASSWORD: Het opgegeven wachtwoord is onjuist.
|
||||
talk-plugin-local-auth:
|
||||
change_password:
|
||||
change_password: "Wachtwoord wijzigen"
|
||||
passwords_dont_match: "Wachtwoorden komen niet overeen"
|
||||
required_field: "Dit veld is verplicht"
|
||||
forgot_password: "Wachtwoord vergeten?"
|
||||
old_password: "Oud Wachtwoord"
|
||||
new_password: "Nieuw Wachtwoord"
|
||||
confirm_new_password: "Bevestig Nieuw Wachtwoord"
|
||||
save: "Opslaan"
|
||||
cancel: "Annuleren"
|
||||
edit: "Wijzigen"
|
||||
changed_password_msg: "Wachtwoord Gewijzigd - Je wachtwoord is succesvol gewijzigd"
|
||||
forgot_password_sent: "Wachtwoord Vergeten - We hebben je een e-mail gestuurd om je wachtwoord te herstellen"
|
||||
change_username:
|
||||
change_username_note: "Gebruikersnamen kunnen eens per 14 dagen worden gewijzigd."
|
||||
is_not_eligible: "Je kunt je gebruikersnaam momenteel niet wijzigen."
|
||||
save: "Opslaan"
|
||||
edit_profile: "Profiel wijzigen"
|
||||
cancel: "Annuleren"
|
||||
confirm_username_change: "Bevestig Gebruikersnaam Wijziging"
|
||||
description: "Je probeert je gebruikersnaam te wijzigen. Je nieuwe gebruikersnaam zal verschijnen bij al je huidige en toekomstige reacties."
|
||||
old_username: "Oude Gebruikersnaam"
|
||||
new_username: "Nieuwe Gebruikersnaam"
|
||||
re_enter: "Voer je nieuwe gebruikersnaam opnieuw in"
|
||||
bottom_note: "Let op: Je kan je gebruikersnaam niet opnieuw wijzigen in de komende 14 dagen."
|
||||
confirm_changes: "Bevestig Wijzigingen"
|
||||
username_does_not_match: "Gebruikersnaam komt niet overeen"
|
||||
cant_be_equal: "Je nieuwe {0} moet verschillen van je huidige"
|
||||
changed_username_success_msg: "Gebruikersnaam Gewijzigd - Je gebruikersnaam is succesvol gewijzigd. Je kan je gebruikersnaam niet wijzigen voor de komende 14 dagen."
|
||||
change_username_attempt: "Gebruikersnaam kan niet worden gewijzigd. Gebruikersnamen kunnen eens per 14 dagen worden gewijzigd."
|
||||
change_email:
|
||||
confirm_email_change: "Bevestig E-mailadres Wijziging"
|
||||
description: "Je probeert je e-mailadres te wijzigen. Je nieuwe e-mailadres zal worden gebruikt om in te loggen en voor het ontvangen van account notificaties."
|
||||
old_email: "Oude E-mailadres"
|
||||
new_email: "Nieuwe E-mailadres"
|
||||
enter_password: "Wachtwoord Invoeren"
|
||||
incorrect_password: "Ongeldig Wachtwoord"
|
||||
confirm_change: "Bevestig Wijziging"
|
||||
cancel: "Annuleren"
|
||||
change_email_msg: "E-mailadres Gewijzigd. Dit E-mailadres zal nu worden gebruikt om in te loggen en voor het ontvangen van account notificaties."
|
||||
add_email:
|
||||
add_email_address: "E-mailadres Toevoegen"
|
||||
enter_email_address: "E-mailadres Invoeren:"
|
||||
invalid_email_address: "Ongeldig E-mailadres"
|
||||
confirm_email_address: "Bevestig E-mailadres:"
|
||||
email_does_not_match: "E-mailadres komt niet overeen"
|
||||
insert_password: "Wachtwoord Invoeren:"
|
||||
confirm_password: "Wachtwoord Bevestigen:"
|
||||
required_field: "Dit veld is verplicht"
|
||||
done: "Klaar"
|
||||
content:
|
||||
title: "Voeg een e-mailadres toe"
|
||||
description: "Voor je veiligheid vragen we gebruikers om een e-mailadres toe te voegen aan hun account. Je e-mailadres zal worden gebruikt om:"
|
||||
item_1: "Updates te ontvangen omtrent wijzigingen in je account (e-mailadres, gebruikersnaam, wachtwoord, etc.)"
|
||||
item_2: "Je reacties te kunnen downloaden."
|
||||
item_3: "Reactie notificaties te sturen indien je hebt gekozen deze te ontvangen."
|
||||
verify:
|
||||
title: "Bevestig Je E-mailadres"
|
||||
description: "We hebben een e-mail gestuurd aan {0} om je account te bevestigen. Je moet je e-mailadres verifiëren zodat deze gebruikt kan worden voor bevestigingen omtrent account wijzigingen en voor notificaties."
|
||||
added:
|
||||
title: "E-mailadres Toegevoegd"
|
||||
description: "Je e-mailadres is toegevoegd aan je account."
|
||||
subtitle: "Wil je je e-mailadres wijzigen?"
|
||||
description_2: "Je kan je account instellingen wijzigen door te gaan naar"
|
||||
path: "Mijn Profiel > Instellingen"
|
||||
alert: "E-mailadres Toegevoegd!"
|
||||
@@ -28,8 +28,8 @@ he:
|
||||
loved: אהבתי
|
||||
nl_NL:
|
||||
talk-plugin-love:
|
||||
love: Ik hou er van
|
||||
loved: Geliefd
|
||||
love: Love
|
||||
loved: Loved
|
||||
pt_BR:
|
||||
talk-plugin-love:
|
||||
love: Love
|
||||
|
||||
@@ -21,10 +21,10 @@ he:
|
||||
member_since: "חבר מאז"
|
||||
nl_NL:
|
||||
talk-plugin-member-since:
|
||||
member_since: "Gebruiker sinds"
|
||||
member_since: "Lid sinds"
|
||||
pt_BR:
|
||||
talk-plugin-member-since:
|
||||
member_since: "Member Since"
|
||||
member_since: "Membro desde"
|
||||
zh_CN:
|
||||
talk-plugin-member-since:
|
||||
member_since: "成员加入日期"
|
||||
|
||||
@@ -15,7 +15,10 @@ class BanUserActionContainer extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { root: { me }, comment } = this.props;
|
||||
const {
|
||||
root: { me },
|
||||
comment,
|
||||
} = this.props;
|
||||
return me.id !== comment.user.id ? (
|
||||
<BanUserAction onBanUser={this.onBanUser} comment={this.props.comment} />
|
||||
) : null;
|
||||
@@ -30,6 +33,11 @@ const mapDispatchToProps = dispatch =>
|
||||
dispatch
|
||||
);
|
||||
|
||||
const enhance = compose(connect(null, mapDispatchToProps));
|
||||
const enhance = compose(
|
||||
connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
)
|
||||
);
|
||||
|
||||
export default enhance(BanUserActionContainer);
|
||||
|
||||
@@ -70,7 +70,10 @@ const mapDispatchToProps = dispatch =>
|
||||
);
|
||||
|
||||
const enhance = compose(
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withSetCommentStatus,
|
||||
withBanUser
|
||||
);
|
||||
|
||||
@@ -68,7 +68,10 @@ const mapDispatchToProps = dispatch =>
|
||||
);
|
||||
|
||||
const enhance = compose(
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
),
|
||||
withFragments({
|
||||
root: gql`
|
||||
fragment TalkModerationActions_root on RootQuery {
|
||||
|
||||
@@ -96,16 +96,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: "拒绝"
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
ar:
|
||||
talk-plugin-notifications-category-featured:
|
||||
toggle_description: تعليقي تم تمييزه
|
||||
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
|
||||
|
||||
@@ -1,6 +1,25 @@
|
||||
ar:
|
||||
talk-plugin-notifications:
|
||||
categories:
|
||||
featured:
|
||||
subject: "تميَزت واحدة من تعليقاتك على {0}"
|
||||
body: "{0}\n
|
||||
حدد أحد أعضاء فريقنا هذا التعليق ليتم عرضه كتعليق مميز للقراء الآخرين: {1}"
|
||||
en:
|
||||
talk-plugin-notifications:
|
||||
categories:
|
||||
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}"
|
||||
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:
|
||||
featured:
|
||||
subject: "Einer Ihrer Kommentare wurde auf {0} hervorgehoben"
|
||||
body: "{0}\nEin Mitglied unseres Teams hat diesen Kommentar ausgewählt, er wird jetzt für andere Leser besonders hervorgehoben: {1}"
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
ar:
|
||||
talk-plugin-notifications-category-reply:
|
||||
toggle_description: يتلقى تعليقي ردا
|
||||
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
|
||||
nl_NL:
|
||||
talk-plugin-notifications-category-reply:
|
||||
toggle_description: Iemand antwoord op mijn reactie
|
||||
|
||||
@@ -1,6 +1,25 @@
|
||||
ar:
|
||||
talk-plugin-notifications:
|
||||
categories:
|
||||
reply:
|
||||
subject: "رد شخص ما على تعليقك على {0}"
|
||||
body: "{0}\n{1} رد على تعليقك
|
||||
{2}"
|
||||
en:
|
||||
talk-plugin-notifications:
|
||||
categories:
|
||||
reply:
|
||||
subject: "Someone has replied to your comment on {0}"
|
||||
body: "{0}\n{1} replied to your comment: {2}"
|
||||
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:
|
||||
reply:
|
||||
subject: "Jemand hat bei {0} auf Ihren Kommentar geantwortet"
|
||||
body: "{0}\n{1} antwortete auf Ihren Kommentar: {2}"
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
ar:
|
||||
talk-plugin-notifications-category-staff:
|
||||
toggle_description: يرد أحد الموظفين على تعليقي
|
||||
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
|
||||
nl_NL:
|
||||
talk-plugin-notifications-category-staff:
|
||||
toggle_description: Een redactielid antwoord op mijn reactie
|
||||
|
||||
@@ -1,6 +1,31 @@
|
||||
ar:
|
||||
talk-plugin-notifications:
|
||||
categories:
|
||||
staff:
|
||||
subject: "شخص ما في {0} قد رد على تعليقك"
|
||||
body: "{0}\n{1} يعمل ل
|
||||
{2} وقد رد على تعليقك: {3}"
|
||||
en:
|
||||
talk-plugin-notifications:
|
||||
categories:
|
||||
staff:
|
||||
subject: "Someone at {0} has replied to your comment"
|
||||
body: "{0}\n{1} works for {2} and has replied to your comment: {3}"
|
||||
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:
|
||||
staff:
|
||||
subject: "Jemand hat bei {0} auf Ihren Kommentar geantwortet"
|
||||
body: "{0}\n{1} arbeitet für {2} und hat auf Ihren Kommentar geantwortet: {3}"
|
||||
nl_NL:
|
||||
talk-plugin-notifications:
|
||||
categories:
|
||||
staff:
|
||||
subject: "Iemand bij {0} heeft geantwoord op je reactie"
|
||||
body: "{0}\n{1} werkt voor {2} en heeft geantwoord op je reactie: {3}"
|
||||
|
||||
@@ -1,4 +1,20 @@
|
||||
ar:
|
||||
talk-plugin-notifications:
|
||||
digest_enum:
|
||||
DAILY: في ملخص يومي
|
||||
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:
|
||||
DAILY: Einmal täglich
|
||||
nl_NL:
|
||||
talk-plugin-notifications:
|
||||
digest_enum:
|
||||
DAILY: In een dagelijkse samenvatting
|
||||
|
||||
@@ -1,4 +1,20 @@
|
||||
ar:
|
||||
talk-plugin-notifications:
|
||||
digest_enum:
|
||||
HOURLY: في ملخص كل ساعة
|
||||
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:
|
||||
HOURLY: Stündlich
|
||||
nl_NL:
|
||||
talk-plugin-notifications:
|
||||
digest_enum:
|
||||
HOURLY: In een uurlijkse samenvatting
|
||||
|
||||
@@ -73,7 +73,11 @@ const withSettingsToggle = settingsName => {
|
||||
mutations: {
|
||||
UpdateNotificationSettings: ({
|
||||
variables: { input },
|
||||
state: { auth: { user: { id } } },
|
||||
state: {
|
||||
auth: {
|
||||
user: { id },
|
||||
},
|
||||
},
|
||||
}) => ({
|
||||
update: proxy => {
|
||||
if (input[settingsName] === undefined) {
|
||||
|
||||
@@ -13,7 +13,11 @@ export default {
|
||||
mutations: {
|
||||
UpdateNotificationSettings: ({
|
||||
variables: { input },
|
||||
state: { auth: { user: { id } } },
|
||||
state: {
|
||||
auth: {
|
||||
user: { id },
|
||||
},
|
||||
},
|
||||
}) => ({
|
||||
optimisticResponse: {
|
||||
updateNotificationSettings: {
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
ar:
|
||||
talk-plugin-notifications:
|
||||
settings_title: إشعارات
|
||||
settings_subtitle: تلقي الإشعارات متى
|
||||
turn_off_all: لا أريد تلقي الإشعارات
|
||||
banner_info:
|
||||
title: التحقق من البريد الإلكتروني مطلوب
|
||||
text: لتلقي إشعارات البريد الإلكتروني ، يجب أن يكون لديك عنوان بريد إلكتروني تم التحقق منه.
|
||||
verify_now: تحقق من بريدك الالكتروني الآن
|
||||
banner_success:
|
||||
title: تم إرسال التحقق عبر البريد الإلكتروني
|
||||
text: تم إرسال رسالة إلكترونية إلى {0} يحتوي على رابط التحقق.
|
||||
banner_error:
|
||||
title: خطأ
|
||||
text: حدث خطأ في إرسال رسالة التحقق الخاصة بك. الرجاء معاودة المحاولة في وقت لاحق.
|
||||
digest_option: إرسال الإشعارات
|
||||
digest_enum:
|
||||
NONE: فورا
|
||||
en:
|
||||
talk-plugin-notifications:
|
||||
settings_title: Notifications
|
||||
@@ -16,3 +34,57 @@ 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
|
||||
settings_subtitle: Benachrichtige mich wenn
|
||||
turn_off_all: Ich möchte keine Benachrichtigungen erhalten
|
||||
banner_info:
|
||||
title: Bestätigte E-Mail-Adresse benötigt
|
||||
text: Um E-Mail-Benachrichtigungen zu erhalten, müssen Sie eine bestätigte E-Mail-Adresse haben.
|
||||
verify_now: E-Mail-Adresse jetzt bestätigen
|
||||
banner_success:
|
||||
title: E-Mail-Bestätigungsanfrage verschickt
|
||||
text: Eine E-Mail mit einem Bestätigungslink wurde an {0} geschickt.
|
||||
banner_error:
|
||||
title: Fehler
|
||||
text: Beim Versand der Bestätigungsmail gab es einen Fehler. Bitte versuchen Sie es später erneut.
|
||||
digest_option: Benachrichtigungen senden
|
||||
digest_enum:
|
||||
NONE: Sofort
|
||||
nl_NL:
|
||||
talk-plugin-notifications:
|
||||
settings_title: Notificaties
|
||||
settings_subtitle: Ontvang notificaties wanneer
|
||||
turn_off_all: Ik wil geen notificaties ontvangen
|
||||
banner_info:
|
||||
title: E-mail bevestiging vereist
|
||||
text: Je moet een geverifieerd e-mailadres hebben om e-mail notificaties te ontvangen
|
||||
verify_now: Verifieer je e-mailadres nu
|
||||
banner_success:
|
||||
title: E-mail verificatie verzonden
|
||||
text: Een e-mail met verificatielink is verstuurd naar {0}.
|
||||
banner_error:
|
||||
title: Fout
|
||||
text: Er is een fout opgetreden tijdens het versturen van je verificatie e-mail. Probeer het later nog eens.
|
||||
digest_option: Notificaties versturen
|
||||
digest_enum:
|
||||
NONE: Onmiddelijk
|
||||
|
||||
@@ -116,7 +116,12 @@ class NotificationManager {
|
||||
try {
|
||||
// Pull out some useful tools.
|
||||
const {
|
||||
connectors: { models: { User }, services: { I18n: { t } } },
|
||||
connectors: {
|
||||
models: { User },
|
||||
services: {
|
||||
I18n: { t },
|
||||
},
|
||||
},
|
||||
} = ctx;
|
||||
|
||||
const organizationName = await getOrganizationName(ctx);
|
||||
|
||||
@@ -6,7 +6,10 @@ const { map, reduce } = require('lodash');
|
||||
|
||||
module.exports = connectors => {
|
||||
const {
|
||||
graph: { subscriptions: { getBroker }, Context },
|
||||
graph: {
|
||||
subscriptions: { getBroker },
|
||||
Context,
|
||||
},
|
||||
services: { Mailer, Plugins },
|
||||
} = connectors;
|
||||
|
||||
|
||||
@@ -37,7 +37,11 @@ const queueNotifications = async (ctx, userID, notifications) => {
|
||||
);
|
||||
|
||||
// Pull out some useful tools.
|
||||
const { connectors: { models: { User } } } = ctx;
|
||||
const {
|
||||
connectors: {
|
||||
models: { User },
|
||||
},
|
||||
} = ctx;
|
||||
|
||||
ctx.log.info(
|
||||
{ notifications: notifications.length, userID },
|
||||
@@ -67,7 +71,13 @@ const sendNotificationsBatch = async (ctx, notifications) => {
|
||||
map(
|
||||
notifications,
|
||||
async ({ handler, notification: { userID, context } }) => {
|
||||
const { connectors: { services: { I18n: { t } } } } = ctx;
|
||||
const {
|
||||
connectors: {
|
||||
services: {
|
||||
I18n: { t },
|
||||
},
|
||||
},
|
||||
} = ctx;
|
||||
const { category } = handler;
|
||||
|
||||
// Compose the subject for the email.
|
||||
@@ -181,7 +191,9 @@ const USER_CONFIRMATION_QUERY = `
|
||||
// returns undefined.
|
||||
const filterVerifiedNotification = ctx => async notification => {
|
||||
// Grab the user that we're supposed to be sending the notification to.
|
||||
const { notification: { userID } } = notification;
|
||||
const {
|
||||
notification: { userID },
|
||||
} = notification;
|
||||
|
||||
// Check their confirmed status. This should have already been hit by the
|
||||
// loaders, so we shouldn't make any more database requests.
|
||||
|
||||
@@ -15,7 +15,12 @@ function reduceSettings(newSettings, newValue, key) {
|
||||
* Update the user notification settings.
|
||||
*/
|
||||
async function updateNotificationSettings(ctx, settings) {
|
||||
const { connectors: { models: { User } }, user } = ctx;
|
||||
const {
|
||||
connectors: {
|
||||
models: { User },
|
||||
},
|
||||
user,
|
||||
} = ctx;
|
||||
|
||||
// Generate the settings set object, and just exit if we haven't changed
|
||||
// anything.
|
||||
@@ -29,7 +34,9 @@ async function updateNotificationSettings(ctx, settings) {
|
||||
}
|
||||
|
||||
module.exports = ctx => {
|
||||
const { connectors: { errors: ErrNotAuthorized } } = ctx;
|
||||
const {
|
||||
connectors: { errors: ErrNotAuthorized },
|
||||
} = ctx;
|
||||
|
||||
let mutators = {
|
||||
User: {
|
||||
|
||||
@@ -16,7 +16,13 @@ module.exports = {
|
||||
digestFrequency: settings => get(settings, 'digestFrequency', 'NONE'),
|
||||
},
|
||||
RootMutation: {
|
||||
async updateNotificationSettings(obj, { input }, { mutators: { User } }) {
|
||||
async updateNotificationSettings(
|
||||
obj,
|
||||
{ input },
|
||||
{
|
||||
mutators: { User },
|
||||
}
|
||||
) {
|
||||
await User.updateNotificationSettings(input);
|
||||
},
|
||||
},
|
||||
|
||||
@@ -4,7 +4,7 @@ const { get, isEmpty, reduce } = require('lodash');
|
||||
|
||||
module.exports = router => {
|
||||
router.get('/account/unsubscribe-notifications', (req, res) => {
|
||||
res.render(path.join(__dirname, 'views/unsubscribe-notifications'));
|
||||
res.render(path.join(__dirname, 'views/unsubscribe-notifications.njk'));
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -12,7 +12,10 @@ module.exports = router => {
|
||||
*/
|
||||
const verifyToken = (req, res, next) => {
|
||||
const {
|
||||
connectors: { secrets: { jwt }, config: { JWT_ISSUER, JWT_AUDIENCE } },
|
||||
connectors: {
|
||||
secrets: { jwt },
|
||||
config: { JWT_ISSUER, JWT_AUDIENCE },
|
||||
},
|
||||
} = req.context;
|
||||
const { token: tokenString = '' } = req.body;
|
||||
if (!tokenString) {
|
||||
@@ -50,7 +53,11 @@ module.exports = router => {
|
||||
'/api/v1/account/unsubscribe-notifications',
|
||||
verifyToken,
|
||||
async (req, res, next) => {
|
||||
const { connectors: { models: { User } } } = req.context;
|
||||
const {
|
||||
connectors: {
|
||||
models: { User },
|
||||
},
|
||||
} = req.context;
|
||||
const { user: userID } = req.token;
|
||||
|
||||
try {
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
ar:
|
||||
talk-plugin-notifications:
|
||||
templates:
|
||||
digest:
|
||||
subject: "نشاطك الأخير للتعليق على {0}"
|
||||
footer: "لقد تلقيت هذا الإشعار نظرًا لأنك معلق على {0} وتم تمكين تلقي الإشعارات."
|
||||
links:
|
||||
unsubscribe: "إلغاء الاشتراك في إشعارات التعليقات"
|
||||
unsubscribe_page:
|
||||
unsubscribe: "إلغاء الاشتراك في إشعارات التعليقات"
|
||||
click_to_confirm: "انقر أدناه لتأكيد رغبتك في إلغاء الاشتراك من جميع الإشعارات"
|
||||
confirm: "أكد"
|
||||
are_unsubscribed: "أنت الآن غير مشترك في جميع الإشعارات."
|
||||
token_invalid: "رابط إلغاء الاشتراك غير صالح ، انقر الرابط من بريد إلكتروني أحدث أو قم بزيارة جدول تعليقات وتسجيل الدخول لتغيير تفضيلات الإشعارات الخاصة بك"
|
||||
en:
|
||||
talk-plugin-notifications:
|
||||
templates:
|
||||
@@ -11,4 +25,32 @@ en:
|
||||
click_to_confirm: "Click below to confirm that you would like to unsubscribe from all notifications"
|
||||
confirm: "Confirm"
|
||||
are_unsubscribed: "You are now unsubscribed from all notifications."
|
||||
token_invalid: "Unsubscribe link is invalid, click the link from a more recent email or visit a comment stream and login to change your notification preferences"
|
||||
token_invalid: "Unsubscribe link is invalid, click the link from a more recent email or visit a comment stream and login to change your notification preferences"
|
||||
de:
|
||||
talk-plugin-notifications:
|
||||
templates:
|
||||
digest:
|
||||
subject: "Ihre Kommentaraktivität bei {0}"
|
||||
footer: "Sie erhalten diese Benachrichtigung, weil Sie Community-Mitglied bei {0} sind und diese E-Mails abonniert haben."
|
||||
links:
|
||||
unsubscribe: "E-Mail-Benachrichtigungen abbestellen"
|
||||
unsubscribe_page:
|
||||
unsubscribe: "Kommentar-Benachrichtigungen abbestellen"
|
||||
click_to_confirm: "Klicken Sie folgenden Link, um zu bestätigen, dass Sie alle Benachrichtigungen abbestellen möchten"
|
||||
confirm: "Bestätigen"
|
||||
are_unsubscribed: "Sie haben haben alle Benachrichtigungen erfolgreich abbestellt."
|
||||
token_invalid: "Der Abbestell-Link ist ungültig. Klicken Sie den Link einer neueren E-Mail oder gehen Sie zu einem Kommentarbereich, melden Sie sich an und ändern Sie dort Ihre Benachrichtigungseinstellungen"
|
||||
nl_NL:
|
||||
talk-plugin-notifications:
|
||||
templates:
|
||||
digest:
|
||||
subject: "Je recente reactie-activiteit op {0}"
|
||||
footer: "Je hebt deze notificatie ontvangen omdat je een reageerder bent op {0} en je hebt je aangemeld om notificaties te ontvangen."
|
||||
links:
|
||||
unsubscribe: "Afmelden voor reactie notificaties"
|
||||
unsubscribe_page:
|
||||
unsubscribe: "Afmelden voor reactie notificaties"
|
||||
click_to_confirm: "Klik onderstaande om te bevestigen dat je je wilt afmelden voor alle notificaties"
|
||||
confirm: "Bevestigen"
|
||||
are_unsubscribed: "Je bent nu afgemeld voor alle notificaties."
|
||||
token_invalid: "Afmeldlink is ongeldig, klik de link van een recentere e-mail of bezoek een pagina met reacties en log in om je notificatie voorkeuren te wijzigen"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
const getOrganizationName = async ctx => {
|
||||
// Grab some useful tools.
|
||||
const { loaders: { Settings } } = ctx;
|
||||
const {
|
||||
loaders: { Settings },
|
||||
} = ctx;
|
||||
|
||||
// Get the settings.
|
||||
const { organizationName = null } = await Settings.select('organizationName');
|
||||
@@ -16,7 +18,13 @@ const getOrganizationName = async ctx => {
|
||||
* @param {Mixed} context the notification context
|
||||
*/
|
||||
const getNotificationBody = async (ctx, handler, context) => {
|
||||
const { connectors: { services: { I18n: { t } } } } = ctx;
|
||||
const {
|
||||
connectors: {
|
||||
services: {
|
||||
I18n: { t },
|
||||
},
|
||||
},
|
||||
} = ctx;
|
||||
const { category, hydrate = () => [] } = handler;
|
||||
|
||||
// Get the body replacement variables for the translation key.
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
|
||||
<title><%= t('talk-plugin-notifications.unsubscribe_page.unsubscribe') %></title>
|
||||
<%- include(root + '/partials/head') %>
|
||||
<link rel="stylesheet" href="https://code.getmdl.io/1.2.1/material.indigo-pink.min.css">
|
||||
<link rel="stylesheet" href="<%= BASE_PATH %>public/css/admin.css">
|
||||
</head>
|
||||
<body class="confirm-email-page">
|
||||
<div id="root">
|
||||
<div class="error-console container"><%= t('talk-plugin-notifications.unsubscribe_page.token_invalid') %></div>
|
||||
<div id="success" style="display:none;" class="legend container"><%= t('talk-plugin-notifications.unsubscribe_page.are_unsubscribed') %></div>
|
||||
<form id="unsubscribe-form" class="container">
|
||||
<legend class="legend"><%= t('talk-plugin-notifications.unsubscribe_page.click_to_confirm') %></legend>
|
||||
<button type="submit"><%= t('talk-plugin-notifications.unsubscribe_page.confirm') %></button>
|
||||
</form>
|
||||
</div>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
var submitting = false;
|
||||
var payload = JSON.stringify({token: location.hash.replace('#', '')});
|
||||
function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (submitting) {
|
||||
return;
|
||||
}
|
||||
|
||||
submitting = true;
|
||||
$('.error-console').removeClass('active');
|
||||
|
||||
$.ajax({
|
||||
url: '<%= BASE_PATH %>api/v1/account/unsubscribe-notifications',
|
||||
contentType: 'application/json',
|
||||
method: 'POST',
|
||||
data: payload,
|
||||
}).then(function (success) {
|
||||
$('#unsubscribe-form').fadeOut(function () {
|
||||
$('#success').fadeIn();
|
||||
});
|
||||
}).catch(function () {
|
||||
submitting = false;
|
||||
$('.error-console').addClass('active');
|
||||
});
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '<%= BASE_PATH %>api/v1/account/unsubscribe-notifications/verify',
|
||||
contentType: 'application/json',
|
||||
method: 'POST',
|
||||
data: payload,
|
||||
})
|
||||
.then(function () {
|
||||
$('#unsubscribe-form').fadeIn().on('submit', handleSubmit);
|
||||
})
|
||||
.catch(function () {
|
||||
$('.error-console').addClass('active');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,68 @@
|
||||
{% extends "templates/account.njk" %}
|
||||
|
||||
{% block title %}{{ t('talk-plugin-notifications.unsubscribe_page.unsubscribe') }}{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{{ super() }}
|
||||
<style nonce="{{ nonce }}" type="text/css">
|
||||
#success { display:none; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block html %}
|
||||
<div id="root">
|
||||
<div class="error-console container">{{ t('talk-plugin-notifications.unsubscribe_page.token_invalid') }}</div>
|
||||
<div id="success" class="legend container">{{ t('talk-plugin-notifications.unsubscribe_page.are_unsubscribed') }}</div>
|
||||
<form id="unsubscribe-form" class="container">
|
||||
<legend class="legend">{{ t('talk-plugin-notifications.unsubscribe_page.click_to_confirm') }}</legend>
|
||||
<button type="submit">{{ t('talk-plugin-notifications.unsubscribe_page.confirm') }}</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
||||
<script nonce="{{ nonce }}" type="text/javascript">
|
||||
$(function() {
|
||||
var submitting = false;
|
||||
var payload = JSON.stringify({token: location.hash.replace('#', '')});
|
||||
function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (submitting) {
|
||||
return;
|
||||
}
|
||||
|
||||
submitting = true;
|
||||
$('.error-console').removeClass('active');
|
||||
|
||||
$.ajax({
|
||||
url: '{{ BASE_PATH }}api/v1/account/unsubscribe-notifications',
|
||||
contentType: 'application/json',
|
||||
method: 'POST',
|
||||
data: payload,
|
||||
}).then(function (success) {
|
||||
$('#unsubscribe-form').fadeOut(function () {
|
||||
$('#success').fadeIn();
|
||||
});
|
||||
}).catch(function () {
|
||||
submitting = false;
|
||||
$('.error-console').addClass('active');
|
||||
});
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '{{ BASE_PATH }}api/v1/account/unsubscribe-notifications/verify',
|
||||
contentType: 'application/json',
|
||||
method: 'POST',
|
||||
data: payload,
|
||||
})
|
||||
.then(function () {
|
||||
$('#unsubscribe-form').fadeIn().on('submit', handleSubmit);
|
||||
})
|
||||
.catch(function () {
|
||||
$('.error-console').addClass('active');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -23,4 +23,7 @@ const mapDispatchToProps = dispatch =>
|
||||
dispatch
|
||||
);
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(OffTopicFilter);
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(OffTopicFilter);
|
||||
|
||||
@@ -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>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user