add i18n translation and use them in the app

pull/691/head
Audric Ackermann 5 years ago
parent 2f8820a27b
commit 291e3b48a0

@ -2289,5 +2289,75 @@
"example": "" "example": ""
} }
} }
},
"beginYourSession": {
"message": "Begin<br/>your<br/>Session."
},
"ensuringPeaceOfMind": {
"message":
"Ensuring <span class='redacted'>peace of</span> mind, one <span class='redacted'>session</span> at a time."
},
"createAccount": {
"message": "Create Account"
},
"signIn": {
"message": "Sign In"
},
"yourUniqueSessionID": {
"message": "Your Unique Session ID"
},
"allUsersAreRandomly...": {
"message":
"All users are randomly generated a set of numbers that act as their unique Session ID. Share your Session ID in order to chat with your friends!"
},
"getStarted": {
"message": "Get started"
},
"generateSessionID": {
"message": "Generate Session ID"
},
"mnemonicSeed": {
"message": "Mnemonic Seed"
},
"enterSeed": {
"message": "Enter Seed"
},
"displayName": {
"message": "Display Name"
},
"enterOptionalDisplayName": {
"message": "Enter Optional Display Name"
},
"optionalPassword": {
"message": "Optional Password"
},
"enterOptionalPassword": {
"message": "Enter Optional Password"
},
"verifyPassword": {
"message": "Verify Password"
},
"devicePairingHeader": {
"message":
"Open the Loki Messenger App on your primary device and select Device Pairing from the main menu. Then, enter your Session ID below to sign in."
},
"enterSessionIDHere": {
"message": "Enter your Session ID here"
},
"continueYourSession": {
"message": "Continue Your Session"
},
"restoreUsingSeed": {
"message": "Restore Using Seed"
},
"linkDeviceToExistingAccount": {
"message": "Link Device To Existing Account"
},
"byUsingThisService...": {
"message":
"By using this service, you agree to our <a>Terms and Conditions</a> and <a>Privacy Statement</a>"
},
"or": {
"message": "or"
} }
} }

@ -440,41 +440,4 @@ $session_message-container-border-radius: 5px;
} }
} }
} }
&-icon-button {
fill: $session-color-white;
opacity: 0.4;
cursor: pointer;
display: inline-block;
transition: opacity $session-transition-duration;
@mixin adjust-icon-size($size) {
line-height: $size;
height: $size;
width: $size;
margin: $size / 3;
img {
height: $size;
width: $size;
}
}
&.small {
@include adjust-icon-size($session-icon-size-sm);
}
&.medium {
@include adjust-icon-size($session-icon-size-md);
}
&.large {
@include adjust-icon-size($session-icon-size-lg);
}
&:hover {
opacity: 1;
}
}
} }

