Instantiate just one I18n instance to pass to all controllers
This commit is contained in:
parent
eda8e83d07
commit
c4f657b7b4
|
@ -1,10 +1,9 @@
|
|||
import { I18n } from '../i18n';
|
||||
|
||||
export class ViewController {
|
||||
constructor(state, viewName, defaultState = {}) {
|
||||
constructor(state, i18n, viewName, defaultState = {}) {
|
||||
// Store the global app state so it's accessible but out of the way.
|
||||
this.appState = state;
|
||||
this.i18n = new I18n(this.appState);
|
||||
this.i18n = i18n;
|
||||
this.i18n.__ = this.i18n.__.bind(i18n); // Allow pulling out just the `__` function for shortened translation declaration.
|
||||
|
||||
// Give this view its own state within the appState.
|
||||
if (!this.appState.viewStates.hasOwnProperty(viewName)) {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { ViewController } from '../controller';
|
||||
|
||||
export class HomeController extends ViewController {
|
||||
constructor(state) {
|
||||
constructor(state, i18n) {
|
||||
// Super passes state, view name, and default state to ViewController,
|
||||
// which stores state in this.appState and the view controller's state to this.state
|
||||
super(state, 'home', {
|
||||
super(state, i18n, 'home', {
|
||||
recentReviews: [],
|
||||
recentUpdates: [],
|
||||
});
|
||||
|
|
|
@ -4,8 +4,8 @@ import { HomeController } from './controller'; // The controller for this view,
|
|||
import { loggedOutView } from './loggedOut';
|
||||
|
||||
// This is the view function that is exported and used in the view manager.
|
||||
export const homeView = (state, emit) => {
|
||||
const controller = new HomeController(state);
|
||||
export const homeView = (state, emit, i18n) => {
|
||||
const controller = new HomeController(state, i18n);
|
||||
|
||||
// Returning an array in a view allows non-shared parent HTML elements.
|
||||
// This one doesn't have the problem right now, but it's good to remember.
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import html from 'choo/html';
|
||||
|
||||
export const loggedOutView = (homeController, emit) => {
|
||||
const { i18n } = homeController;
|
||||
|
||||
const { __ } = homeController.i18n;
|
||||
|
||||
return [
|
||||
html`<section>
|
||||
<h2>${i18n.__('home.logged_out_subtitle')}</h2>
|
||||
<h2>${__('home.logged_out_subtitle')}</h2>
|
||||
<article class="flex one three-500">
|
||||
<div>
|
||||
<div class="card">
|
||||
|
@ -15,7 +15,7 @@ export const loggedOutView = (homeController, emit) => {
|
|||
</span>
|
||||
</header>
|
||||
<footer>
|
||||
${i18n.__('home.logged_out_track_books')}
|
||||
${__('home.logged_out_track_books')}
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -27,7 +27,7 @@ export const loggedOutView = (homeController, emit) => {
|
|||
</span>
|
||||
</header>
|
||||
<footer>
|
||||
${i18n.__('home.logged_out_share_friends')}
|
||||
${__('home.logged_out_share_friends')}
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -39,20 +39,20 @@ export const loggedOutView = (homeController, emit) => {
|
|||
</span>
|
||||
</header>
|
||||
<footer>
|
||||
${i18n.__('home.logged_out_read_rate')}
|
||||
${__('home.logged_out_read_rate')}
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</section>`,
|
||||
html`<section>
|
||||
<h2>${i18n.__('home.logged_out_community_header')}</h2>
|
||||
<h2>${__('home.logged_out_community_header')}</h2>
|
||||
<div class="flex one two-700">
|
||||
<div>
|
||||
<div class="card">
|
||||
<header>
|
||||
<h3>${i18n.__('home.logged_out_recent_reviews')}</h3>
|
||||
<button class="small pseudo pull-right tooltip-left" data-tooltip=${i18n.__('interaction.reload')}>
|
||||
<h3>${__('home.logged_out_recent_reviews')}</h3>
|
||||
<button class="small pseudo pull-right tooltip-left" data-tooltip=${__('interaction.reload')}>
|
||||
<i class="icon-loading"></i><!--/* This needs to get updated to a reload icon */-->
|
||||
</button>
|
||||
</header>
|
||||
|
@ -64,8 +64,8 @@ export const loggedOutView = (homeController, emit) => {
|
|||
<div>
|
||||
<div class="card">
|
||||
<header>
|
||||
<h3>${i18n.__('home.logged_out_recent_updates')}</h3>
|
||||
<button class="small pseudo pull-right tooltip-left" data-tooltip=${i18n.__('interaction.reload')}>
|
||||
<h3>${__('home.logged_out_recent_updates')}</h3>
|
||||
<button class="small pseudo pull-right tooltip-left" data-tooltip=${__('interaction.reload')}>
|
||||
<i class="icon-loading"></i><!--/* This needs to get updated to a reload icon */-->
|
||||
</button>
|
||||
</header>
|
||||
|
@ -77,7 +77,7 @@ export const loggedOutView = (homeController, emit) => {
|
|||
</div>
|
||||
</section>`,
|
||||
html`<section class="center-align">
|
||||
<a href="/login" class="large success button">${i18n.__('home.logged_out_join_now')}</a>
|
||||
<a href="/login" class="large success button">${__('home.logged_out_join_now')}</a>
|
||||
</section>`,
|
||||
];
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
import { ViewController } from '../controller';
|
||||
|
||||
export class LoginController extends ViewController {
|
||||
constructor(state) {
|
||||
constructor(state, i18n) {
|
||||
// Super passes state, view name, and default state to ViewController,
|
||||
// which stores state in this.appState and the view controller's state to this.state
|
||||
super(state, 'login', {});
|
||||
super(state, i18n, 'login', {});
|
||||
|
||||
// If using controller methods in an input's onchange or onclick instance,
|
||||
// either bind the class's 'this' instance to the method first...
|
||||
|
|
|
@ -2,9 +2,9 @@ import html from 'choo/html';
|
|||
|
||||
import { LoginController } from './controller';
|
||||
|
||||
export const loginView = (state, emit) => {
|
||||
const controller = new LoginController(state);
|
||||
const { i18n } = controller;
|
||||
export const loginView = (state, emit, i18n) => {
|
||||
const controller = new LoginController(state, i18n);
|
||||
const { __ } = controller.i18n;
|
||||
|
||||
return html`<section>
|
||||
|
||||
|
@ -12,48 +12,48 @@ export const loginView = (state, emit) => {
|
|||
<div>
|
||||
<article class="card">
|
||||
<header>
|
||||
<h3>${i18n.__('login.log_in')}</h3>
|
||||
<h3>${__('login.log_in')}</h3>
|
||||
</header>
|
||||
<footer>
|
||||
<label>
|
||||
<span>${i18n.__('login.email')}</span>
|
||||
<span>${__('login.email')}</span>
|
||||
<input type="email" name="email">
|
||||
</label>
|
||||
<label>
|
||||
<span>${i18n.__('login.password')}</span>
|
||||
<span>${__('login.password')}</span>
|
||||
<input type="password" name="password">
|
||||
</label>
|
||||
<input type="submit" value="${i18n.__('login.login_button')}">
|
||||
<input type="submit" value="${__('login.login_button')}">
|
||||
</footer>
|
||||
</article>
|
||||
</div>
|
||||
<div>
|
||||
<article class="card">
|
||||
<header>
|
||||
<h3>${i18n.__('login.create_account')}</h3>
|
||||
<h3>${__('login.create_account')}</h3>
|
||||
</header>
|
||||
<footer>
|
||||
<label>
|
||||
<span>${i18n.__('login.email')}</span>
|
||||
<span>${__('login.email')}</span>
|
||||
<input type="email" name="new_email">
|
||||
</label>
|
||||
<label>
|
||||
<span>${i18n.__('login.password')}</span>
|
||||
<span>${__('login.password')}</span>
|
||||
<input type="password" name="new_password">
|
||||
</label>
|
||||
<label>
|
||||
<span>${i18n.__('login.confirm_password')}</span>
|
||||
<span>${__('login.confirm_password')}</span>
|
||||
<input type="password" name="confirm_password">
|
||||
</label>
|
||||
<label>
|
||||
<span>${i18n.__('login.username')}</span>
|
||||
<span>${__('login.username')}</span>
|
||||
<input type="text" name="new_username">
|
||||
</label>
|
||||
<label>
|
||||
<span>${i18n.__('login.display_name')}</span>
|
||||
<span>${__('login.display_name')}</span>
|
||||
<input type="text" name="new_displayname">
|
||||
</label>
|
||||
<input type="submit" class="success" value="${i18n.__('login.create_account_button')}">
|
||||
<input type="submit" class="success" value="${__('login.create_account_button')}">
|
||||
</footer>
|
||||
</article>
|
||||
</div>
|
||||
|
|
|
@ -8,22 +8,22 @@ import { loginView } from './login';
|
|||
import { searchView } from './search';
|
||||
|
||||
export const viewManager = (state, emit) => {
|
||||
const i18n = new I18n(state);
|
||||
const i18n = new I18n(state); // Global I18n class passed to all views
|
||||
// In viewManager all we are doing is checking the app's state
|
||||
// and passing the state and emit to the relevant view.
|
||||
let htmlContent = html`<div>loading</div>`;
|
||||
switch (state.params.page) {
|
||||
case 'home':
|
||||
default: {
|
||||
htmlContent = homeView(state, emit);
|
||||
htmlContent = homeView(state, emit, i18n);
|
||||
break;
|
||||
}
|
||||
case 'login': {
|
||||
htmlContent = loginView(state, emit);
|
||||
htmlContent = loginView(state, emit, i18n);
|
||||
break;
|
||||
}
|
||||
case 'search': {
|
||||
htmlContent = searchView(state, emit);
|
||||
htmlContent = searchView(state, emit, i18n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import html from 'choo/html';
|
|||
import { starRating } from './starRating';
|
||||
|
||||
export const reviewCard = (controller, review) => {
|
||||
const { i18n } = controller;
|
||||
const { __ } = controller.i18n;
|
||||
|
||||
return html`<article class="card">
|
||||
<header style="font-weight:normal;">
|
||||
|
@ -16,7 +16,7 @@ export const reviewCard = (controller, review) => {
|
|||
${review.review}
|
||||
</p>
|
||||
</div>
|
||||
<span class="tooltip-top" data-tooltip=${i18n.__('interaction.heart')}>
|
||||
<span class="tooltip-top" data-tooltip=${__('interaction.heart')}>
|
||||
<button class="pseudo">
|
||||
<i class="icon-heart-outline"></i>
|
||||
</button>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { ViewController } from '../controller';
|
||||
|
||||
export class SearchController extends ViewController {
|
||||
constructor(state) {
|
||||
constructor(state, i18n) {
|
||||
// Super passes state, view name, and default state to ViewController,
|
||||
// which stores state in this.appState and the view controller's state to this.state
|
||||
super(state, 'search', {
|
||||
super(state, i18n, 'search', {
|
||||
lastSearch: undefined,
|
||||
done: false,
|
||||
results: {
|
||||
|
|
|
@ -4,12 +4,11 @@ import { SearchController } from './controller'; // The controller for this vie
|
|||
import { resultDetails } from './resultDetails';
|
||||
|
||||
// This is the view function that is exported and used in the view manager.
|
||||
export const searchView = (state, emit) => {
|
||||
const controller = new SearchController(state);
|
||||
const { i18n } = controller;
|
||||
export const searchView = (state, emit, i18n) => {
|
||||
const controller = new SearchController(state, i18n);
|
||||
const { __ } = controller.i18n;
|
||||
|
||||
if (controller.state.lastSearch !== state.query.for) {
|
||||
console.log('searching!');
|
||||
controller.search().then(() => {
|
||||
emit('render');
|
||||
});
|
||||
|
@ -19,7 +18,7 @@ export const searchView = (state, emit) => {
|
|||
// This one doesn't have the problem right now, but it's good to remember.
|
||||
return [
|
||||
html`<section>
|
||||
<h1 class="title">${i18n.__('search.header')}</h1>
|
||||
<h1 class="title">${__('search.header')}</h1>
|
||||
|
||||
<article>
|
||||
${controller.doneSearching ? null : html`<h2><i class="icon-loading animate-spin"></i></h2>`}
|
||||
|
@ -27,7 +26,7 @@ export const searchView = (state, emit) => {
|
|||
${controller.results.works < 1
|
||||
? null
|
||||
: [
|
||||
html`<h2>${i18n.__('search.books_header')}</h2>`,
|
||||
html`<h2>${__('search.books_header')}</h2>`,
|
||||
controller.results.works.map(result => {
|
||||
return html`<div class="flex search-result">
|
||||
<div class="two-third-800 half-500">
|
||||
|
@ -44,7 +43,7 @@ export const searchView = (state, emit) => {
|
|||
${controller.results.series.length < 1
|
||||
? null
|
||||
: [
|
||||
html`<h2>${i18n.__('search.series_header')}</h2>`,
|
||||
html`<h2>${__('search.series_header')}</h2>`,
|
||||
controller.results.series.map(result => {
|
||||
return html`<div class="flex search-result">
|
||||
<div class="two-third-800 half-500">
|
||||
|
@ -52,9 +51,9 @@ export const searchView = (state, emit) => {
|
|||
${result.description ? html`<h4 class="subtitle">${result.description}</h4>` : null}
|
||||
</div>
|
||||
<div class="third-800 half-500">
|
||||
<span class="tooltip-left" data-tooltip=${i18n.__('search.see_details_tooltip')}>
|
||||
<span class="tooltip-left" data-tooltip=${__('search.see_details_tooltip')}>
|
||||
<a class="small pseudo button" href=${result.link} target="_blank">
|
||||
${i18n.__('search.see_inventaire_details')}
|
||||
${__('search.see_inventaire_details')}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -65,7 +64,7 @@ export const searchView = (state, emit) => {
|
|||
${controller.results.humans.length < 1
|
||||
? null
|
||||
: [
|
||||
html`<h2>${i18n.__('search.people_header')}</h2>`,
|
||||
html`<h2>${__('search.people_header')}</h2>`,
|
||||
controller.results.humans.map(result => {
|
||||
return html`<div class="flex search-result">
|
||||
<div class="sixth">
|
||||
|
@ -76,9 +75,9 @@ export const searchView = (state, emit) => {
|
|||
${result.description ? html`<h4 class="subtitle">${result.description}</h4>` : null}
|
||||
</div>
|
||||
<div class="third-800">
|
||||
<span class="tooltip-left" data-tooltip=${i18n.__('search.see_details_tooltip')}>
|
||||
<span class="tooltip-left" data-tooltip=${__('search.see_details_tooltip')}>
|
||||
<a class="small pseudo button" href=${result.link} target="_blank">
|
||||
${i18n.__('search.see_inventaire_details')}
|
||||
${__('search.see_inventaire_details')}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -5,14 +5,14 @@ import { starRating } from '../partials/starRating';
|
|||
import { modal } from '../partials/modal';
|
||||
|
||||
export const resultDetails = (searchController, result, emit = () => {}) => {
|
||||
const { i18n } = searchController;
|
||||
const { __ } = searchController.i18n;
|
||||
const modalId = `result_${result.uri}`;
|
||||
|
||||
const buttonHTML = html`<label for=${modalId} class="pseudo button">
|
||||
<span data-tooltip="${i18n.__('interaction.average_rating')}: ${result.averageRating}">
|
||||
<span data-tooltip="${__('interaction.average_rating')}: ${result.averageRating}">
|
||||
${starRating(result.averageRating)}
|
||||
</span>
|
||||
<span style="margin-left:10px;" data-tooltip=${i18n.__('interaction.reviews_written')}>
|
||||
<span style="margin-left:10px;" data-tooltip=${__('interaction.reviews_written')}>
|
||||
<span style="margin-right:8px;"><i class="icon-chat"></i></span>
|
||||
<span>${result.numberOfReviews}</span>
|
||||
</span>
|
||||
|
@ -55,7 +55,7 @@ export const resultDetails = (searchController, result, emit = () => {}) => {
|
|||
}
|
||||
</div>
|
||||
<div class="two-third-700">
|
||||
<h4>${i18n.__('interaction.average_rating')}</h4>
|
||||
<h4>${__('interaction.average_rating')}</h4>
|
||||
<span data-tooltip="${result.averageRating}">${starRating(result.averageRating)}</span>
|
||||
|
||||
<div class="flex">
|
||||
|
@ -66,7 +66,7 @@ export const resultDetails = (searchController, result, emit = () => {}) => {
|
|||
<a href="/book/${result.uri}" class="small button">
|
||||
<span style="margin-right:8px;"><i class="icon-chat"></i></span>
|
||||
<span>${result.numberOfReviews}</span>
|
||||
<span>${i18n.__('search.see_interaction_details')}</span>
|
||||
<span>${__('search.see_interaction_details')}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -76,16 +76,16 @@ export const resultDetails = (searchController, result, emit = () => {}) => {
|
|||
</div>
|
||||
<div class="sixth-700">
|
||||
<p>
|
||||
<span data-tooltip=${i18n.__('interaction.add')}>
|
||||
<span data-tooltip=${__('interaction.add')}>
|
||||
<button class="success">
|
||||
<i class="icon-plus"></i>
|
||||
</button>
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<span data-tooltip=${i18n.__('search.see_details_tooltip')}>
|
||||
<span data-tooltip=${__('search.see_details_tooltip')}>
|
||||
<a class="small pseudo button" href=${result.link} target="_blank">
|
||||
${i18n.__('search.see_book_details')}
|
||||
${__('search.see_book_details')}
|
||||
</a>
|
||||
</span>
|
||||
</p>
|
||||
|
|
Loading…
Reference in New Issue