mirror of
https://github.com/ascribe/onion.git
synced 2024-12-23 01:39:36 +01:00
merge localization
This commit is contained in:
commit
0ef0558e3f
@ -15,7 +15,6 @@ class PieceListActions {
|
|||||||
PieceListFetcher
|
PieceListFetcher
|
||||||
.fetch(page, pageSize, search, orderBy, orderAsc)
|
.fetch(page, pageSize, search, orderBy, orderAsc)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log(res);
|
|
||||||
this.actions.updatePieceList({
|
this.actions.updatePieceList({
|
||||||
page,
|
page,
|
||||||
pageSize,
|
pageSize,
|
||||||
|
@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
|
|
||||||
import AccordionListItemTable from './accordion_list_item_table';
|
import AccordionListItemTable from './accordion_list_item_table';
|
||||||
|
|
||||||
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
let AccordionListItem = React.createClass({
|
let AccordionListItem = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
@ -19,7 +20,7 @@ let AccordionListItem = React.createClass({
|
|||||||
</div>
|
</div>
|
||||||
<div className="info-wrapper">
|
<div className="info-wrapper">
|
||||||
<h1>{this.props.content.title}</h1>
|
<h1>{this.props.content.title}</h1>
|
||||||
<h3>by {this.props.content.artist_name}</h3>
|
<h3>{getLangText('by %s', this.props.content.artist_name)}</h3>
|
||||||
</div>
|
</div>
|
||||||
<span style={{'clear': 'both'}}></span>
|
<span style={{'clear': 'both'}}></span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,6 +5,8 @@ import TableItem from '../ascribe_table/table_item';
|
|||||||
|
|
||||||
import TableColumnContentModel from '../../models/table_column_content_model';
|
import TableColumnContentModel from '../../models/table_column_content_model';
|
||||||
|
|
||||||
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
let AccordionListItemTable = React.createClass({
|
let AccordionListItemTable = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
className: React.PropTypes.string,
|
className: React.PropTypes.string,
|
||||||
|
@ -15,6 +15,8 @@ import TableItemText from '../ascribe_table/table_item_text';
|
|||||||
import TableItemCheckbox from '../ascribe_table/table_item_checkbox';
|
import TableItemCheckbox from '../ascribe_table/table_item_checkbox';
|
||||||
import TableItemAclFiltered from '../ascribe_table/table_item_acl_filtered';
|
import TableItemAclFiltered from '../ascribe_table/table_item_acl_filtered';
|
||||||
|
|
||||||
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
let AccordionListItemTableEditions = React.createClass({
|
let AccordionListItemTableEditions = React.createClass({
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
@ -52,9 +54,9 @@ let AccordionListItemTableEditions = React.createClass({
|
|||||||
render() {
|
render() {
|
||||||
let columnList = [
|
let columnList = [
|
||||||
new TableColumnContentModel((item) => { return { 'editionId': item.id, 'pieceId': this.props.parentId, 'selectItem': this.selectItem, 'selected': item.selected }}, '', '', TableItemCheckbox, 1, false),
|
new TableColumnContentModel((item) => { return { 'editionId': item.id, 'pieceId': this.props.parentId, 'selectItem': this.selectItem, 'selected': item.selected }}, '', '', TableItemCheckbox, 1, false),
|
||||||
new TableColumnContentModel((item) => { return { 'content': item.edition_number }}, 'num_editions', 'Nr', TableItemText, 1, false),
|
new TableColumnContentModel((item) => { return { 'content': item.edition_number }}, 'num_editions', '#', TableItemText, 1, false),
|
||||||
new TableColumnContentModel((item) => { return { 'content': item.bitcoin_id }}, 'bitcoin_id', 'Bitcoin Address', TableItemText, 5, false),
|
new TableColumnContentModel((item) => { return { 'content': item.bitcoin_id }}, 'bitcoin_id', getLangText('Bitcoin Address'), TableItemText, 5, false),
|
||||||
new TableColumnContentModel((item) => { return { 'content': item.acl }}, 'acl', 'Actions', TableItemAclFiltered, 4, false)
|
new TableColumnContentModel((item) => { return { 'content': item.acl }}, 'acl', getLangText('Actions'), TableItemAclFiltered, 4, false)
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Router from 'react-router';
|
import Router from 'react-router';
|
||||||
|
|
||||||
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
let Link = Router.Link;
|
let Link = Router.Link;
|
||||||
|
|
||||||
let PaginationButton = React.createClass({
|
let PaginationButton = React.createClass({
|
||||||
@ -25,14 +27,14 @@ let PaginationButton = React.createClass({
|
|||||||
page -= 1;
|
page -= 1;
|
||||||
directionDisplay = (
|
directionDisplay = (
|
||||||
<span>
|
<span>
|
||||||
<span aria-hidden="true">←</span> Previous
|
<span aria-hidden="true">←</span> {getLangText('Previous')}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
page += 1;
|
page += 1;
|
||||||
directionDisplay = (
|
directionDisplay = (
|
||||||
<span>
|
<span>
|
||||||
Next <span aria-hidden="true">→</span>
|
{getLangText('Next')} <span aria-hidden="true">→</span>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import TableColumnMixin from '../../mixins/table_column_mixin';
|
import TableColumnMixin from '../../mixins/table_column_mixin';
|
||||||
import GeneralUtils from '../../utils/general_utils';
|
|
||||||
import TableHeaderItem from './table_header_item';
|
import TableHeaderItem from './table_header_item';
|
||||||
|
|
||||||
import TableColumnContentModel from '../../models/table_column_content_model';
|
import TableColumnContentModel from '../../models/table_column_content_model';
|
||||||
|
@ -5,6 +5,14 @@ import AltContainer from 'alt/AltContainer';
|
|||||||
import UserActions from '../actions/user_actions';
|
import UserActions from '../actions/user_actions';
|
||||||
import UserStore from '../stores/user_store';
|
import UserStore from '../stores/user_store';
|
||||||
|
|
||||||
|
import Nav from 'react-bootstrap/lib/Nav';
|
||||||
|
import Navbar from 'react-bootstrap/lib/Navbar';
|
||||||
|
import NavItem from 'react-bootstrap/lib/NavItem';
|
||||||
|
import DropdownButton from 'react-bootstrap/lib/DropdownButton';
|
||||||
|
import MenuItem from 'react-bootstrap/lib/MenuItem';
|
||||||
|
|
||||||
|
import { getLangText } from '../utils/lang_utils';
|
||||||
|
|
||||||
let Link = Router.Link;
|
let Link = Router.Link;
|
||||||
|
|
||||||
let Header = React.createClass({
|
let Header = React.createClass({
|
||||||
@ -24,40 +32,24 @@ let Header = React.createClass({
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<nav className="navbar navbar-default">
|
<Navbar>
|
||||||
<div className="container">
|
<Nav>
|
||||||
<div className="navbar-header">
|
|
||||||
<button type="button" className="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
|
|
||||||
<span className="sr-only">Toggle navigation</span>
|
|
||||||
<span className="icon-bar"></span>
|
|
||||||
<span className="icon-bar"></span>
|
|
||||||
<span className="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<a className="navbar-brand" href="#">
|
<a className="navbar-brand" href="#">
|
||||||
<span>ascribe </span>
|
<span>ascribe </span>
|
||||||
<span className="glyph-ascribe-spool-chunked ascribe-color"></span>
|
<span className="glyph-ascribe-spool-chunked ascribe-color"></span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</Nav>
|
||||||
|
<Nav right>
|
||||||
<div id="navbar" className="navbar-collapse collapse">
|
<DropdownButton eventKey={3} title={this.state.currentUser.username}>
|
||||||
<ul className="nav navbar-nav navbar-left">
|
<MenuItem eventKey="1" href="/art/account_settings/">{getLangText('Account Settings')}</MenuItem>
|
||||||
</ul>
|
|
||||||
<ul className="nav navbar-nav navbar-right">
|
|
||||||
<li className="dropdown">
|
|
||||||
<a href="#" className="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">{this.state.currentUser.username} <span className="caret"></span></a>
|
|
||||||
<ul className="dropdown-menu" role="menu">
|
|
||||||
<li><a href="/art/faq/">Account Settings</a></li>
|
|
||||||
<li className="divider"></li>
|
<li className="divider"></li>
|
||||||
<li><a href="/art/faq/">FAQ</a></li>
|
<MenuItem eventKey="2" href="/art/faq/">{getLangText('FAQ')}</MenuItem>
|
||||||
<li><a href="/art/terms/">Terms of Service</a></li>
|
<MenuItem eventKey="3" href="/art/terms/">{getLangText('Terms of Service')}</MenuItem>
|
||||||
<li className="divider"></li>
|
<MenuItem divider />
|
||||||
<li><a href="/api/users/logout/">Log out</a></li>
|
<MenuItem eventKey="4" href="/api/users/logout/">{getLangText('Log out')}</MenuItem>
|
||||||
</ul>
|
</DropdownButton>
|
||||||
</li>
|
</Nav>
|
||||||
</ul>
|
</Navbar>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
32
js/constants/languages.js
Normal file
32
js/constants/languages.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
const languages = {
|
||||||
|
'en-US': {
|
||||||
|
'Bitcoin Address': 'Bitcoin Address',
|
||||||
|
'Actions': 'Actions',
|
||||||
|
'Hide': 'Hide',
|
||||||
|
'Show the edition': 'Show the edition',
|
||||||
|
'Show all %d Editions': 'Show all %d Editions',
|
||||||
|
'by %s': 'by %s',
|
||||||
|
'Account Settings': 'Account Settings',
|
||||||
|
'FAQ': 'FAQ',
|
||||||
|
'Terms of Service': 'Terms of Service',
|
||||||
|
'Log out': 'Log out',
|
||||||
|
'Previous': 'Previous',
|
||||||
|
'Next': 'Next'
|
||||||
|
},
|
||||||
|
'de': {
|
||||||
|
'Bitcoin Address': 'Bitcoin Adresse',
|
||||||
|
'Actions': 'Aktionen',
|
||||||
|
'Hide': 'Verstecke',
|
||||||
|
'Show the edition': 'Zeige die Edition',
|
||||||
|
'Show all %d Editions': 'Zeige alle %d Editionen an',
|
||||||
|
'by %s': 'von %s',
|
||||||
|
'Account Settings': 'Kontoeinstellungen',
|
||||||
|
'FAQ': 'Fragen & Antworten',
|
||||||
|
'Terms of Service': 'AGB',
|
||||||
|
'Log out': 'Log out',
|
||||||
|
'Previous': 'Zurück',
|
||||||
|
'Next': 'Weiter'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default languages;
|
@ -1,7 +1,6 @@
|
|||||||
import fetch from '../utils/fetch';
|
import fetch from '../utils/fetch';
|
||||||
|
|
||||||
import AppConstants from '../constants/application_constants';
|
import AppConstants from '../constants/application_constants';
|
||||||
import FetchApiUtils from '../utils/fetch_api_utils';
|
|
||||||
|
|
||||||
|
|
||||||
let EditionFetcher = {
|
let EditionFetcher = {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import AppConstants from '../constants/application_constants';
|
import AppConstants from '../constants/application_constants';
|
||||||
import FetchApiUtils from '../utils/fetch_api_utils';
|
import { generateOrderingQueryParams } from '../utils/fetch_api_utils';
|
||||||
import fetch from '../utils/fetch';
|
import fetch from '../utils/fetch';
|
||||||
|
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ let PieceListFetcher = {
|
|||||||
* Can be called with all supplied queryparams the API.
|
* Can be called with all supplied queryparams the API.
|
||||||
*/
|
*/
|
||||||
fetch(page, pageSize, search, orderBy, orderAsc) {
|
fetch(page, pageSize, search, orderBy, orderAsc) {
|
||||||
let ordering = FetchApiUtils.generateOrderingQueryParams(orderBy, orderAsc);
|
let ordering = generateOrderingQueryParams(orderBy, orderAsc);
|
||||||
return fetch.get('pieces_list', { page, pageSize, search, ordering });
|
return fetch.get('pieces_list', { page, pageSize, search, ordering });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import fetch from '../utils/fetch';
|
import fetch from '../utils/fetch';
|
||||||
|
|
||||||
import AppConstants from '../constants/application_constants';
|
import AppConstants from '../constants/application_constants';
|
||||||
import FetchApiUtils from '../utils/fetch_api_utils';
|
|
||||||
|
|
||||||
|
|
||||||
let UserFetcher = {
|
let UserFetcher = {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import GeneralUtils from '../utils/general_utils';
|
import { sumNumList } from '../utils/general_utils';
|
||||||
|
|
||||||
let TableColumnMixin = {
|
let TableColumnMixin = {
|
||||||
/**
|
/**
|
||||||
@ -11,7 +11,7 @@ let TableColumnMixin = {
|
|||||||
let bootstrapClasses = ['col-xs-', 'col-sm-', 'col-md-', 'col-lg-'];
|
let bootstrapClasses = ['col-xs-', 'col-sm-', 'col-md-', 'col-lg-'];
|
||||||
|
|
||||||
let listOfRowValues = list.map((column) => column.rowWidth );
|
let listOfRowValues = list.map((column) => column.rowWidth );
|
||||||
let numOfUsedColumns = GeneralUtils.sumNumList(listOfRowValues);
|
let numOfUsedColumns = sumNumList(listOfRowValues);
|
||||||
|
|
||||||
if(numOfUsedColumns > numOfColumns) {
|
if(numOfUsedColumns > numOfColumns) {
|
||||||
throw new Error('This table has only ' + numOfColumns + ' columns to assign. You defined ' + numOfUsedColumns + '. Change this in the columnMap you\'re passing to the table.')
|
throw new Error('This table has only ' + numOfColumns + ' columns to assign. You defined ' + numOfUsedColumns + '. Change this in the columnMap you\'re passing to the table.')
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import alt from '../alt';
|
import alt from '../alt';
|
||||||
import EditionAction from '../actions/edition_actions';
|
import EditionActions from '../actions/edition_actions';
|
||||||
|
|
||||||
|
|
||||||
class EditionStore {
|
class EditionStore {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.edition = {};
|
this.edition = {};
|
||||||
this.bindActions(EditionAction);
|
this.bindActions(EditionActions);
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdateEdition(edition) {
|
onUpdateEdition(edition) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { default as _fetch } from 'isomorphic-fetch';
|
import { default as _fetch } from 'isomorphic-fetch';
|
||||||
import FetchApiUtils from '../utils/fetch_api_utils';
|
import { argsToQueryParams } from '../utils/fetch_api_utils';
|
||||||
|
|
||||||
|
|
||||||
class UrlMapError extends Error {};
|
class UrlMapError extends Error {};
|
||||||
@ -66,7 +66,7 @@ class Fetch {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (attachParamsToQuery && params && Object.keys(params).length > 0) {
|
if (attachParamsToQuery && params && Object.keys(params).length > 0) {
|
||||||
newUrl += FetchApiUtils.argsToQueryParams(params);
|
newUrl += argsToQueryParams(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newUrl;
|
return newUrl;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import GeneralUtils from './general_utils';
|
import { sanitize } from './general_utils';
|
||||||
|
|
||||||
|
|
||||||
// TODO: Create Unittests that test all functions
|
// TODO: Create Unittests that test all functions
|
||||||
let FetchApiUtils = {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a key-value object of this form:
|
* Takes a key-value object of this form:
|
||||||
@ -20,9 +18,9 @@ let FetchApiUtils = {
|
|||||||
* CamelCase gets converted to snake_case!
|
* CamelCase gets converted to snake_case!
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
argsToQueryParams(obj) {
|
export function argsToQueryParams(obj) {
|
||||||
|
|
||||||
obj = GeneralUtils.sanitize(obj);
|
obj = sanitize(obj);
|
||||||
|
|
||||||
return Object
|
return Object
|
||||||
.keys(obj)
|
.keys(obj)
|
||||||
@ -40,13 +38,13 @@ let FetchApiUtils = {
|
|||||||
return s + snakeCaseKey + '=' + encodeURIComponent(obj[key]);
|
return s + snakeCaseKey + '=' + encodeURIComponent(obj[key]);
|
||||||
})
|
})
|
||||||
.join('');
|
.join('');
|
||||||
},
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a string and a boolean and generates a string query parameter for
|
* Takes a string and a boolean and generates a string query parameter for
|
||||||
* an API call.
|
* an API call.
|
||||||
*/
|
*/
|
||||||
generateOrderingQueryParams(orderBy, orderAsc) {
|
export function generateOrderingQueryParams(orderBy, orderAsc) {
|
||||||
let interpolation = '';
|
let interpolation = '';
|
||||||
|
|
||||||
if(!orderAsc) {
|
if(!orderAsc) {
|
||||||
@ -54,14 +52,11 @@ let FetchApiUtils = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return interpolation + orderBy;
|
return interpolation + orderBy;
|
||||||
},
|
};
|
||||||
|
|
||||||
status(response) {
|
export function status(response) {
|
||||||
if (response.status >= 200 && response.status < 300) {
|
if (response.status >= 200 && response.status < 300) {
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
throw new Error(response.json())
|
throw new Error(response.json())
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FetchApiUtils;
|
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
// TODO: Create Unittests that test all functions
|
// TODO: Create Unittests that test all functions
|
||||||
|
|
||||||
let GeneralUtils = {
|
export function sanitize(obj) {
|
||||||
/**
|
|
||||||
* Removes undefined and null values from an key-value object.
|
|
||||||
*/
|
|
||||||
sanitize(obj) {
|
|
||||||
Object
|
Object
|
||||||
.keys(obj)
|
.keys(obj)
|
||||||
.map((key) => {
|
.map((key) => {
|
||||||
@ -16,26 +12,52 @@ let GeneralUtils = {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
},
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the values of an object.
|
* Returns the values of an object.
|
||||||
*/
|
*/
|
||||||
valuesOfObject(obj) {
|
export function valuesOfObject(obj) {
|
||||||
return Object
|
return Object
|
||||||
.keys(obj)
|
.keys(obj)
|
||||||
.map(key => obj[key]);
|
.map(key => obj[key]);
|
||||||
},
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sums up a list of numbers. Like a Epsilon-math-kinda-sum...
|
* Sums up a list of numbers. Like a Epsilon-math-kinda-sum...
|
||||||
*/
|
*/
|
||||||
sumNumList(l) {
|
export function sumNumList(l) {
|
||||||
let sum = 0;
|
let sum = 0;
|
||||||
l.forEach((num) => sum += parseFloat(num) || 0);
|
l.forEach((num) => sum += parseFloat(num) || 0);
|
||||||
return sum;
|
return sum;
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default GeneralUtils;
|
/*
|
||||||
|
Taken from http://stackoverflow.com/a/4795914/1263876
|
||||||
|
Behaves like C's format string function
|
||||||
|
*/
|
||||||
|
export function formatText() {
|
||||||
|
var args = arguments,
|
||||||
|
string = args[0],
|
||||||
|
i = 1;
|
||||||
|
return string.replace(/%((%)|s|d)/g, function (m) {
|
||||||
|
// m is the matched format, e.g. %s, %d
|
||||||
|
var val = null;
|
||||||
|
if (m[2]) {
|
||||||
|
val = m[2];
|
||||||
|
} else {
|
||||||
|
val = args[i];
|
||||||
|
// A switch statement so that the formatter can be extended. Default is %s
|
||||||
|
switch (m) {
|
||||||
|
case '%d':
|
||||||
|
val = parseFloat(val);
|
||||||
|
if (isNaN(val)) {
|
||||||
|
val = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
30
js/utils/lang_utils.js
Normal file
30
js/utils/lang_utils.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import languages from '../constants/languages';
|
||||||
|
|
||||||
|
import { formatText } from './general_utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is used to translate strings to another language. Basically can be used with C's string format method.
|
||||||
|
* @param {string} s The string you want to translate
|
||||||
|
* @param {array} args An array of arguments (essentially JavaScript's this.arguments) that can be used to substitute digits and other strings
|
||||||
|
* @return {string} The formated string
|
||||||
|
*/
|
||||||
|
export function getLangText(s, ...args) {
|
||||||
|
let lang = navigator.language || navigator.userLanguage;
|
||||||
|
// this is just for testing, as changing the navigator.language wasn't possible
|
||||||
|
lang = 'de';
|
||||||
|
try {
|
||||||
|
if(lang in languages) {
|
||||||
|
return formatText(languages[lang][s], args);
|
||||||
|
} else {
|
||||||
|
// just use the english language
|
||||||
|
return formatText(languages['en-US'][s], args);
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
if(!(s in languages[lang])) {
|
||||||
|
console.error(new Error('Language-string is not in constants file. Add: "' + s + '" to the "' + lang + '" language file.'));
|
||||||
|
} else {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user