@ -10,25 +10,25 @@
height: 100%; height: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
&-accent { &-accent {
flex-grow: 1; flex-grow: 1;
padding-left: 20px; padding-left: 20px;
&-text { &-text {
color: $session-color-white; color: $session-color-white;
font-family: $session-font-family; font-family: $session-font-family;
.title { .title {
font-size: 100px; font-size: 100px;
font-weight: 700; font-weight: 700;
line-height: 120px; line-height: 120px;
} }
.subtitle { .subtitle {
font-size: 18px; font-size: 18px;
font-weight: 700; font-weight: 700;
.redacted { .redacted {
background: $session-color-white; background: $session-color-white;
white-space: nowrap; white-space: nowrap;
@ -36,7 +36,7 @@
border-radius: 100px; border-radius: 100px;
padding-left: 7px; padding-left: 7px;
padding-right: 7px; padding-right: 7px;
&:hover { &:hover {
background-color: $session-color-black; background-color: $session-color-black;
} }
@ -44,35 +44,32 @@
} }
} }
} }
&-registration { &-registration {
height: 60%; height: 60%;
padding-right: 128px; padding-right: 128px;
} }
} }
&-registration { &-registration {
&-container{ &-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 289px; width: 289px;
} }
&__content { &__content {
width: 100%; width: 100%;
overflow-y: auto; overflow-y: auto;
padding-top: 20px; padding-top: 20px;
} }
&__sections { &__sections {
display: flex; display: flex;
flex-grow: 1; flex-grow: 1;
flex-direction: column; flex-direction: column;
} }
&__tab-container { &__tab-container {
display: flex; display: flex;
flex-grow: 0; flex-grow: 0;
@ -82,12 +79,12 @@
height: 30px; height: 30px;
left: 0; left: 0;
right: 0; right: 0;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
color: $session-color-white; color: $session-color-white;
} }
&__tab { &__tab {
@include fontWasaBold(); @include fontWasaBold();
width: 100%; width: 100%;
@ -99,12 +96,12 @@
transition: border-color $session-transition-duration linear; transition: border-color $session-transition-duration linear;
line-height: 17px; line-height: 17px;
font-size: 15px; font-size: 15px;
&--active { &--active {
border-bottom: 4px solid $session-color-green; border-bottom: 4px solid $session-color-green;
} }
} }
@mixin registration-label-mixin { @mixin registration-label-mixin {
color: $session-color-white; color: $session-color-white;
text-align: center; text-align: center;
@ -113,16 +110,16 @@
line-height: 17px; line-height: 17px;
padding: 12px; padding: 12px;
} }
&__or { &__or {
@include registration-label-mixin; @include registration-label-mixin;
} }
&__unique-session-id { &__unique-session-id {
@include registration-label-mixin; @include registration-label-mixin;
padding-top: 3em; padding-top: 3em;
} }
&__entry-fields { &__entry-fields {
margin: 0px; margin: 0px;
padding-bottom: 30px; padding-bottom: 30px;
@ -137,7 +134,7 @@
transition: opacity $session-transition-duration; transition: opacity $session-transition-duration;
opacity: 1; opacity: 1;
position: relative; position: relative;
label { label {
line-height: 14px; line-height: 14px;
opacity: 0; opacity: 0;
@ -147,11 +144,11 @@
position: absolute; position: absolute;
top: 0px; top: 0px;
} }
&.filled { &.filled {
opacity: 1; opacity: 1;
} }
input { input {
border: none; border: none;
outline: 0; outline: 0;
@ -165,14 +162,14 @@
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
} }
hr { hr {
border: 1px solid $session-color-white; border: 1px solid $session-color-white;
width: 100%; width: 100%;
position: absolute; position: absolute;
bottom: 0px; bottom: 0px;
} }
button { button {
position: absolute; position: absolute;
top: 50%; top: 50%;
@ -186,23 +183,23 @@
color: $session-color-light-grey; color: $session-color-light-grey;
text-align: center; text-align: center;
font-size: 12px; font-size: 12px;
a { a {
white-space: nowrap; white-space: nowrap;
font-weight: bold; font-weight: bold;
color: $session-color-light-grey; color: $session-color-light-grey;
transition: $session-transition-duration; transition: $session-transition-duration;
&:visited &:link { &:visited &:link {
color: $session-color-light-grey; color: $session-color-light-grey;
} }
&:hover { &:hover {
color: $session-color-white; color: $session-color-white;
} }
} }
} }
&-signup-header, &-signup-header,
&-signin-device-pairing-header { &-signin-device-pairing-header {
padding-top: 10px; padding-top: 10px;
@ -212,7 +209,7 @@
font-size: 12px; font-size: 12px;
line-height: 20px; line-height: 20px;
} }
&-signin-enter-session-id { &-signin-enter-session-id {
height: auto; height: auto;
width: 289px; width: 289px;
@ -228,8 +225,6 @@
overflow-wrap: break-word; overflow-wrap: break-word;
padding: 20px 5px 20px 5px; padding: 20px 5px 20px 5px;
display: inline-block; display: inline-block;
} }
} }

@ -1,11 +1,9 @@
import React from 'react'; import React from 'react';
import classNames from 'classnames';
//import { LocalizerType } from '../../types/Util'; import { LocalizerType } from '../../types/Util';
interface Props { interface Props {
//i18n: LocalizerType; i18n: LocalizerType;
// text: string;
showSubtitle?: boolean; showSubtitle?: boolean;
} }
@ -15,19 +13,23 @@ export class AccentText extends React.PureComponent<Props> {
} }
public render() { public render() {
const { showSubtitle } = this.props; const { showSubtitle, i18n } = this.props;
const title = i18n('beginYourSession');
const subtitle = i18n('ensuringPeaceOfMind');
return ( return (
<div className="session-content-accent-text"> <div className="session-content-accent-text">
<div className="session-content-accent-text title"> <div
Begin<br />your<br />Session. className="session-content-accent-text title"
</div> dangerouslySetInnerHTML={{ __html: title }}
/>
{showSubtitle ? ( {showSubtitle ? (
<div className="session-content-accent-text subtitle"> <div
Ensuring <span className={classNames('redacted')}>peace of</span>{' '} className="session-content-accent-text subtitle"
mind, one <span className={classNames('redacted')}>session</span> at dangerouslySetInnerHTML={{ __html: subtitle }}
a time. />
</div>
) : ( ) : (
'' ''
)} )}

@ -91,18 +91,22 @@ export class RegistrationTabs extends React.Component<Props, State> {
private renderTabs() { private renderTabs() {
const { selectedTab } = this.state; const { selectedTab } = this.state;
const { i18n } = this.props;
const createAccount = i18n('createAccount');
const signIn = i18n('signIn');
return ( return (
<div className="session-registration-container"> <div className="session-registration-container">
<div className="session-registration__tab-container"> <div className="session-registration__tab-container">
<Tab <Tab
label="Create Account" label={createAccount}
type="create" type="create"
isSelected={selectedTab === 'create'} isSelected={selectedTab === 'create'}
onSelect={this.handleTabSelect} onSelect={this.handleTabSelect}
/> />
<Tab <Tab
label="Sign In" label={signIn}
type="signin" type="signin"
isSelected={selectedTab === 'signin'} isSelected={selectedTab === 'signin'}
onSelect={this.handleTabSelect} onSelect={this.handleTabSelect}
@ -143,7 +147,8 @@ export class RegistrationTabs extends React.Component<Props, State> {
} }
private renderSignUp() { private renderSignUp() {
const {signUpMode} = this.state; const { signUpMode } = this.state;
const { i18n } = this.props;
if (signUpMode === SignUpMode.Default) { if (signUpMode === SignUpMode.Default) {
return ( return (
<div className="session-registration__content"> <div className="session-registration__content">
@ -151,13 +156,12 @@ export class RegistrationTabs extends React.Component<Props, State> {
{this.renderSignUpButton()} {this.renderSignUpButton()}
</div> </div>
); );
} } else {
else {
return ( return (
<div className="session-registration__content"> <div className="session-registration__content">
{this.renderSignUpHeader()} {this.renderSignUpHeader()}
<div className="session-registration__unique-session-id"> <div className="session-registration__unique-session-id">
Your Unique Session ID {i18n('yourUniqueSessionID')}
</div> </div>
{this.renderEnterSessionID(false)} {this.renderEnterSessionID(false)}
{this.renderSignUpButton()} {this.renderSignUpButton()}
@ -165,7 +169,6 @@ export class RegistrationTabs extends React.Component<Props, State> {
</div> </div>
); );
} }
} }
private getRenderTermsConditionAgreement() { private getRenderTermsConditionAgreement() {
@ -186,26 +189,23 @@ export class RegistrationTabs extends React.Component<Props, State> {
} }
private renderSignUpHeader() { private renderSignUpHeader() {
return ( const allUsersAreRandomly = this.props.i18n('allUsersAreRandomly...');
<div className="session-signup-header">
All users are randomly generated a set of numbers that act as their return <div className="session-signup-header">{allUsersAreRandomly}</div>;
unique Session ID. Share your Session ID in order to chat with your
friends!
</div>
);
} }
private renderSignUpButton() { private renderSignUpButton() {
const { signUpMode } = this.state; const { signUpMode } = this.state;
const { i18n } = this.props;
let buttonType: any; let buttonType: any;
let buttonText: string; let buttonText: string;
if (signUpMode !== SignUpMode.Default) { if (signUpMode !== SignUpMode.Default) {
buttonType = SessionButtonTypes.FullGreen; buttonType = SessionButtonTypes.FullGreen;
buttonText = 'Get started'; buttonText = i18n('getStarted');
} else { } else {
buttonType = SessionButtonTypes.Green; buttonType = SessionButtonTypes.Green;
buttonText = 'Generate Session ID'; buttonText = i18n('generateSessionID');
} }
return ( return (
@ -234,15 +234,15 @@ export class RegistrationTabs extends React.Component<Props, State> {
private renderRegistrationContent() { private renderRegistrationContent() {
const { signInMode } = this.state; const { signInMode } = this.state;
const { i18n } = this.props;
if (signInMode === SignInMode.UsingSeed) { if (signInMode === SignInMode.UsingSeed) {
return ( return (
<div className={classNames('session-registration__entry-fields')}> <div className={classNames('session-registration__entry-fields')}>
<SessionInput <SessionInput
label="Mnemonic Seed" label={i18n('mnemonicSeed')}
type="password" type="password"
placeholder="Enter Seed" placeholder={i18n('enterSeed')}
i18n={this.props.i18n}
value={this.state.seed} value={this.state.seed}
enableShowHide={true} enableShowHide={true}
onValueChanged={(val: string) => { onValueChanged={(val: string) => {
@ -250,29 +250,26 @@ export class RegistrationTabs extends React.Component<Props, State> {
}} }}
/> />
<SessionInput <SessionInput
label="Display Name" label={i18n('displayName')}
type="text" type="text"
placeholder="Enter Optional Display Name" placeholder={i18n('enterOptionalDisplayName')}
i18n={this.props.i18n}
value={this.state.displayName} value={this.state.displayName}
onValueChanged={(val: string) => { onValueChanged={(val: string) => {
this.onDisplayNameChanged(val); this.onDisplayNameChanged(val);
}} }}
/> />
<SessionInput <SessionInput
label="Optional Password" label={i18n('optionalPassword')}
type="password" type="password"
placeholder="Enter Optional Password" placeholder={i18n('enterOptionalPassword')}
i18n={this.props.i18n}
onValueChanged={(val: string) => { onValueChanged={(val: string) => {
this.onPasswordChanged(val); this.onPasswordChanged(val);
}} }}
/> />
<SessionInput <SessionInput
label="Verify Password" label={i18n('verifyPassword')}
type="password" type="password"
placeholder="Optional Password" placeholder={i18n('optionalPassword')}
i18n={this.props.i18n}
onValueChanged={(val: string) => { onValueChanged={(val: string) => {
this.onPasswordVerifyChanged(val); this.onPasswordVerifyChanged(val);
}} }}
@ -283,9 +280,7 @@ export class RegistrationTabs extends React.Component<Props, State> {
return ( return (
<div className=""> <div className="">
<div className="session-signin-device-pairing-header"> <div className="session-signin-device-pairing-header">
Open the Loki Messenger App on your primary device and select {i18n('devicePairingHeader')}
"Device Pairing" from the main menu. Then, enter your Session ID
below to sign in.
</div> </div>
{this.renderEnterSessionID(true)} {this.renderEnterSessionID(true)}
</div> </div>
@ -296,32 +291,37 @@ export class RegistrationTabs extends React.Component<Props, State> {
} }
private renderEnterSessionID(contentEditable: boolean) { private renderEnterSessionID(contentEditable: boolean) {
const { i18n } = this.props;
const enterSessionIDHere = i18n('enterSessionIDHere');
return ( return (
<div <div
className="session-signin-enter-session-id" className="session-signin-enter-session-id"
contentEditable={contentEditable} contentEditable={contentEditable}
placeholder="Enter your Session ID here" placeholder={enterSessionIDHere}
/> />
); );
} }
private renderSignInButtons() { private renderSignInButtons() {
const { signInMode } = this.state; const { signInMode } = this.state;
const { i18n } = this.props;
const or = i18n('or');
let greenButtonType: any; let greenButtonType: any;
let greenText: string; let greenText: string;
let whiteButtonText: string; let whiteButtonText: string;
if (signInMode !== SignInMode.Default) { if (signInMode !== SignInMode.Default) {
greenButtonType = SessionButtonTypes.FullGreen; greenButtonType = SessionButtonTypes.FullGreen;
greenText = 'Continue Your Session'; greenText = i18n('continueYourSession');
} else { } else {
greenButtonType = SessionButtonTypes.Green; greenButtonType = SessionButtonTypes.Green;
greenText = 'Restore Using Seed'; greenText = i18n('restoreUsingSeed');
} }
if (signInMode === SignInMode.LinkingDevice) { if (signInMode === SignInMode.LinkingDevice) {
whiteButtonText = 'Restore Using Seed'; whiteButtonText = i18n('restoreUsingSeed');
} else { } else {
whiteButtonText = 'Link Device To Existing Account'; whiteButtonText = i18n('linkDeviceToExistingAccount');
} }
return ( return (
@ -335,7 +335,7 @@ export class RegistrationTabs extends React.Component<Props, State> {
buttonType={greenButtonType} buttonType={greenButtonType}
text={greenText} text={greenText}
/> />
<div className="session-registration__or">or</div> <div className="session-registration__or">{or}</div>
<SessionButton <SessionButton
onClick={() => { onClick={() => {
this.setState({ this.setState({
@ -350,12 +350,15 @@ export class RegistrationTabs extends React.Component<Props, State> {
} }
private renderTermsConditionAgreement() { private renderTermsConditionAgreement() {
// FIXME link to our Terms and Conditions and privacy statement
const { i18n } = this.props;
const byUsingThisService = i18n('byUsingThisService...');
return ( return (
<div className="session-terms-conditions-agreement"> <div
By using this service, you agree to our <a>Terms and Conditions</a> and{' '} className="session-terms-conditions-agreement"
<a>Privacy Statement</a> dangerouslySetInnerHTML={{ __html: byUsingThisService }}
</div> />
); );
// FIXME link to our Terms and Conditions and privacy statement
} }
} }

@ -1,8 +1,6 @@
import React from 'react'; import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
//import { LocalizerType } from '../../types/Util';
export enum SessionButtonType { export enum SessionButtonType {
Brand = 'brand', Brand = 'brand',
BrandOutline = 'brand-outline', BrandOutline = 'brand-outline',
@ -23,7 +21,6 @@ export enum SessionButtonColor {
} }
interface Props { interface Props {
//i18n: LocalizerType;
text: string; text: string;
buttonType: SessionButtonType; buttonType: SessionButtonType;
buttonColor: SessionButtonColor; buttonColor: SessionButtonColor;

@ -1,10 +1,8 @@
import React from 'react'; import React from 'react';
import { LocalizerType } from '../../types/Util';
import classNames from 'classnames'; import classNames from 'classnames';
interface Props { interface Props {
i18n: LocalizerType;
label: string; label: string;
type: string; type: string;
value?: string; value?: string;

@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import { AccentText } from './AccentText'; import { AccentText } from './AccentText';
//import classNames from 'classnames';
import { LocalizerType } from '../../types/Util'; import { LocalizerType } from '../../types/Util';
import { RegistrationTabs } from './RegistrationTabs'; import { RegistrationTabs } from './RegistrationTabs';
@ -14,36 +13,20 @@ declare global {
interface Props { interface Props {
showSubtitle: boolean; showSubtitle: boolean;
i18n: LocalizerType; i18n: LocalizerType;
/* profileName: string;
avatarPath: string;
avatarColor: string;
pubkey: string;
onClose: any;
onStartConversation: any; */
} }
/*
interface State {
avatarColor: string;
} */
export class SessionRegistrationView extends React.Component<Props> { export class SessionRegistrationView extends React.Component<Props> {
constructor(props: Props) { constructor(props: Props) {
super(props); super(props);
//this.closeDialog = this.closeDialog.bind(this);
window.addEventListener('keyup', this.onKeyUp);
} }
public render() { public render() {
//const i18n = this.props.i18n;
//const cancelText = i18n('cancel');
const { showSubtitle, i18n } = this.props; const { showSubtitle, i18n } = this.props;
return ( return (
<div className="session-content"> <div className="session-content">
<div className="session-content-accent"> <div className="session-content-accent">
<AccentText showSubtitle={showSubtitle || true} /> <AccentText showSubtitle={showSubtitle || true} i18n={i18n} />
</div> </div>
<div className="session-content-registration"> <div className="session-content-registration">
<RegistrationTabs i18n={i18n} /> <RegistrationTabs i18n={i18n} />
@ -51,15 +34,4 @@ export class SessionRegistrationView extends React.Component<Props> {
</div> </div>
); );
} }
private onKeyUp(event: any) {
switch (event.key) {
case 'Enter':
break;
case 'Esc':
case 'Escape':
break;
default:
}
}
} }

Loading…
Cancel
Save