mirror of
https://github.com/chinchang/web-maker.git
synced 2025-07-16 03:26:19 +02:00
Add language picker in settings and translate some header strings. fixes #170
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"compileNamespace": "es6",
|
"compileNamespace": "es",
|
||||||
"localeDir": "src/locales/",
|
"localeDir": "src/locales/",
|
||||||
"srcPathDirs": ["src/components"],
|
"srcPathDirs": ["src/components"],
|
||||||
"format": "po",
|
"format": "po",
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import { h, Component } from 'preact';
|
import { h, Component } from 'preact';
|
||||||
import { PureComponent } from 'preact-compat';
|
|
||||||
|
|
||||||
import { Inspector, chromeDark } from 'react-inspector';
|
import { Inspector, chromeDark } from 'react-inspector';
|
||||||
|
|
||||||
import { Trans } from '@lingui/macro';
|
import { Trans } from '@lingui/macro';
|
||||||
|
|
||||||
class LogRow extends Component {
|
class LogRow extends Component {
|
||||||
@ -56,7 +53,7 @@ export class Console extends Component {
|
|||||||
onDblClick={onConsoleHeaderDblClick}
|
onDblClick={onConsoleHeaderDblClick}
|
||||||
>
|
>
|
||||||
<span class="code-wrap__header-label">
|
<span class="code-wrap__header-label">
|
||||||
Console (<span>{logs.length}</span>)
|
<Trans>Console</Trans> (<span>{logs.length}</span>)
|
||||||
</span>
|
</span>
|
||||||
<div class="code-wrap__header-right-options">
|
<div class="code-wrap__header-right-options">
|
||||||
<a
|
<a
|
||||||
|
@ -1,125 +1,137 @@
|
|||||||
import { h } from 'preact';
|
import { h } from 'preact';
|
||||||
import { Button } from './common';
|
import { Button } from './common';
|
||||||
|
import { Trans, t } from '@lingui/macro';
|
||||||
|
import { I18n } from '@lingui/react';
|
||||||
|
|
||||||
const DEFAULT_PROFILE_IMG =
|
const DEFAULT_PROFILE_IMG =
|
||||||
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='#ccc' d='M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z' /%3E%3C/svg%3E";
|
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='#ccc' d='M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z' /%3E%3C/svg%3E";
|
||||||
|
|
||||||
export function MainHeader(props) {
|
export function MainHeader(props) {
|
||||||
return (
|
return (
|
||||||
<div class="main-header">
|
<I18n>
|
||||||
<input
|
{({ i18n }) => (
|
||||||
type="text"
|
<div class="main-header">
|
||||||
id="titleInput"
|
<input
|
||||||
title="Click to edit"
|
type="text"
|
||||||
class="item-title-input"
|
id="titleInput"
|
||||||
value={props.title}
|
title="Click to edit"
|
||||||
onBlur={props.titleInputBlurHandler}
|
class="item-title-input"
|
||||||
/>
|
value={props.title}
|
||||||
<div class="main-header__btn-wrap flex flex-v-center">
|
onBlur={props.titleInputBlurHandler}
|
||||||
<button
|
|
||||||
id="runBtn"
|
|
||||||
class="hide btn--dark flex flex-v-center hint--rounded hint--bottom-left"
|
|
||||||
aria-label="Run preview (Ctrl/⌘ + Shift + 5)"
|
|
||||||
onClick={props.runBtnClickHandler}
|
|
||||||
>
|
|
||||||
<svg style="width: 14px; height: 14px;">
|
|
||||||
<use xlinkHref="#play-icon" />
|
|
||||||
</svg>Run
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{!this.props.isFileMode && (
|
|
||||||
<Button
|
|
||||||
onClick={props.addLibraryBtnHandler}
|
|
||||||
data-event-category="ui"
|
|
||||||
data-event-action="addLibraryButtonClick"
|
|
||||||
class="btn--dark flex-v-center hint--rounded hint--bottom-left"
|
|
||||||
aria-label="Add a JS/CSS library"
|
|
||||||
>
|
|
||||||
Add library{' '}
|
|
||||||
<span
|
|
||||||
id="js-external-lib-count"
|
|
||||||
style={`display:${props.externalLibCount ? 'inline' : 'none'}`}
|
|
||||||
class="count-label"
|
|
||||||
>
|
|
||||||
{props.externalLibCount}
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<button
|
|
||||||
class="btn--dark flex flex-v-center hint--rounded hint--bottom-left"
|
|
||||||
aria-label="Start a new creation"
|
|
||||||
onClick={props.newBtnHandler}
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
style="vertical-align:middle;width:14px;height:14px"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path d="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" />
|
|
||||||
</svg>New
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
id="saveBtn"
|
|
||||||
class={`btn--dark flex flex-v-center hint--rounded hint--bottom-left ${
|
|
||||||
props.isSaving ? 'is-loading' : ''
|
|
||||||
} ${props.unsavedEditCount ? 'is-marked' : 0}`}
|
|
||||||
aria-label="Save current creation (Ctrl/⌘ + S)"
|
|
||||||
onClick={props.saveBtnHandler}
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
style="vertical-align:middle;width:14px;height:14px"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path d="M15,9H5V5H15M12,19A3,3 0 0,1 9,16A3,3 0 0,1 12,13A3,3 0 0,1 15,16A3,3 0 0,1 12,19M17,3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V7L17,3Z" />
|
|
||||||
</svg>
|
|
||||||
<svg class="btn-loader" width="15" height="15" stroke="#fff">
|
|
||||||
<use xlinkHref="#loader-icon" />
|
|
||||||
</svg>
|
|
||||||
Save
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
id="openItemsBtn"
|
|
||||||
class={`btn--dark flex flex-v-center hint--rounded hint--bottom-left ${
|
|
||||||
props.isFetchingItems ? 'is-loading' : ''
|
|
||||||
}`}
|
|
||||||
aria-label="Open a saved creation (Ctrl/⌘ + O)"
|
|
||||||
onClick={props.openBtnHandler}
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
style="width:14px;height:14px;vertical-align:middle;"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path d="M13,9V3.5L18.5,9M6,2C4.89,2 4,2.89 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2H6Z" />
|
|
||||||
</svg>
|
|
||||||
<svg class="btn-loader" width="15" height="15" stroke="#fff">
|
|
||||||
<use xlinkHref="#loader-icon" />
|
|
||||||
</svg>
|
|
||||||
Open
|
|
||||||
</button>
|
|
||||||
<Button
|
|
||||||
onClick={props.loginBtnHandler}
|
|
||||||
data-event-category="ui"
|
|
||||||
data-event-action="loginButtonClick"
|
|
||||||
class="hide-on-login btn--dark flex flex-v-center hint--rounded hint--bottom-left"
|
|
||||||
aria-label="Login/Signup"
|
|
||||||
>
|
|
||||||
Login/Signup
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
onClick={props.profileBtnHandler}
|
|
||||||
data-event-category="ui"
|
|
||||||
data-event-action="headerAvatarClick"
|
|
||||||
aria-label="See profile or Logout"
|
|
||||||
class="hide-on-logout btn--dark hint--rounded hint--bottom-left"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
id="headerAvatarImg"
|
|
||||||
width="20"
|
|
||||||
src={props.user ? props.user.photoURL || DEFAULT_PROFILE_IMG : ''}
|
|
||||||
class="main-header__avatar-img"
|
|
||||||
/>
|
/>
|
||||||
</Button>
|
<div class="main-header__btn-wrap flex flex-v-center">
|
||||||
</div>
|
<button
|
||||||
</div>
|
id="runBtn"
|
||||||
|
class="hide btn--dark flex flex-v-center hint--rounded hint--bottom-left"
|
||||||
|
aria-label="Run preview (Ctrl/⌘ + Shift + 5)"
|
||||||
|
onClick={props.runBtnClickHandler}
|
||||||
|
>
|
||||||
|
<svg style="width: 14px; height: 14px;">
|
||||||
|
<use xlinkHref="#play-icon" />
|
||||||
|
</svg>
|
||||||
|
<Trans>Run</Trans>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{!this.props.isFileMode && (
|
||||||
|
<Button
|
||||||
|
onClick={props.addLibraryBtnHandler}
|
||||||
|
data-event-category="ui"
|
||||||
|
data-event-action="addLibraryButtonClick"
|
||||||
|
class="btn--dark flex-v-center hint--rounded hint--bottom-left"
|
||||||
|
aria-label={i18n._(t`Add a JS/CSS library`)}
|
||||||
|
>
|
||||||
|
<Trans>Add library</Trans>{' '}
|
||||||
|
<span
|
||||||
|
id="js-external-lib-count"
|
||||||
|
style={`display:${
|
||||||
|
props.externalLibCount ? 'inline' : 'none'
|
||||||
|
}`}
|
||||||
|
class="count-label"
|
||||||
|
>
|
||||||
|
{props.externalLibCount}
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="btn--dark flex flex-v-center hint--rounded hint--bottom-left"
|
||||||
|
aria-label="Start a new creation"
|
||||||
|
onClick={props.newBtnHandler}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
style="vertical-align:middle;width:14px;height:14px"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path d="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" />
|
||||||
|
</svg>
|
||||||
|
<Trans>New</Trans>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
id="saveBtn"
|
||||||
|
class={`btn--dark flex flex-v-center hint--rounded hint--bottom-left ${
|
||||||
|
props.isSaving ? 'is-loading' : ''
|
||||||
|
} ${props.unsavedEditCount ? 'is-marked' : 0}`}
|
||||||
|
aria-label="Save current creation (Ctrl/⌘ + S)"
|
||||||
|
onClick={props.saveBtnHandler}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
style="vertical-align:middle;width:14px;height:14px"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path d="M15,9H5V5H15M12,19A3,3 0 0,1 9,16A3,3 0 0,1 12,13A3,3 0 0,1 15,16A3,3 0 0,1 12,19M17,3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V7L17,3Z" />
|
||||||
|
</svg>
|
||||||
|
<svg class="btn-loader" width="15" height="15" stroke="#fff">
|
||||||
|
<use xlinkHref="#loader-icon" />
|
||||||
|
</svg>
|
||||||
|
<Trans>Save</Trans>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
id="openItemsBtn"
|
||||||
|
class={`btn--dark flex flex-v-center hint--rounded hint--bottom-left ${
|
||||||
|
props.isFetchingItems ? 'is-loading' : ''
|
||||||
|
}`}
|
||||||
|
aria-label="Open a saved creation (Ctrl/⌘ + O)"
|
||||||
|
onClick={props.openBtnHandler}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
style="width:14px;height:14px;vertical-align:middle;"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path d="M13,9V3.5L18.5,9M6,2C4.89,2 4,2.89 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2H6Z" />
|
||||||
|
</svg>
|
||||||
|
<svg class="btn-loader" width="15" height="15" stroke="#fff">
|
||||||
|
<use xlinkHref="#loader-icon" />
|
||||||
|
</svg>
|
||||||
|
<Trans>Open</Trans>
|
||||||
|
</button>
|
||||||
|
<Button
|
||||||
|
onClick={props.loginBtnHandler}
|
||||||
|
data-event-category="ui"
|
||||||
|
data-event-action="loginButtonClick"
|
||||||
|
class="hide-on-login btn--dark flex flex-v-center hint--rounded hint--bottom-left"
|
||||||
|
aria-label="Login/Signup"
|
||||||
|
>
|
||||||
|
<Trans>Login</Trans>/<Trans>Signup</Trans>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={props.profileBtnHandler}
|
||||||
|
data-event-category="ui"
|
||||||
|
data-event-action="headerAvatarClick"
|
||||||
|
aria-label="See profile or Logout"
|
||||||
|
class="hide-on-logout btn--dark hint--rounded hint--bottom-left"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
id="headerAvatarImg"
|
||||||
|
width="20"
|
||||||
|
src={
|
||||||
|
props.user ? props.user.photoURL || DEFAULT_PROFILE_IMG : ''
|
||||||
|
}
|
||||||
|
class="main-header__avatar-img"
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</I18n>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -320,6 +320,22 @@ export default class Settings extends Component {
|
|||||||
stopped.
|
stopped.
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<label class="line">
|
||||||
|
Language
|
||||||
|
<select
|
||||||
|
data-setting="lang"
|
||||||
|
value={prefs.lang}
|
||||||
|
onChange={this.updateSetting.bind(this)}
|
||||||
|
>
|
||||||
|
<option value="en">English</option>
|
||||||
|
<option value="hi">Hindi</option>
|
||||||
|
<option value="ja">Japanese</option>
|
||||||
|
<option value="sa">Sanskrit</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -64,13 +64,13 @@ import {
|
|||||||
SHOW_KEYBOARD_SHORTCUTS_EVENT
|
SHOW_KEYBOARD_SHORTCUTS_EVENT
|
||||||
} from '../commands';
|
} from '../commands';
|
||||||
import { commandPaletteService } from '../commandPaletteService';
|
import { commandPaletteService } from '../commandPaletteService';
|
||||||
// import hiTranslations from '../locales/hi/messages';
|
|
||||||
import { I18nProvider } from '@lingui/react';
|
import { I18nProvider } from '@lingui/react';
|
||||||
const hiTranslations = {};
|
|
||||||
if (module.hot) {
|
if (module.hot) {
|
||||||
require('preact/debug');
|
require('preact/debug');
|
||||||
}
|
}
|
||||||
const catalogs = { hi: hiTranslations };
|
|
||||||
const LocalStorageKeys = {
|
const LocalStorageKeys = {
|
||||||
LOGIN_AND_SAVE_MESSAGE_SEEN: 'loginAndsaveMessageSeen',
|
LOGIN_AND_SAVE_MESSAGE_SEEN: 'loginAndsaveMessageSeen',
|
||||||
ASKED_TO_IMPORT_CREATIONS: 'askedToImportCreations'
|
ASKED_TO_IMPORT_CREATIONS: 'askedToImportCreations'
|
||||||
@ -130,7 +130,8 @@ export default class App extends Component {
|
|||||||
lineWrap: true,
|
lineWrap: true,
|
||||||
infiniteLoopTimeout: 1000,
|
infiniteLoopTimeout: 1000,
|
||||||
layoutMode: 2,
|
layoutMode: 2,
|
||||||
isJs13kModeOn: false
|
isJs13kModeOn: false,
|
||||||
|
lang: 'en'
|
||||||
};
|
};
|
||||||
this.prefs = {};
|
this.prefs = {};
|
||||||
|
|
||||||
@ -253,6 +254,22 @@ export default class App extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getLanguageDefinition() {
|
||||||
|
console.log('🇯🇲 fetching defninition');
|
||||||
|
const { lang } = this.state.prefs;
|
||||||
|
if (!lang || lang === 'en') {
|
||||||
|
return {};
|
||||||
|
} else if (lang === 'hi') {
|
||||||
|
const def = require('../locales/hi/messages');
|
||||||
|
|
||||||
|
return { hi: def.default };
|
||||||
|
} else if (lang === 'ja') {
|
||||||
|
const def = require('../locales/ja/messages');
|
||||||
|
|
||||||
|
return { ja: def.default };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
incrementUnsavedChanges() {
|
incrementUnsavedChanges() {
|
||||||
this.setState({ unsavedEditCount: this.state.unsavedEditCount + 1 });
|
this.setState({ unsavedEditCount: this.state.unsavedEditCount + 1 });
|
||||||
|
|
||||||
@ -1398,7 +1415,10 @@ export default class App extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<I18nProvider language="hi" catalogs={catalogs}>
|
<I18nProvider
|
||||||
|
language={this.state.prefs.lang}
|
||||||
|
catalogs={this.getLanguageDefinition()}
|
||||||
|
>
|
||||||
<div class={this.getRootClasses()}>
|
<div class={this.getRootClasses()}>
|
||||||
<div class="main-container">
|
<div class="main-container">
|
||||||
<MainHeader
|
<MainHeader
|
||||||
|
Reference in New Issue
Block a user