more fixes

This commit is contained in:
or-else
2018-10-26 16:36:30 +03:00
parent 782f2d1fea
commit 71bbfb4fdd
12 changed files with 152 additions and 60 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "tinode-webapp",
"description": "Tinode messenger for the web",
"version": "0.15.8-rc1",
"version": "0.15.9-rc1",
"devDependencies": {
"@babel/core": "^7.1.2",
"@babel/preset-env": "^7.1.0",
+9 -1
View File
@@ -10,6 +10,14 @@
"sign_in_button": "Sign in",
"label_client": "Client:",
"label_server": "Server:",
"online_now": "online now",
"last_seen_timestamp": "Last seen",
"title_not_found": "Not found",
"unnamed_topic": "Unnamed",
"messages_not_readable": "no access to messages",
"label_server_to_use": "Server to use:",
"label_wire_transport": "Wire transport:",
"button_update": "Update",
"sidepanel_title_login": "Sign In",
"sidepanel_title_register": "Create Account",
"sidepanel_title_settings": "Settings",
@@ -17,4 +25,4 @@
"sidepanel_title_newtpk": "Start New Chat",
"sidepanel_title_cred": "Confirm Credentials",
"sidepanel_title_reset": "Reset Password"
}
}
+8
View File
@@ -10,6 +10,14 @@
"sign_in_button": "Войти",
"label_client": "Клиент:",
"label_server": "Сервер:",
"online_now": "онлайн",
"last_seen_timestamp": "Был активен",
"title_not_found": "Не найден",
"unnamed_topic": "Без названия",
"messages_not_readable": "нет доступа к сообщениям",
"label_server_to_use": "Использовать сервер:",
"label_wire_transport": "Соединение:",
"button_update": "Применить",
"sidepanel_title_login": "Авторизация",
"sidepanel_title_register": "Зарегистрироваться",
"sidepanel_title_settings": "Настройки",
+9 -3
View File
@@ -11,10 +11,16 @@ import ru from './i18n/ru.json';
import TinodeWeb from './views/tinode-web.jsx';
import HashNavigation from './lib/navigation.js';
const {params} = HashNavigation.parseUrlHash(window.location.hash);
const language = (params && params.hl) ||
(navigator.languages && navigator.languages[0]) ||
navigator.language ||
navigator.userLanguage;
ReactDOM.render(
<IntlProvider
locale={navigator.language}
messages={en} >
<IntlProvider locale={language} messages={en} >
<TinodeWeb />
</IntlProvider>,
document.getElementById('mountPoint')
+1 -1
View File
@@ -1,3 +1,3 @@
// This is a generated file. Don't edit.
export const PACKAGE_VERSION = "0.15.8-rc1";
export const PACKAGE_VERSION = "0.15.9-rc1";
+7 -6
View File
@@ -95,27 +95,28 @@ export default class CreateAccountView extends React.PureComponent {
<div className="panel-form-row">
<FormattedMessage id="full_name_prompt" defaultMessage="Full name, e.g. John Doe"
description="Input placeholder for person's full name">{
<input type="text" placeholder={full_name_prompt} autoComplete="name"
(full_name_prompt) => <input type="text" placeholder={full_name_prompt} autoComplete="name"
value={this.state.fn} onChange={this.handleFnChange} required/>
}</FormattedMessage>
</div>
<div className="panel-form-row">
<FormattedMessage id="email_prompt" defaultMessage="Email, e.g. jdoe@example.com"
description="Input placeholder for email entry">{
<input type="email" placeholder={email_prompt} autoComplete="email"
(email_prompt) => <input type="email" placeholder={email_prompt} autoComplete="email"
value={this.state.email} onChange={this.handleEmailChange} required/>
}</FormattedMessage>
</div>
<div className="panel-form-row">
<CheckBox id="save-token" name="save-token" checked={this.state.saveToken}
onChange={this.handleToggleSaveToken} />
<FormattedMessage id="stay_logged_in">
{(stay_logged_in) => <label htmlFor="save-token">&nbsp;{stay_logged_in}</label>}
</FormattedMessage>
<FormattedMessage id="stay_logged_in">{
(stay_logged_in) => <label htmlFor="save-token">&nbsp;{stay_logged_in}</label>
}</FormattedMessage>
</div>
<div className="dialog-buttons">
<button className={submitClasses} type="submit">
<FormattedMessage id="sign_up_button" defaultMessage="Sign up" />
<FormattedMessage id="sign_up_button" defaultMessage="Sign up"
description="Create account button [Sign Up]" />
</button>
</div>
</form>
+55 -23
View File
@@ -1,4 +1,5 @@
import React from 'react';
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import ChatMessage from '../widgets/chat-message.jsx';
import ErrorPanel from '../widgets/error-panel.jsx';
@@ -9,9 +10,27 @@ import LoadSpinner from '../widgets/load-spinner.jsx';
import LogoView from './logo-view.jsx';
import SendMessage from '../widgets/send-message.jsx';
const NOT_FOUND_TOPIC_TITLE = "Not found";
import { shortDateFormat } from '../lib/strformat.js';
export default class MessagesView extends React.Component {
const messages = defineMessages({
online_now: {
id: 'online_now',
defaultMessage: 'online now',
description: 'Indicator that the user or topic is currently online',
},
last_seen: {
id: 'last_seen_timestamp',
defaultMessage: 'Last seen',
description: 'Label for the timestamp of when the user or topic was last online'
},
'not_found': {
id: 'title_not_found',
defaultMessage: 'Not found',
description: 'Title shown when topic is not found'
}
});
class MessagesView extends React.Component {
constructor(props) {
super(props);
@@ -162,8 +181,9 @@ export default class MessagesView extends React.Component {
})
.catch((err) => {
this.props.onError(err.message, 'err');
const {formatMessage} = this.props.intl;
this.setState({
title: NOT_FOUND_TOPIC_TITLE,
title: formatMessage(messages.not_found),
avatar: null,
readOnly: true,
writeOnly: true,
@@ -349,21 +369,24 @@ export default class MessagesView extends React.Component {
}
render() {
var component = null;
const {formatMessage} = this.props.intl;
let component;
if (this.state.topic) {
var messageNodes = [];
var topic = this.props.tinode.getTopic(this.state.topic);
var groupTopic = topic.getType() == 'grp';
var previousFrom = null;
for (var i=0; i<this.state.messages.length; i++) {
var msg = this.state.messages[i];
var nextFrom = null;
let messageNodes = [];
let topic = this.props.tinode.getTopic(this.state.topic);
let groupTopic = topic.getType() == 'grp';
let previousFrom = null;
for (let i=0; i<this.state.messages.length; i++) {
let msg = this.state.messages[i];
let nextFrom = null;
if (i + 1 < this.state.messages.length) {
nextFrom = this.state.messages[i+1].from
}
var sequence = 'single';
let sequence = 'single';
if (msg.from == previousFrom) {
if (msg.from == nextFrom) {
sequence = 'middle';
@@ -375,12 +398,12 @@ export default class MessagesView extends React.Component {
}
previousFrom = msg.from;
var isReply = !(msg.from == this.props.myUserId);
var deliveryStatus = topic.msgStatus(msg);
let isReply = !(msg.from == this.props.myUserId);
let deliveryStatus = topic.msgStatus(msg);
var userName, userAvatar, userFrom, chatBoxClass;
let userName, userAvatar, userFrom, chatBoxClass;
if (groupTopic) {
var user = topic.userDesc(msg.from);
let user = topic.userDesc(msg.from);
if (user && user.public) {
userName = user.public.fn;
userAvatar = makeImageUrl(user.public.photo);
@@ -411,14 +434,14 @@ export default class MessagesView extends React.Component {
let cont = this.props.tinode.getMeTopic().getContact(this.state.topic);
if (cont && Tinode.topicType(cont.topic) == 'p2p') {
if (cont.online) {
lastSeen = "online now";
lastSeen = formatMessage(messages.online_now);
} else if (cont.seen) {
lastSeen = "Last active: " + shortDateFormat(cont.seen.when);
// TODO(gene): also handle user agent in c.seen.ua
lastSeen = formatMessage(messages.last_seen) + ": " + shortDateFormat(cont.seen.when);
// TODO: also handle user agent in c.seen.ua
}
}
var avatar = this.state.avatar || true;
var online = this.props.online ? 'online' + (this.state.typingIndicator ? ' typing' : '') : 'offline';
let avatar = this.state.avatar || true;
let online = this.props.online ? 'online' + (this.state.typingIndicator ? ' typing' : '') : 'offline';
component = (
<div id="topic-view" className={this.props.hideSelf ? 'nodisplay' : null}>
@@ -437,7 +460,11 @@ export default class MessagesView extends React.Component {
<span className={online} />
</div>
<div id="topic-title-group">
<div id="topic-title" className="panel-title">{this.state.title || <i>Unknown</i>}</div>
<div id="topic-title" className="panel-title">{
this.state.title ||
<i><FormattedMessage id="unnamed_topic" defaultMessage="Unnamed"
description="Title shown when the topic has no name" /></i>
}</div>
<div id="topic-last-seen">{lastSeen}</div>
</div>
{groupTopic ?
@@ -466,7 +493,10 @@ export default class MessagesView extends React.Component {
</div>
{this.state.writeOnly ?
<div id="write-only-background">
<div id="write-only-note">no access to messages</div>
<div id="write-only-note">
<FormattedMessage id="messages_not_readable" defaultMessage="no access to messages"
description="Message shown in topic without the read access" />
</div>
</div>
:
null
@@ -493,3 +523,5 @@ export default class MessagesView extends React.Component {
return component;
}
};
export default injectIntl(MessagesView);
+3 -1
View File
@@ -3,6 +3,8 @@ import React from 'react';
import VisiblePassword from '../widgets/visible-password.jsx';
import HashNavigation from '../lib/navigation.js';
export default class PasswordResetView extends React.PureComponent {
constructor(props) {
super(props);
@@ -18,7 +20,7 @@ export default class PasswordResetView extends React.PureComponent {
}
componentDidMount() {
let parsed = parseUrlHash(window.location.hash);
let parsed = HashNavigation.parseUrlHash(window.location.hash);
this.setState({token: parsed.params.token, scheme: parsed.params.scheme});
}
+15 -5
View File
@@ -1,5 +1,6 @@
// Tinode config panel.
import React from 'react';
import { FormattedMessage } from 'react-intl';
import HostSelector from '../widgets/host-selector.jsx';
@@ -35,10 +36,10 @@ export default class SettingsView extends React.PureComponent {
}
render() {
var names = {def: "default", ws: "websocket", lp: "long polling"};
const names = {def: "default", ws: "websocket", lp: "long polling"};
var transportOptions = [];
var instance = this;
['def', 'ws', 'lp'].map(function(item){
['def', 'ws', 'lp'].map(function(item) {
var id = 'transport-' + item;
var name = names[item];
transportOptions.push(
@@ -54,12 +55,18 @@ export default class SettingsView extends React.PureComponent {
return (
<form id="settings-form" className="panel-form" onSubmit={this.handleSubmit}>
<div className="panel-form-row">
<label className="small">Server to use:</label>
<label className="small">
<FormattedMessage id="label_server_to_use" defaultMessage="Server to use:"
description="Label for server selector in SettingsView" />
</label>
</div>
<HostSelector serverAddress={this.state.serverAddress}
onServerAddressChange={this.handleServerAddressChange} />
<div className="panel-form-row">
<label className="small">Wire transport:</label>
<label className="small">
<FormattedMessage id="label_wire_transport" defaultMessage="Wire transport:"
description="Label for wire transport selection in SettingsView" />
</label>
</div>
<div className="panel-form-row">
<ul className="quoted">
@@ -67,7 +74,10 @@ export default class SettingsView extends React.PureComponent {
</ul>
</div>
<div className="dialog-buttons">
<button type="submit" className="blue">Update</button>
<button type="submit" className="blue">
<FormattedMessage id="button_update" defaultMessage="Update"
description="Button [Update]" />
</button>
</div>
</form>
);
+4 -2
View File
@@ -1,5 +1,7 @@
import React from 'react';
import { KNOWN_HOSTS } from '../config.js';
/* Combobox for selecting host name */
export default class HostSelector extends React.PureComponent {
@@ -28,8 +30,8 @@ export default class HostSelector extends React.PureComponent {
render() {
var hostOptions = [];
for (var key in KNOWN_HOSTS) {
var item = KNOWN_HOSTS[key];
for (let key in KNOWN_HOSTS) {
let item = KNOWN_HOSTS[key];
hostOptions.push(
<option key={item} value={item} />
);
+34 -11
View File
File diff suppressed because one or more lines are too long
+6 -6
View File
File diff suppressed because one or more lines are too long