diff --git a/config/mobile.json b/config/mobile.json
index 332dc1e3e..6168e18d2 100644
--- a/config/mobile.json
+++ b/config/mobile.json
@@ -17,7 +17,8 @@
"custom_client": "blogs"
},
"notify_service": {
- "host": "https://notify.golos.app"
+ "host": "https://notify.golos.app",
+ "host_ws": "wss://notify.golos.app/ws"
},
"blogs_service": {
"host": "https://golos.id"
diff --git a/src/components/elements/VerticalMenu.scss b/src/components/elements/VerticalMenu.scss
index 9bdf1c161..d3aba6adc 100644
--- a/src/components/elements/VerticalMenu.scss
+++ b/src/components/elements/VerticalMenu.scss
@@ -55,6 +55,10 @@
padding: 0 1rem 0 3.8rem;
line-height: 50px;
+ @media screen and (max-width: 39.9375em) {
+ padding: 0 20px;
+ }
+
.Icon {
@include themify($themes) {
fill: themed('textColorPrimary');
diff --git a/src/components/elements/groups/GroupMember.jsx b/src/components/elements/groups/GroupMember.jsx
index f43591870..30a7855d6 100644
--- a/src/components/elements/groups/GroupMember.jsx
+++ b/src/components/elements/groups/GroupMember.jsx
@@ -6,6 +6,7 @@ import Icon from 'app/components/elements/Icon'
import TimeAgoWrapper from 'app/components/elements/TimeAgoWrapper'
import Userpic from 'app/components/elements/Userpic'
import { getRoleInGroup } from 'app/utils/groups'
+import isScreenSmall from 'app/utils/isScreenSmall'
class GroupMember extends React.Component {
// shouldComponentUpdate(nextProps) {
@@ -96,6 +97,8 @@ class GroupMember extends React.Component {
onClick={e => this.groupMember(e, member, 'retired')} />
}
+ const isSmall = isScreenSmall()
+
return
@@ -106,7 +109,7 @@ class GroupMember extends React.Component {
|
- {!creatingNew && }
+ {!isSmall && !creatingNew && }
|
{isOwner && { return {
- name: tt('create_group_jsx.step_name'),
- logo: tt('create_group_jsx.step_logo'),
- members: tt('create_group_jsx.step_members'),
- final: tt('create_group_jsx.step_create')
-} }
+const STEPS = () => {
+ const isSmall = isScreenSmall()
+ return {
+ name: tt('create_group_jsx.step_name'),
+ logo: isSmall ? tt('create_group_jsx.step_logo_mobile') : tt('create_group_jsx.step_logo'),
+ members: isSmall ? tt('create_group_jsx.step_members_mobile') : tt('create_group_jsx.step_members'),
+ final: isSmall ? tt('create_group_jsx.step_create_mobile') : tt('create_group_jsx.step_create')
+ }
+}
class ActionOnUnmount extends React.Component {
componentWillUnmount() {
diff --git a/src/components/modules/MessagesTopCenter.jsx b/src/components/modules/MessagesTopCenter.jsx
index 0726b4d02..a4744ff6d 100644
--- a/src/components/modules/MessagesTopCenter.jsx
+++ b/src/components/modules/MessagesTopCenter.jsx
@@ -229,6 +229,31 @@ class MessagesTopCenter extends React.Component {
}
+ showErrorLogs = (e) => {
+ e.preventDefault()
+ e.stopPropagation()
+ try {
+ const { errorLogs } = this.props
+ let msg = ''
+ for (const err of errorLogs) {
+ msg += (err.err ? err.err.toString() : '') + '\n' + JSON.stringify(err.details) + '\n\n'
+ }
+ alert(msg)
+ } catch (err) {
+ alert('Cannot display error logs, due to: ' + (err && err.toString()))
+ }
+ }
+
+ refreshSync = e => {
+ this.setState({ refreshing: true })
+ e.preventDefault()
+ e.stopPropagation()
+ this.props.fetchState(this.props.to)
+ setTimeout(() => {
+ this.setState({ refreshing: false })
+ }, 500)
+ }
+
render() {
let avatar = []
let items = []
@@ -257,7 +282,7 @@ class MessagesTopCenter extends React.Component {
closeOnClickOutside
dropdownClassName="GroupDropdown"
dropdownPosition="bottom"
- dropdownAlignment="center"
+ dropdownAlignment="right"
dropdownContent={this._renderGroupDropdown()}
transition={Fade}
>
@@ -282,12 +307,13 @@ class MessagesTopCenter extends React.Component {
}
if (notifyErrors >= 30) {
+ const { refreshing } = this.state
items.push(
{isSmall ?
-
+
{tt('messages.sync_error_short')}
- { e.preventDefault(); this.props.fetchState(this.props.to) }}>
- {tt('g.refresh').toLowerCase()}.
+
+ {refreshing ? '...' : tt('g.refresh')}.
:
{tt('messages.sync_error')}
diff --git a/src/components/modules/groups/MyGroups.jsx b/src/components/modules/groups/MyGroups.jsx
index f818bf340..9de07e978 100644
--- a/src/components/modules/groups/MyGroups.jsx
+++ b/src/components/modules/groups/MyGroups.jsx
@@ -4,6 +4,7 @@ import { Link } from 'react-router-dom'
import { Map } from 'immutable'
import { api, formatter } from 'golos-lib-js'
import tt from 'counterpart'
+import cn from 'classnames'
import DialogManager from 'app/components/elements/common/DialogManager'
import g from 'app/redux/GlobalReducer'
@@ -15,6 +16,7 @@ import LoadingIndicator from 'app/components/elements/LoadingIndicator'
import MarkNotificationRead from 'app/components/elements/MarkNotificationRead'
import { showLoginDialog } from 'app/components/dialogs/LoginDialog'
import { getGroupLogo, getGroupMeta, getRoleInGroup } from 'app/utils/groups'
+import isScreenSmall from 'app/utils/isScreenSmall'
class MyGroups extends React.Component {
constructor(props) {
@@ -126,10 +128,13 @@ class MyGroups extends React.Component {
const meta = getGroupMeta(json_metadata)
+ const isSmall = isScreenSmall()
+
+ const maxLength = isSmall ? 15 : 20
let title = meta.title || name
let titleShr = title
- if (titleShr.length > 20) {
- titleShr = titleShr.substring(0, 17) + '...'
+ if (titleShr.length > maxLength) {
+ titleShr = titleShr.substring(0, maxLength - 3) + '...'
}
const kebabItems = []
@@ -161,7 +166,9 @@ class MyGroups extends React.Component {
e.preventDefault()
e.stopPropagation()
}}>
- {amPending ? : null}
-
+
+
+ {tt('app_settings.notify_service_ws')}
+
+
+
+
+
{tt('app_settings.blogs_service')}
diff --git a/src/locales/en.json b/src/locales/en.json
index 55d6d22e2..3f0dbb4e7 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -107,7 +107,7 @@
"new_message5": " notifications",
"invalid_message": "(This message could not be displayed in Golos Messenger)",
"sync_error": "Sync error. To receive new messages please refresh the page.",
- "sync_error_short": "Sync error. To receive new messages touch ",
+ "sync_error_short": "Sync error. ",
"blocked_BY": "You are blocked by @%(BY)s.",
"do_not_bother_BY": "@%(BY)s wants to not be bothered by low-reputation users."
},
@@ -156,8 +156,11 @@
"submit": "Create",
"step_name": "Name",
"step_logo": "Logo",
+ "step_logo_mobile": "Logo",
"step_members": "Members",
+ "step_members_mobile": "Membs",
"step_create": "Create!",
+ "step_create_mobile": "Go!",
"group_already_exists": "Group already exists.",
"group_min_length": "Min is 3 symbols.",
"golos_power_too_low": "To create group you should have Golos Power at least ",
@@ -313,7 +316,8 @@
"current_node": "GOLOS node URL",
"img_proxy_prefix": "Use Proxy For Images",
"auth_service": "Golos Auth & Registration Service (for messenger)",
- "notify_service": "Golos Notify Service (for messenger)",
+ "notify_service": "Golos Notify Service (for instant messages)",
+ "notify_service_ws": "Golos Notify Service WebSocket (for instant messages)",
"blogs_service": "Blogs",
"save": "Save",
"node_error_NODE": "Cannot connect to %(NODE)s. It may be internet failure. Try ",
@@ -374,6 +378,7 @@
"name": "Name",
"night_mode": "Night Mode",
"ok": "OK",
+ "or": "or",
"refresh": "Refresh",
"required": "Required",
"replies": "Replies",
diff --git a/src/locales/ru-RU.json b/src/locales/ru-RU.json
index 950087b87..910190bc4 100644
--- a/src/locales/ru-RU.json
+++ b/src/locales/ru-RU.json
@@ -108,7 +108,7 @@
"new_message5": " новых сообщений",
"invalid_message": "(Это сообщение не может быть отображено в Golos Messenger)",
"sync_error": "Ошибка синхронизации. Для получения новых сообщений обновляйте страницу.",
- "sync_error_short": "Ошибка синхронизации. Для получения новых сообщений нажимайте ",
+ "sync_error_short": "Ошибка синхронизации. ",
"blocked_BY": "Вы заблокированы пользователем @%(BY)s.",
"do_not_bother_BY": "@%(BY)s просит пользователей с низкой репутацией не беспокоить.",
"too_low_gp": "Не хватает Силы Голоса. Для участия в группах нужно не менее ",
@@ -162,8 +162,11 @@
"submit": "Создать",
"step_name": "Имя",
"step_logo": "Логотип",
+ "step_logo_mobile": "Лого",
"step_members": "Участники",
+ "step_members_mobile": "Люди",
"step_create": "Создать!",
+ "step_create_mobile": "Go!",
"group_already_exists": "Такая группа уже существует.",
"validating": "Проверка существования группы...",
"group_min_length": "Минимум 3 символа.",
@@ -330,6 +333,7 @@
"img_proxy_prefix": "Использовать прокси для изображений",
"auth_service": "Golos Auth & Registration Service (для мгновенных сообщений)",
"notify_service": "Golos Notify Service (для мгновенных сообщений)",
+ "notify_service_ws": "Golos Notify Service WebSocket (для мгновенных сообщений)",
"blogs_service": "Блоги",
"save": "Сохранить",
"node_error_NODE": "Не удалось подключиться к ноде %(NODE)s. Возможно, это проблемы с интернетом. Попробуйте ",
diff --git a/src/redux/TransactionSaga.js b/src/redux/TransactionSaga.js
index 7a8410b48..5c4ccc8ac 100644
--- a/src/redux/TransactionSaga.js
+++ b/src/redux/TransactionSaga.js
@@ -57,6 +57,7 @@ function* preBroadcast_custom_json({operation}) {
}
const newMsg = messageOpToObject(json[1], group, mentions)
msgs = msgs.insert(0, fromJS(newMsg))
+ messages_update = json[1].nonce;
} else {
messages_update = json[1].nonce;
msgs = msgs.update(idx, msg => {
diff --git a/src/redux/UserSaga.js b/src/redux/UserSaga.js
index 3b57ef347..b2fa49b8f 100644
--- a/src/redux/UserSaga.js
+++ b/src/redux/UserSaga.js
@@ -134,10 +134,15 @@ function* usernamePasswordLogin(action) {
yield put(user.actions.setUser({ username, private_keys, }))
}
+ const { errorLogs } = window
+
if (postingWif) {
let alreadyAuthorized = false;
try {
const res = yield notifyApiLogin(username, localStorage.getItem('X-Auth-Session'));
+
+ errorLogs.push({ details: { notifyApiLogin1: res } })
+
alreadyAuthorized = (res.status === 'ok');
} catch(error) {
// Does not need to be fatal
@@ -148,6 +153,9 @@ function* usernamePasswordLogin(action) {
let authorized = false;
try {
const res = yield authApiLogin(username, null);
+
+ errorLogs.push({ details: { authApiLogin1: res } })
+
if (!res.already_authorized) {
console.log('login_challenge', res.login_challenge);
@@ -156,6 +164,9 @@ function* usernamePasswordLogin(action) {
posting: postingWif,
});
const res2 = yield authApiLogin(username, signatures);
+
+ errorLogs.push({ details: { authApiLogin2: res2 } })
+
if (res2.guid) {
localStorage.setItem('guid', res2.guid)
}
@@ -174,6 +185,8 @@ function* usernamePasswordLogin(action) {
try {
const res = yield notifyApiLogin(username, localStorage.getItem('X-Auth-Session'));
+ errorLogs.push({ details: { notifyApiLogin2: res } })
+
if (res.status !== 'ok') {
throw new Error(res);
}
diff --git a/src/utils/NotifyApiClient.js b/src/utils/NotifyApiClient.js
index 4df4ebca5..602892e90 100644
--- a/src/utils/NotifyApiClient.js
+++ b/src/utils/NotifyApiClient.js
@@ -14,13 +14,13 @@ const notifyAvailable = () => {
&& $GLS_Config.notify_service && $GLS_Config.notify_service.host;
};
-const notifyWsAvailable = () => {
+export function notifyWsHost() {
return notifyAvailable() && $GLS_Config.notify_service.host_ws
}
-const notifyUrl = (pathname) => {
+export function notifyUrl(pathname = '') {
return new URL(pathname, window.$GLS_Config.notify_service.host).toString();
-};
+}
function notifySession() {
return localStorage.getItem('X-Session')
@@ -50,7 +50,7 @@ async function connectNotifyWs() {
window.notifyWs.close()
}
await new Promise((resolve, reject) => {
- const notifyWs = new WebSocket($GLS_Config.notify_service.host_ws)
+ const notifyWs = new WebSocket(notifyWsHost())
window.notifyWs = notifyWs
const timeout = setTimeout(() => {
@@ -211,7 +211,7 @@ export async function notificationSubscribe(account, scopes = 'message,donate_ms
}
export async function notificationSubscribeWs(account, callback, scopes = 'message,donate_msgs', sidKey = '__subscriber_id') {
- if (!notifyWsAvailable()) return null
+ if (!notifyWsHost()) throw new Error('No notify_service host_ws in config')
const xSession = notifySession()
return await new Promise(async (resolve, reject) => {
await notifyWsSend('queues/subscribe', {
@@ -327,7 +327,7 @@ export async function queueWatch(account, group, sidKey = '__subscriber_id') {
}
export async function queueWatchWs(account, group, sidKey = '__subscriber_id') {
- if (!notifyWsAvailable()) return null
+ if (!notifyWsHost()) return null
const xSession = notifySession()
return await new Promise(async (resolve, reject) => {
await notifyWsSend('queues/subscribe', {
diff --git a/src/utils/app/SplashUtils.js b/src/utils/app/SplashUtils.js
index fdd8b6658..1e0c4f305 100644
--- a/src/utils/app/SplashUtils.js
+++ b/src/utils/app/SplashUtils.js
@@ -1,10 +1,13 @@
export function hideSplash() {
- if (process.env.MOBILE_APP) {
- try {
+ try {
+ if (process.env.MOBILE_APP) {
navigator.splashscreen.hide()
- } catch (err) {
- console.error('hideSplash', err)
+ } else if (process.env.DESKTOP_APP) {
+ if (window.appSplash)
+ window.appSplash.contentLoaded()
}
+ } catch (err) {
+ console.error('hideSplash', err)
}
}
diff --git a/src/utils/initConfig.js b/src/utils/initConfig.js
index 290276805..ab252c8dc 100644
--- a/src/utils/initConfig.js
+++ b/src/utils/initConfig.js
@@ -23,7 +23,10 @@ const loadMobileConfig = async () => {
if (cfg) {
try {
cfg = JSON.parse(cfg)
- // Add here migrations in future, if need
+ // Add here migrations
+ if (cfg.notify_service && !cfg.notify_service.host_ws) {
+ delete cfg.notify_service
+ }
cfg = { ...defaultCfg, ...cfg }
} catch (err) {
console.error('Cannot parse app_settings', err)
|