diff --git a/server/index.js b/server/index.js
index 3fbf53473..b7b0aef0c 100644
--- a/server/index.js
+++ b/server/index.js
@@ -7,6 +7,7 @@ const cors = require('@koa/cors')
const coBody = require('co-body')
const config = require('config')
const git = require('git-rev-sync')
+const fs = require('fs')
const path = require('path')
const { convertEntriesToArrays, } = require('./utils/misc')
@@ -70,14 +71,22 @@ if (env === 'production') {
}
if (env === 'production') {
+ const buildPath = path.join(__dirname, '../build')
app.use(async (ctx, next) => {
- if (ctx.path.startsWith('/@')) {
- ctx.url = '/'
+ const parts = ctx.path.split('/')
+ // /
+ // /@user
+ // /group
+ if (parts.length === 2 && parts[1] !== 'api') {
+ const filePath = path.join(buildPath, parts[1])
+ if (!fs.existsSync(filePath)) {
+ ctx.url = '/'
+ }
}
await next()
})
const cacheOpts = { maxage: 0, gzip: true }
- app.use(static(path.join(__dirname, '../build'), cacheOpts))
+ app.use(static(buildPath, cacheOpts))
}
app.use(router.routes())
diff --git a/src/assets/icons/golos.svg b/src/assets/icons/golos.svg
new file mode 100644
index 000000000..cf13e03be
--- /dev/null
+++ b/src/assets/icons/golos.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/components/elements/Icon.jsx b/src/components/elements/Icon.jsx
index 80fe69eef..dcf3f562e 100644
--- a/src/components/elements/Icon.jsx
+++ b/src/components/elements/Icon.jsx
@@ -24,7 +24,7 @@ const icons = new Map([
// ['clock', require('app/assets/icons/clock.svg')],
// ['copy', require('app/assets/icons/copy.svg')],
// ['extlink', require('app/assets/icons/extlink.svg')],
- // ['golos', require('app/assets/icons/golos.svg')],
+ ['golos', require('app/assets/icons/golos.svg')],
['dropdown-arrow', require('app/assets/icons/dropdown-arrow.svg')],
// ['printer', require('app/assets/icons/printer.svg')],
// ['search', require('app/assets/icons/search.svg')],
diff --git a/src/components/elements/messages/ChatError/ChatError.scss b/src/components/elements/messages/ChatError/ChatError.scss
new file mode 100644
index 000000000..6b0ee4537
--- /dev/null
+++ b/src/components/elements/messages/ChatError/ChatError.scss
@@ -0,0 +1,6 @@
+.ChatError {
+ position: absolute;
+ top: 50%;
+ transform: translateX(-50%) translateY(-50%);
+ left: 50%;
+}
diff --git a/src/components/elements/messages/ChatError/index.jsx b/src/components/elements/messages/ChatError/index.jsx
new file mode 100644
index 000000000..3a22ff33a
--- /dev/null
+++ b/src/components/elements/messages/ChatError/index.jsx
@@ -0,0 +1,18 @@
+import React from 'react'
+import tt from 'counterpart'
+
+import Icon from 'app/components/elements/Icon'
+import './ChatError.scss'
+
+class ChatError extends React.Component {
+ render() {
+ const { isGroup } = this.props
+ return
+
+
{isGroup ? tt('msgs_chat_error.404_group') : tt('msgs_chat_error.404_acc')}
+
{tt('msgs_chat_error.404_but')}
+
+ }
+}
+
+export default ChatError
diff --git a/src/components/modules/messages/MessageList/index.js b/src/components/modules/messages/MessageList/index.js
index 3af4c9f4d..ffeb5c170 100644
--- a/src/components/modules/messages/MessageList/index.js
+++ b/src/components/modules/messages/MessageList/index.js
@@ -79,7 +79,15 @@ export default class MessageList extends React.Component {
}
renderMessages = () => {
- const { to, renderEmpty, messages, selectedMessages, onMessageSelect } = this.props;
+ const { to, renderEmpty, renderMessages, messages, selectedMessages, onMessageSelect } = this.props;
+
+ let renderRes = false
+ if (renderMessages) {
+ renderRes = renderMessages({})
+ }
+ if (renderRes !== false) {
+ return renderRes
+ }
if (!to && renderEmpty) {
return renderEmpty()
diff --git a/src/components/modules/messages/Messenger/index.js b/src/components/modules/messages/Messenger/index.js
index 2f04d2255..93b2a3d44 100644
--- a/src/components/modules/messages/Messenger/index.js
+++ b/src/components/modules/messages/Messenger/index.js
@@ -38,10 +38,11 @@ export default class Messages extends React.Component {
}
render() {
- const { account, to,
+ const { account, to, toNew,
contacts, conversationTopLeft, conversationTopRight, conversationLinkPattern,
onConversationSearch, onConversationSelect,
- messagesTopLeft, messagesTopCenter, messagesTopRight, messages, replyingMessage, onCancelReply, onSendMessage,
+ messagesTopLeft, messagesTopCenter, messagesTopRight, messages, renderMessages,
+ replyingMessage, onCancelReply, onSendMessage,
onButtonImageClicked, onImagePasted,
selectedMessages, onMessageSelect, onPanelDeleteClick, onPanelReplyClick, onPanelEditClick, onPanelCloseClick,
composeRef
@@ -86,6 +87,7 @@ export default class Messages extends React.Component {
if ((localStorage.getItem('msgr_auth') && !account) || process.env.MOBILE_APP) return null
return
}}
+ renderMessages={renderMessages}
messages={messages}
replyingMessage={replyingMessage}
onCancelReply={onCancelReply}
diff --git a/src/components/pages/Messages.jsx b/src/components/pages/Messages.jsx
index 6e394dd1f..d16c2f0a1 100644
--- a/src/components/pages/Messages.jsx
+++ b/src/components/pages/Messages.jsx
@@ -17,6 +17,7 @@ import MarkNotificationRead from 'app/components/elements/MarkNotificationRead'
import NotifiCounter from 'app/components/elements/NotifiCounter'
import DialogManager from 'app/components/elements/common/DialogManager'
import AddImageDialog from 'app/components/dialogs/AddImageDialog'
+import ChatError from 'app/components/elements/messages/ChatError'
import PageFocus from 'app/components/elements/messages/PageFocus'
import TimeAgoWrapper from 'app/components/elements/TimeAgoWrapper'
import Userpic from 'app/components/elements/Userpic'
@@ -56,11 +57,18 @@ class Messages extends React.Component {
this.composeRef = React.createRef()
}
+ getToAcc = () => {
+ let { to } = this.props
+ if (to) to = to.replace('@', '')
+ return to
+ }
+
markMessages() {
const { messages } = this.state;
if (!messages.length) return;
- const { account, accounts, to } = this.props;
+ const { account, accounts, } = this.props;
+ const to = this.getToAcc()
let OPERATIONS = golos.messages.makeDatedGroups(messages, (message_object, idx) => {
return message_object.toMark && !message_object._offchain;
@@ -390,7 +398,8 @@ class Messages extends React.Component {
onSendMessage = (message, event) => {
if (!message.length) return;
- const { to, account, accounts, currentUser, messages } = this.props;
+ const { account, accounts, currentUser, messages } = this.props;
+ const to = this.getToAcc()
const private_key = currentUser.getIn(['private_keys', 'memo_private']);
let editInfo;
@@ -480,7 +489,8 @@ class Messages extends React.Component {
onPanelDeleteClick = (event) => {
const { messages } = this.state;
- const { account, accounts, to } = this.props;
+ const { account, accounts, } = this.props;
+ const to = this.getToAcc()
// TODO: works wrong if few messages have same create_time
/*let OPERATIONS = golos.messages.makeDatedGroups(messages, (message_object, idx) => {
@@ -597,7 +607,8 @@ class Messages extends React.Component {
if (!url)
return;
- const { to, account, accounts, currentUser, messages } = this.props;
+ const { account, accounts, currentUser, messages } = this.props;
+ const to = this.getToAcc()
const private_key = currentUser.getIn(['private_keys', 'memo_private']);
this.props.sendMessage({
senderAcc: account, memoKey: private_key, toAcc: accounts[to],
@@ -746,7 +757,8 @@ class Messages extends React.Component {
_renderMessagesTopCenter = ({ isSmall }) => {
let messagesTopCenter = [];
- const { to, accounts } = this.props;
+ const { accounts } = this.props;
+ const to = this.getToAcc()
if (accounts[to]) {
let checkmark
if (to === 'notify') {
@@ -862,6 +874,21 @@ class Messages extends React.Component {
);
};
+ _renderMessages = ({ }) => {
+ const { to, the_group, accounts } = this.props
+
+ if (to) {
+ const isGroup = !to.startsWith('@')
+ if (isGroup && the_group === null) {
+ return
+ } else if (!isGroup && !accounts[this.getToAcc()]) {
+ return
+ }
+ }
+
+ return false
+ }
+
handleFocusChange = isFocused => {
this.windowFocused = isFocused;
if (!isFocused) {
@@ -915,7 +942,7 @@ class Messages extends React.Component {
}
render() {
- const { contacts, account, to, nodeError } = this.props;
+ const { contacts, account, to, the_group, nodeError } = this.props;
let bbc, auc
if (process.env.MOBILE_APP) {
bbc =
@@ -934,6 +961,8 @@ class Messages extends React.Component {
conversationTopLeft={this._renderConversationTopLeft}
/>
);
+ const toAcc = this.getToAcc()
+
return (
{bbc}
@@ -946,7 +975,7 @@ class Messages extends React.Component {
{Messenger ? ( dispatch(user.actions.showMyGroups()),
fetchState: (to) => {
- const pathname = '/' + (to ? ('@' + to) : '');
+ const pathname = '/' + (to || '')
dispatch({type: 'FETCH_STATE', payload: {
location: {
pathname
diff --git a/src/locales/ru-RU.json b/src/locales/ru-RU.json
index ca295b03d..4afe4d32f 100644
--- a/src/locales/ru-RU.json
+++ b/src/locales/ru-RU.json
@@ -109,6 +109,11 @@
"start_chat": "Начать чат",
"create_group": "Создать группу"
},
+ "msgs_chat_error": {
+ "404_group": "Такой группы у нас нет",
+ "404_acc": "Такого пользователя нет",
+ "404_but": "Но у нас есть много интересного..."
+ },
"create_group_jsx": {
"title": "Название",
"name": "Ссылка chat.golos.app/",
diff --git a/src/redux/FetchDataSaga.js b/src/redux/FetchDataSaga.js
index e19cbd27b..232521e39 100644
--- a/src/redux/FetchDataSaga.js
+++ b/src/redux/FetchDataSaga.js
@@ -61,15 +61,33 @@ export function* fetchState(location_change_action) {
state.contacts = yield callSafe(state, [], 'getContactsAsync', [api, api.getContactsAsync], account, 'unknown', 100, 0)
if (hasErr) return
- if (parts[1]) {
- const to = parts[1].replace('@', '');
- accounts.add(to);
-
- state.messages = yield callSafe(state, [], 'getThreadAsync', [api, api.getThreadAsync], account, to, {});
- if (hasErr) return
-
- if (state.messages.length) {
- state.messages_update = state.messages[state.messages.length - 1].nonce;
+ const path = parts[1]
+ if (path) {
+ if (path.startsWith('@')) {
+ const to = path.replace('@', '');
+ accounts.add(to);
+
+ state.messages = yield callSafe(state, [], 'getThreadAsync', [api, api.getThreadAsync], account, to, {});
+ if (hasErr) return
+
+ if (state.messages.length) {
+ state.messages_update = state.messages[state.messages.length - 1].nonce;
+ }
+ } else {
+ let the_group = yield callSafe(state, [], 'getGroupsAsync', [api, api.getGroupsAsync], {
+ start_group: path,
+ limit: 1,
+ with_members: {
+ accounts: [account]
+ }
+ })
+ if (hasErr) return
+ if (the_group[0] && the_group[0].name === path) {
+ the_group = the_group[0]
+ } else {
+ the_group = null
+ }
+ state.the_group = the_group
}
}
for (let contact of state.contacts) {
diff --git a/src/utils/Normalizators.js b/src/utils/Normalizators.js
index 9200d4da5..844a63486 100644
--- a/src/utils/Normalizators.js
+++ b/src/utils/Normalizators.js
@@ -68,6 +68,8 @@ export function normalizeContacts(contacts, accounts, currentUser, preDecoded, c
}
export function normalizeMessages(messages, accounts, currentUser, to, preDecoded) {
+ if (to) to = to.replace('@', '')
+
if (!to || !accounts[to]) {
return [];
}