merge devel
This commit is contained in:
@@ -28,16 +28,17 @@ This is NOT a standalone app, this is just a frontend, a client. It requires a [
|
||||
|
||||
The app is fully internationalized using [React-Intl](https://github.com/formatjs/react-intl). The UI language is selected automatically from the language specified by the browser. A specific language can be forced by adding `#?hl=XX` parameter to the URL when starting the app, e.g. https://web.tinode.co/#?hl=ru.
|
||||
|
||||
As of the time of this writing the following translations exist:
|
||||
The app is currently available in the following languages:
|
||||
* English
|
||||
* Chinese (simplified)
|
||||
* Chinese (traditional)
|
||||
* German
|
||||
* Korean
|
||||
* Romanian
|
||||
* Russian
|
||||
* Spanish
|
||||
|
||||
More translations are welcome. The source file with the original English strings and context explanations is located at [/src/i18n/ex/base-en.json](/src/i18n/ex/base-en.json). Only `defaultMessage` needs to be translated. Send a pull request with a json file with translated strings. Take a look at [Spanish](/src/i18n/es.json), [Russian](/src/i18n/ru.json), or [Simplified Chinese](/src/i18n/zh.json) translations for guidance.
|
||||
More translations are welcome. See [instructions](https://github.com/tinode/chat/blob/devel/docs/translations.md#webapp).
|
||||
|
||||
|
||||
## Not done yet
|
||||
|
||||
+10
-3
@@ -4,8 +4,9 @@ importScripts('https://cdn.jsdelivr.net/npm/firebase@8.7.1/firebase-messaging.js
|
||||
importScripts('firebase-init.js');
|
||||
importScripts('version.js');
|
||||
|
||||
// Channel to notify the webapp.
|
||||
const webAppChannel = new BroadcastChannel('tinode-sw');
|
||||
// Channel to notify the webapp. There is no BroadcastChannel in Safari.
|
||||
const webAppChannel = (typeof BroadcastChannel == 'function') ?
|
||||
new BroadcastChannel('tinode-sw') : null;
|
||||
|
||||
// Basic internationalization.
|
||||
const i18n = {
|
||||
@@ -36,6 +37,10 @@ const i18n = {
|
||||
'zh': {
|
||||
'new_message': "新讯息",
|
||||
'new_chat': "新聊天",
|
||||
},
|
||||
'zh-TW': {
|
||||
'new_message': "新訊息",
|
||||
'new_chat': "新聊天",
|
||||
}
|
||||
};
|
||||
self.i18nMessage = function(id) {
|
||||
@@ -56,7 +61,9 @@ fbMessaging.onBackgroundMessage((payload) => {
|
||||
}
|
||||
|
||||
// Notify webapp that a message was received.
|
||||
webAppChannel.postMessage(payload.data);
|
||||
if (webAppChannel) {
|
||||
webAppChannel.postMessage(payload.data);
|
||||
}
|
||||
|
||||
const pushType = payload.data.what || 'msg';
|
||||
const title = payload.data.title || self.i18nMessage(pushType == 'msg' ? 'new_message' : 'new_chat');
|
||||
|
||||
+23
-13
@@ -391,24 +391,28 @@ class TinodeWeb extends React.Component {
|
||||
'cred','reset','newtpk','archive','blocked','contacts',''].includes(hash.path[0])) {
|
||||
this.setState({sidePanelSelected: hash.path[0]});
|
||||
} else {
|
||||
console.info("Unknown sidepanel view", hash.path[0]);
|
||||
console.warn("Unknown sidepanel view", hash.path[0]);
|
||||
}
|
||||
|
||||
// Topic for MessagesView selector.
|
||||
const topicName = hash.path[1];
|
||||
if (Tinode.topicType(topicName) && topicName != this.state.topicSelected) {
|
||||
const newState = {
|
||||
topicSelected: topicName
|
||||
};
|
||||
const acs = this.tinode.getTopicAccessMode(topicName);
|
||||
if (acs) {
|
||||
newState.topicSelectedAcs = acs;
|
||||
}
|
||||
this.setState(newState);
|
||||
let topicName = hash.path[1] || null;
|
||||
if (topicName != this.state.topicSelected) {
|
||||
if (!Tinode.topicType(topicName)) {
|
||||
// Clear invalid topic name.
|
||||
topicName = null;
|
||||
}
|
||||
const newState = {
|
||||
topicSelected: topicName
|
||||
};
|
||||
const acs = this.tinode.getTopicAccessMode(topicName);
|
||||
if (acs) {
|
||||
newState.topicSelectedAcs = acs;
|
||||
}
|
||||
this.setState(newState);
|
||||
}
|
||||
} else {
|
||||
// Empty hashpath
|
||||
this.setState({sidePanelSelected: ''});
|
||||
this.setState({sidePanelSelected: '', topicSelected: null});
|
||||
}
|
||||
|
||||
// Save validation credentials, if available.
|
||||
@@ -784,6 +788,12 @@ class TinodeWeb extends React.Component {
|
||||
newState.topicSelectedAcs = c.acs;
|
||||
}
|
||||
});
|
||||
|
||||
const past = new Date(0);
|
||||
newState.chatList.sort((a, b) => {
|
||||
return (a.touched || past).getTime() - (b.touched || past).getTime();
|
||||
});
|
||||
|
||||
// Merge search results and chat list.
|
||||
newState.searchableContacts = TinodeWeb.prepareSearchableContacts(newState.chatList, this.state.searchResults);
|
||||
this.setState(newState);
|
||||
@@ -950,7 +960,7 @@ class TinodeWeb extends React.Component {
|
||||
});
|
||||
break;
|
||||
default:
|
||||
console.info("Unknown invitation action", '"' + action + '""');
|
||||
console.warn("Unknown invitation action", '"' + action + '""');
|
||||
}
|
||||
|
||||
if (response != null) {
|
||||
|
||||
+14
-5
@@ -5012,12 +5012,16 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
sidePanelSelected: hash.path[0]
|
||||
});
|
||||
} else {
|
||||
console.info("Unknown sidepanel view", hash.path[0]);
|
||||
console.warn("Unknown sidepanel view", hash.path[0]);
|
||||
}
|
||||
|
||||
const topicName = hash.path[1];
|
||||
let topicName = hash.path[1] || null;
|
||||
|
||||
if (topicName != this.state.topicSelected) {
|
||||
if (!tinode_sdk__WEBPACK_IMPORTED_MODULE_4___default().topicType(topicName)) {
|
||||
topicName = null;
|
||||
}
|
||||
|
||||
if (tinode_sdk__WEBPACK_IMPORTED_MODULE_4___default().topicType(topicName) && topicName != this.state.topicSelected) {
|
||||
const newState = {
|
||||
topicSelected: topicName
|
||||
};
|
||||
@@ -5031,7 +5035,8 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
}
|
||||
} else {
|
||||
this.setState({
|
||||
sidePanelSelected: ''
|
||||
sidePanelSelected: '',
|
||||
topicSelected: null
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5409,6 +5414,10 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
newState.topicSelectedAcs = c.acs;
|
||||
}
|
||||
});
|
||||
const past = new Date(0);
|
||||
newState.chatList.sort((a, b) => {
|
||||
return (a.touched || past).getTime() - (b.touched || past).getTime();
|
||||
});
|
||||
newState.searchableContacts = TinodeWeb.prepareSearchableContacts(newState.chatList, this.state.searchResults);
|
||||
this.setState(newState);
|
||||
}
|
||||
@@ -5576,7 +5585,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
break;
|
||||
|
||||
default:
|
||||
console.info("Unknown invitation action", '"' + action + '""');
|
||||
console.warn("Unknown invitation action", '"' + action + '""');
|
||||
}
|
||||
|
||||
if (response != null) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-5
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user