Utilize nested locale translations and update usage

This commit is contained in:
Robbie Antenesse 2019-12-01 14:08:12 -07:00
parent 3c40673774
commit cd4e628e11
8 changed files with 116 additions and 94 deletions

View File

@ -25,11 +25,11 @@ export const appUtilities = (app) => {
.then(response => response.json()) .then(response => response.json())
.then(response => { .then(response => {
if (response.error !== false) { if (response.error !== false) {
console.warn(response); console.warn(appState.i18n.__(response.message));
return false; return false;
} }
console.info(response.message); console.info(appState.i18n.__(response.message));
appState.isLoggedIn = true; appState.isLoggedIn = true;
return true; return true;
}); });

View File

@ -5,12 +5,12 @@ export const loggedInView = (homeController, emit) => {
return [ return [
html`<section> html`<section>
<h2>${__('home.logged_in_subtitle')}</h2> <h2>${__('home.logged_in.subtitle')}</h2>
<div class="flex one two-700"> <div class="flex one two-700">
<div> <div>
<div class="card"> <div class="card">
<header> <header>
<h3>${__('home.logged_in_updates')}</h3> <h3>${__('home.logged_in.updates')}</h3>
<button class="small pseudo pull-right tooltip-left" data-tooltip=${__('interaction.reload')}> <button class="small pseudo pull-right tooltip-left" data-tooltip=${__('interaction.reload')}>
<i class="icon-reload"></i> <i class="icon-reload"></i>
</button> </button>
@ -23,7 +23,7 @@ export const loggedInView = (homeController, emit) => {
<div> <div>
<div class="card"> <div class="card">
<header> <header>
<h3>${__('home.logged_in_interactions')}</h3> <h3>${__('home.logged_in.interactions')}</h3>
<button class="small pseudo pull-right tooltip-left" data-tooltip=${__('interaction.reload')}> <button class="small pseudo pull-right tooltip-left" data-tooltip=${__('interaction.reload')}>
<i class="icon-reload"></i> <i class="icon-reload"></i>
</button> </button>

View File

@ -5,7 +5,7 @@ export const loggedOutView = (homeController, emit) => {
return [ return [
html`<section> html`<section>
<h2>${__('home.logged_out_subtitle')}</h2> <h2>${__('home.logged_out.subtitle')}</h2>
<article class="flex one three-500"> <article class="flex one three-500">
<div> <div>
<div class="card"> <div class="card">
@ -15,7 +15,7 @@ export const loggedOutView = (homeController, emit) => {
</span> </span>
</header> </header>
<footer> <footer>
${__('home.logged_out_track_books')} ${__('home.logged_out.track_books')}
</footer> </footer>
</div> </div>
</div> </div>
@ -27,7 +27,7 @@ export const loggedOutView = (homeController, emit) => {
</span> </span>
</header> </header>
<footer> <footer>
${__('home.logged_out_share_friends')} ${__('home.logged_out.share_friends')}
</footer> </footer>
</div> </div>
</div> </div>
@ -39,19 +39,19 @@ export const loggedOutView = (homeController, emit) => {
</span> </span>
</header> </header>
<footer> <footer>
${__('home.logged_out_read_rate')} ${__('home.logged_out.read_rate')}
</footer> </footer>
</div> </div>
</div> </div>
</article> </article>
</section>`, </section>`,
html`<section> html`<section>
<h2>${__('home.logged_out_community_header')}</h2> <h2>${__('home.logged_out.community_header')}</h2>
<div class="flex one two-700"> <div class="flex one two-700">
<div> <div>
<div class="card"> <div class="card">
<header> <header>
<h3>${__('home.logged_out_recent_reviews')}</h3> <h3>${__('home.logged_out.recent_reviews')}</h3>
<button class="small pseudo pull-right tooltip-left" data-tooltip=${__('interaction.reload')}> <button class="small pseudo pull-right tooltip-left" data-tooltip=${__('interaction.reload')}>
<i class="icon-reload"></i> <i class="icon-reload"></i>
</button> </button>
@ -64,7 +64,7 @@ export const loggedOutView = (homeController, emit) => {
<div> <div>
<div class="card"> <div class="card">
<header> <header>
<h3>${__('home.logged_out_recent_updates')}</h3> <h3>${__('home.logged_out.recent_updates')}</h3>
<button class="small pseudo pull-right tooltip-left" data-tooltip=${__('interaction.reload')}> <button class="small pseudo pull-right tooltip-left" data-tooltip=${__('interaction.reload')}>
<i class="icon-reload"></i> <i class="icon-reload"></i>
</button> </button>
@ -77,7 +77,7 @@ export const loggedOutView = (homeController, emit) => {
</div> </div>
</section>`, </section>`,
html`<section class="center-align"> html`<section class="center-align">
<a href="/login" class="large success button">${__('home.logged_out_join_now')}</a> <a href="/login" class="large success button">${__('home.logged_out.join_now')}</a>
</section>`, </section>`,
]; ];
} }

View File

@ -20,7 +20,7 @@ export const loginView = (state, emit, i18n) => {
<header> <header>
${ ${
controller.state.loginMessage === '' controller.state.loginMessage === ''
? __('login.already_logged_in') ? __('api.already_logged_in')
: controller.state.loginMessage : controller.state.loginMessage
} }
</header> </header>

View File

@ -48,7 +48,7 @@ export const searchView = (state, emit, i18n) => {
<div> <div>
${modal('searchSourceInfo', controller, [ ${modal('searchSourceInfo', controller, [
html`<p> html`<p>
${__('search.search_source_help_text')} ${__('search.search_source.help.text')}
</p>`, </p>`,
html`<ul> html`<ul>
<li> <li>
@ -57,7 +57,7 @@ export const searchView = (state, emit, i18n) => {
</a> </a>
<ul> <ul>
<li> <li>
${__('search.search_source_help_inventaire')} ${__('search.search_source.help.inventaire')}
</li> </li>
</ul> </ul>
</li> </li>
@ -67,18 +67,18 @@ export const searchView = (state, emit, i18n) => {
</a> </a>
<ul> <ul>
<li> <li>
${__('search.search_source_help_openLibrary')} ${__('search.search_source.help.openLibrary')}
</li> </li>
</ul> </ul>
</li> </li>
</ul>`, </ul>`,
], { ], {
buttonText: __('search.search_source_help_button'), buttonText: __('search.search_source.help.button'),
buttonClasses: 'small marginless pseudo button pull-right', buttonClasses: 'small marginless pseudo button pull-right',
headerText: __('search.search_source_help_header'), headerText: __('search.search_source.help.header'),
})} })}
<label> <label>
${__('search.search_source_label')} ${__('search.search_source.label')}
<select onchange=${event => { <select onchange=${event => {
controller.state.searchSource = event.target.value; controller.state.searchSource = event.target.value;
@ -93,7 +93,7 @@ export const searchView = (state, emit, i18n) => {
</label> </label>
</div> </div>
<div> <div>
${__('search.search_by_label')}<br> ${__('search.search_by.label')}<br>
<label> <label>
<input type="radio" name="searchBy" value="title" <input type="radio" name="searchBy" value="title"
@ -105,7 +105,7 @@ export const searchView = (state, emit, i18n) => {
}} }}
> >
<span class="checkable"> <span class="checkable">
${__('search.search_by_title')} ${__('search.search_by.title')}
</span> </span>
</label> </label>
<label> <label>
@ -118,7 +118,7 @@ export const searchView = (state, emit, i18n) => {
}} }}
> >
<span class="checkable"> <span class="checkable">
${__('search.search_by_author')} ${__('search.search_by.author')}
</span> </span>
</label> </label>
</div> </div>

View File

@ -30,19 +30,19 @@ class AccountController {
|| createAccountData.password === '') { || createAccountData.password === '') {
return { return {
error: true, error: true,
message: 'api.account_create_required_data_missing', message: 'api.account.create.required_data_missing',
}; };
} }
if (createAccountData.email.length < 5 || !/^.+@.+\..+$/.test(createAccountData.email)) { if (createAccountData.email.length < 5 || !/^.+@.+\..+$/.test(createAccountData.email)) {
return { return {
error: true, error: true,
message: 'api.account_create_invalid_email', message: 'api.account.create.invalid_email',
}; };
} }
if (createAccountData.username.length < 2 || !/^[a-z0-9_]+$/i.test(createAccountData.username)) { if (createAccountData.username.length < 2 || !/^[a-z0-9_]+$/i.test(createAccountData.username)) {
return { return {
error: true, error: true,
message: 'api.account_create_invalid_username', message: 'api.account.create.invalid_username',
}; };
} }
@ -55,13 +55,13 @@ class AccountController {
|| loginData.password === '') { || loginData.password === '') {
return { return {
error: true, error: true,
message: 'api.account_login_required_data_missing', message: 'api.account.login.required_data_missing',
}; };
} }
if (loginData.email.length < 5 || !/^.+@.+\..+$/.test(loginData.email)) { if (loginData.email.length < 5 || !/^.+@.+\..+$/.test(loginData.email)) {
return { return {
error: true, error: true,
message: 'api.account_login_invalid_email', message: 'api.account.login.invalid_email',
}; };
} }
@ -84,7 +84,7 @@ class AccountController {
|| !createAccountData.confirm) { || !createAccountData.confirm) {
return { return {
error: true, error: true,
message: 'api.account_confirm_required_data_missing', message: 'api.account.confirm.required_data_missing',
}; };
} }
@ -117,13 +117,13 @@ class AccountController {
if (emailExists) { if (emailExists) {
return { return {
error: true, error: true,
message: 'api.account_email_exists', message: 'api.account.email_exists',
}; };
} }
if (usernameExists) { if (usernameExists) {
return { return {
error: true, error: true,
message: 'api.account_username_exists', message: 'api.account.username_exists',
}; };
} }
@ -160,7 +160,7 @@ class AccountController {
if (!userToConfirm) { if (!userToConfirm) {
return { return {
error: true, error: true,
message: 'api.account_confirm_invalid_code', message: 'api.account.confirm.invalid_code',
} }
} }
@ -175,7 +175,7 @@ class AccountController {
if (success[0] < 1) { if (success[0] < 1) {
return { return {
error: true, error: true,
message: 'api.account_confirm_update_fail', message: 'api.account.confirm.update_fail',
} }
} }
return userToConfirm; return userToConfirm;
@ -192,14 +192,14 @@ class AccountController {
if (existingUser == null) { if (existingUser == null) {
return { return {
error: true, error: true,
message: 'api.account_login_invalid_email', message: 'api.account.login.invalid_email',
}; };
} }
if (existingUser.accountConfirm !== null) { if (existingUser.accountConfirm !== null) {
return { return {
error: true, error: true,
message: 'api.account_login_not_confirmed', message: 'api.account.login.not_confirmed',
}; };
} }
@ -207,7 +207,7 @@ class AccountController {
if (!passwordIsValid) { if (!passwordIsValid) {
return { return {
error: true, error: true,
message: 'api.account_login_invalid_password', message: 'api.account.login.invalid_password',
}; };
} }

View File

@ -9,20 +9,24 @@
"menu_logout": "Log Out", "menu_logout": "Log Out",
"footer_repo": "Repo", "footer_repo": "Repo",
"footer_chat": "Chat", "footer_chat": "Chat",
"change_language": "Change Language" "change_language": "Language"
}, },
"home": { "home": {
"logged_out_subtitle": "All the Book Buzz in Once Place", "logged_out": {
"logged_out_track_books": "Keep track of books you've read, want to read, and are currently reading.", "subtitle": "All the Book Buzz in Once Place",
"logged_out_share_friends": "Share your thoughts about what you're reading and see what your friends think of their books.", "track_books": "Keep track of books you've read, want to read, and are currently reading.",
"logged_out_read_rate": "Rate, review, and recommmend books or something. I dunno. It's early days, my friends!", "share_friends": "Share your thoughts about what you're reading and see what your friends think of their books.",
"logged_out_community_header": "A Look Inside the Hive", "read_rate": "Rate, review, and recommmend books or something. I dunno. It's early days, my friends!",
"logged_out_recent_reviews": "Recent Reviews", "community_header": "A Look Inside the Hive",
"logged_out_recent_updates": "Recent Updates", "recent_reviews": "Recent Reviews",
"logged_out_join_now": "Join Now!", "recent_updates": "Recent Updates",
"logged_in_subtitle": "Welcome!", "join_now": "Join Now!"
"logged_in_updates": "Updates", },
"logged_in_interactions": "Interactions" "logged_in": {
"subtitle": "Welcome!",
"updates": "Updates",
"interactions": "Interactions"
}
}, },
"404": { "404": {
"header": "Oops!", "header": "Oops!",
@ -46,15 +50,21 @@
"header": "Search", "header": "Search",
"placeholder": "Search for Books", "placeholder": "Search for Books",
"button_text": "Search", "button_text": "Search",
"search_source_label": "Search Source", "search_source": {
"search_source_help_button": "What's This?", "label": "Search Source",
"search_source_help_header": "What does \"Search Source\" mean?", "help": {
"search_source_help_text": "This refers to where the search tries to look for data. Each source can be easily contributed to if you want to add missing books or correct errors.", "button": "What's This?",
"search_source_help_inventaire": "Sources and extends data from WikiData, the service structure that powers Wikipedia and the like. Offers as many language options as possible.", "header": "What does \"Search Source\" mean?",
"search_source_help_openLibrary": "Sources data from Internet Archive and may provide a digital copy to read. Only offers English unless a work is in another language.", "text": "This refers to where the search tries to look for data. Each source can be easily contributed to if you want to add missing books or correct errors.",
"search_by_label": "Search By", "inventaire": "Sources and extends data from WikiData, the service structure that powers Wikipedia and the like. Offers as many language options as possible.",
"search_by_title": "Title", "openLibrary": "Sources data from Internet Archive and may provide a digital copy to read. Only offers English unless a work is in another language."
"search_by_author": "Author", }
},
"search_by": {
"label": "Search By",
"title": "Title",
"author": "Author"
},
"loading": "Loading...", "loading": "Loading...",
"no_results": "None Found", "no_results": "None Found",
"no_results_suggestion": "If you're expecting book data, go and help fill out the Inventaire database!", "no_results_suggestion": "If you're expecting book data, go and help fill out the Inventaire database!",
@ -73,28 +83,40 @@
"reviews_written": "Total Reviews Written" "reviews_written": "Total Reviews Written"
}, },
"api": { "api": {
"account_already_logged_in": "You are already logged in! You cannot create an account or log in again.", "not_logged_in": "You are not logged in.",
"account_create_required_data_missing": "Could not create account because required data is missing.", "already_logged_in": "You are already logged in! You cannot create an account or log in again.",
"account_create_invalid_email": "The email address entered is not valid.", "account": {
"account_create_invalid_username": "The username entered is not valid. Usernames must be at least 2 characters long and can only contain letters az, numbers 09, and underscores", "username_exists": "The username entered is already in use.",
"account_email_exists": "The email address entered is already in use.", "email_send_fail": "Your account was created successfully, but we were unable to send the confirmation email!",
"account_username_exists": "The username entered is already in use.", "email_exists": "The email address entered is already in use.",
"account_email_send_fail": "Your account was created successfully, but we were unable to send the confirmation email!", "create": {
"account_confirm_email": "A confirmation email has been sent to the address you specified. Please confirm your account using the link provided.", "fail": "Something went wrong and the account could not be created. Please try again later.",
"account_create_success": "Account created successfully! You may now log in using the email address and password you provided.", "required_data_missing": "Could not create account because required data is missing.",
"account_confirm_required_data_missing": "Could not confirm account because required data is missing.", "invalid_email": "The email address entered is not valid.",
"account_confirm_invalid_code": "The specified confirmation code is not valid.", "invalid_username": "The username entered is not valid. Usernames must be at least 2 characters long and can only contain letters az, numbers 09, and underscores",
"account_confirm_update_fail": "Something went wrong and we couldn't confirm your account. Please try again later!", "success": "Account created successfully! You may now log in using the email address and password you provided."
"account_confirm_email_send_fail": "Your account has been confirmed, but we were unable to send the email notification about it. You can log in anyway.", },
"account_confirm_success_email": "Your account has been confirmed, and an email notification has been sent! You may now log in using your email address and password.", "confirm": {
"account_confirm_success": "Your account has been confirmed! You may now log in using your email address and password.", "email": "A confirmation email has been sent to the address you specified. Please confirm your account using the link provided.",
"account_login_required_data_missing": "Could not attempt login because required data is missing.", "required_data_missing": "Could not confirm account because required data is missing.",
"account_login_invalid_email": "The email address specified does not have an associated account.", "invalid_code": "The specified confirmation code is not valid.",
"account_login_not_confirmed": "The specified account has not been confirmed. Please use the link you received to confirm your email address.", "update_fail": "Something went wrong and we couldn't confirm your account. Please try again later!",
"account_login_invalid_password": "The password specified is not correct.", "email_send_fail": "Your account has been confirmed, but we were unable to send the email notification about it. You can log in anyway.",
"account_login_success": "You have been successfully logged in! You will now be redirected to the home screen.", "success_email": "Your account has been confirmed, and an email notification has been sent! You may now log in using your email address and password.",
"account_validate_missing_token": "User not logged in: There is no login token to validate.", "success": "Your account has been confirmed! You may now log in using your email address and password."
"account_validate_invalid_token": "User not logged in: The stored token is not a valid token.", },
"account_validate_renewed_token": "User logged in, and the token has been renewed." "login": {
"required_data_missing": "Could not attempt login because required data is missing.",
"invalid_email": "The email address specified does not have an associated account.",
"not_confirmed": "The specified account has not been confirmed. Please use the link you received to confirm your email address.",
"invalid_password": "The password specified is not correct.",
"success": "You have been successfully logged in! You will now be redirected to the home screen."
},
"validate": {
"missing_token": "User not logged in: There is no login token to validate.",
"invalid_token": "User not logged in: The stored token is not a valid token.",
"renewed_token": "User logged in, and the token has been renewed."
}
}
} }
} }

View File

@ -12,7 +12,7 @@ async function routes(fastify, options) {
if (request.isLoggedInUser) { if (request.isLoggedInUser) {
return reply.code(400).send({ return reply.code(400).send({
error: true, error: true,
message: 'api.account_already_logged_in', message: 'api.already_logged_in',
}); });
} }
@ -33,7 +33,7 @@ async function routes(fastify, options) {
const newUser = await account.createUser(formData.email, formData.username, formData.displayName, formData.password, fastify.canEmail); const newUser = await account.createUser(formData.email, formData.username, formData.displayName, formData.password, fastify.canEmail);
if (typeof newUser.error !== 'undefined' && newUser.error !== false) { if (typeof newUser.error !== 'undefined' && newUser.error !== false) {
newUser.message = 'api.account_create_fail'; newUser.message = 'api.account.create.fail';
return reply.code(400).send(newUser); return reply.code(400).send(newUser);
} }
@ -43,7 +43,7 @@ async function routes(fastify, options) {
// If some of the default shelves are not created successfully, delete the user and send an error // If some of the default shelves are not created successfully, delete the user and send an error
if (typeof defaultShelvesCreated.error !== 'undefined' && defaultShelvesCreated.error !== false) { if (typeof defaultShelvesCreated.error !== 'undefined' && defaultShelvesCreated.error !== false) {
account.deleteUser(newUser); account.deleteUser(newUser);
defaultShelvesCreated.message = 'api.account_create_fail'; defaultShelvesCreated.message = 'api.account.create.fail';
return reply.code(400).send(defaultShelvesCreated); return reply.code(400).send(defaultShelvesCreated);
} }
@ -72,14 +72,14 @@ async function routes(fastify, options) {
console.error(email.err); console.error(email.err);
return reply.send({ return reply.send({
error: true, error: true,
message: 'api.account_email_send_fail', message: 'api.account.email_send_fail',
newUser, newUser,
}); });
} }
return reply.send({ return reply.send({
error: false, error: false,
message: 'api.account_confirm_email', message: 'api.account.confirm.email',
}); });
}); });
} catch (ex) { } catch (ex) {
@ -89,7 +89,7 @@ async function routes(fastify, options) {
return reply.send({ return reply.send({
error: false, error: false,
message: 'api.account_create_success', message: 'api.account.create.success',
}); });
}); });
@ -97,7 +97,7 @@ async function routes(fastify, options) {
if (request.isLoggedInUser) { if (request.isLoggedInUser) {
return reply.code(400).send({ return reply.code(400).send({
error: true, error: true,
message: 'api.account_already_logged_in', message: 'api.already_logged_in',
}); });
} }
@ -137,13 +137,13 @@ async function routes(fastify, options) {
console.error(email.err); console.error(email.err);
return reply.code(400).send({ return reply.code(400).send({
error: true, error: true,
message: 'api.account_confirm_email_send_fail', message: 'api.account.confirm.email_send_fail',
}); });
} }
return reply.send({ return reply.send({
error: false, error: false,
message: 'api.account_confirm_success_email', message: 'api.account.confirm.success_email',
}); });
}) })
} catch (ex) { } catch (ex) {
@ -152,7 +152,7 @@ async function routes(fastify, options) {
return reply.send({ return reply.send({
error: false, error: false,
message: 'api.account_confirm_success', message: 'api.account.confirm.success',
}); });
}); });
@ -182,7 +182,7 @@ async function routes(fastify, options) {
}) })
.send({ .send({
error: false, error: false,
message: 'api.account_login_success', message: 'api.account.login.success',
}); });
}); });
@ -190,7 +190,7 @@ async function routes(fastify, options) {
if (typeof request.cookies.token === "undefined") { if (typeof request.cookies.token === "undefined") {
return reply.code(400).send({ return reply.code(400).send({
error: true, error: true,
message: 'api.account_validate_missing_token', message: 'api.account.validate.missing_token',
}); });
} }
@ -198,7 +198,7 @@ async function routes(fastify, options) {
if (!tokenIsValid) { if (!tokenIsValid) {
return reply.code(400).send({ return reply.code(400).send({
error: true, error: true,
message: 'api.account_validate_invalid_token', message: 'api.account.validate.invalid_token',
}); });
} }
@ -214,7 +214,7 @@ async function routes(fastify, options) {
}) })
.send({ .send({
error: false, error: false,
message: 'api.account_validate_renewed_token', message: 'api.account.validate.renewed_token',
}); });
}); });